Highload-2022: Отчёт Виталия Филиппова — различия между версиями
Строка 130: | Строка 130: | ||
* Append-only volume-ы с переупаковкой. То есть, объекты хранятся в дописываемых всегда в конец больших файлах-томах вперемешку с заголовками, при удалении из тома сразу не удаляются, а только помечаются удалёнными — а потом, когда количество удалённого превышает определённый %, приходит отдельный процесс (называемый по вкусу compaction/defrag/gc/repack) и перезаписывает том целиком, на этот раз действительно удаляя удалённые объекты. Волюмы fallocate-ятся, чтобы исключить фрагментацию места в ФС. | * Append-only volume-ы с переупаковкой. То есть, объекты хранятся в дописываемых всегда в конец больших файлах-томах вперемешку с заголовками, при удалении из тома сразу не удаляются, а только помечаются удалёнными — а потом, когда количество удалённого превышает определённый %, приходит отдельный процесс (называемый по вкусу compaction/defrag/gc/repack) и перезаписывает том целиком, на этот раз действительно удаляя удалённые объекты. Волюмы fallocate-ятся, чтобы исключить фрагментацию места в ФС. | ||
* Есть «шарды», являющие собой группы из N (2, 3 или ещё скольки-то) таких томов на разных машинах, связанных репликацией вместе. То есть, запись идёт в пары или тройки томов. В терминологии Ceph шард — по сути, PG (placement group). В терминологии zepto — «бакет» (и сам волюм тоже, видимо, называется «бакет»). | * Есть «шарды», являющие собой группы из N (2, 3 или ещё скольки-то) таких томов на разных машинах, связанных репликацией вместе. То есть, запись идёт в пары или тройки томов. В терминологии Ceph шард — по сути, PG (placement group). В терминологии zepto — «бакет» (и сам волюм тоже, видимо, называется «бакет»). | ||
− | * Клиент хранит ID шарда (бакета) у себя и для чтения объекта обращается к конкретному шарду. Центральный сервер метаданных, знающий, | + | * Клиент хранит ID шарда (бакета) у себя и для чтения объекта обращается к конкретному шарду. Центральный сервер метаданных, знающий, где лежат все объекты, отсутствует. |
* Запись через page cache. fsync-ов после каждой записи и строгой консистентности формально нет. fsync просто раз в секунду выполняется в отдельном потоке, чтобы стимулировать сброс данных на диск. Но так как бешеные уборщицы не ходят по залу и не дёргают в произвольном порядке целые датацентры из розеток — данные не теряются. | * Запись через page cache. fsync-ов после каждой записи и строгой консистентности формально нет. fsync просто раз в секунду выполняется в отдельном потоке, чтобы стимулировать сброс данных на диск. Но так как бешеные уборщицы не ходят по залу и не дёргают в произвольном порядке целые датацентры из розеток — данные не теряются. | ||
* Есть «прокси», предоставляющие API доступа к хранилищу. У них они называются zeptoproxy и ставятся прямо на клиентские машины. | * Есть «прокси», предоставляющие API доступа к хранилищу. У них они называются zeptoproxy и ставятся прямо на клиентские машины. | ||
Строка 144: | Строка 144: | ||
** Бакеты складываются в 2 ТБ разделы дисков и один раздел (~1000 бакетов) обслуживается 1 процессом «bucketservice». В ноде 72 диска по 18 ТБ, но под Zepto на них обычно выделено только 4-6 ТБ, так что на одной машине живёт примерно 216 bucketservice-ов. | ** Бакеты складываются в 2 ТБ разделы дисков и один раздел (~1000 бакетов) обслуживается 1 процессом «bucketservice». В ноде 72 диска по 18 ТБ, но под Zepto на них обычно выделено только 4-6 ТБ, так что на одной машине живёт примерно 216 bucketservice-ов. | ||
** Процесс-переупаковщик бакетов называется bucketcompactor. | ** Процесс-переупаковщик бакетов называется bucketcompactor. | ||
− | * Репликация — клиентская, запись — кворумная. То есть клиент напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. | + | * Репликация — клиентская, запись — кворумная. То есть клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. |
− | * Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. | + | * Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете. |
* Консистентность удалений — если какой-то bucketservice лежит в момент удаления — другие сохраняют к себе запись типа «foreign delete», то есть «данный объект был удалён в другом месте» и после его поднятия досылают ему записи удалений. | * Консистентность удалений — если какой-то bucketservice лежит в момент удаления — другие сохраняют к себе запись типа «foreign delete», то есть «данный объект был удалён в другом месте» и после его поднятия досылают ему записи удалений. | ||
* Восстановление — тупое, только полным копированием тома на отсутствующие/повреждённые реплики. | * Восстановление — тупое, только полным копированием тома на отсутствующие/повреждённые реплики. | ||
<pre> | <pre> | ||
− | + | + bucket-видимо pg. ан нет, это еблоб реплицированный. волюм seaweedfs. правда странички по 4 кб. есть crc на 4 кб. фоновые скрабы. нахуя 4кб.. если хедеры м | |
елкие | елкие | ||
− | + | + версия бакета = оффсет в файле. о, дельты, привет! | |
− | + | + zeptoproxy клиент прямо рядом с приложением | |
− | + | + 1 диск = 1 bucketservice. разные порты. осд короче. фоновые - bucketcompactor | |
- statusservice. индекс бакетов. дельтами получает. держит карту бакетов в памяти. api: дай бакет для записи, дай адрес по бакету. пошардирован по дц. мастер | - statusservice. индекс бакетов. дельтами получает. держит карту бакетов в памяти. api: дай бакет для записи, дай адрес по бакету. пошардирован по дц. мастер | ||
для своих бакетов %3 | для своих бакетов %3 | ||
− | + | + размер бакета 2 ГБ. пиздец же, мало. а они довольны, типа меньше чем было | |
− | + | + fallocate. врайты в конец. мало меты. мало лишних иопс | |
− | + | + кворумная запись. пись. пись | |
- x2, x3, x1.5 | - x2, x3, x1.5 | ||
- xor. полторирование. ебать хитрая сосиска. после закрытия. ну видимо конвертация сосиски после. а шо с удалением из ec? | - xor. полторирование. ебать хитрая сосиска. после закрытия. ну видимо конвертация сосиски после. а шо с удалением из ec? | ||
Строка 165: | Строка 165: | ||
- пары это logical partitions | - пары это logical partitions | ||
- ретраи на пут, на гет. все ясно. а если данные убрали из памяти, стрим? | - ретраи на пут, на гет. все ясно. а если данные убрали из памяти, стрим? | ||
− | + | + zeptoid=bid+recordid, 64bit. 2^64 байт? = 16 ЕБ. смещение что ли? почта = 15 пет, им похуй. ебааааать, индекс удалений. ну да, забавно сделано | |
− | + | + delete = put в конец. lock. compact. по % удалений как и везде. а EC? | |
− | + | + консистентность делете: ну это томбстоуны, понятно... а, не совсем. есть foreign del, форвард другому бакету | |
- zeptoctl. move in = новая группа. тоже приоритет пустых. потом будет перекос по get-ам. есть масштабирование. средний du. не, стоп, а нагрузка? | - zeptoctl. move in = новая группа. тоже приоритет пустых. потом будет перекос по get-ам. есть масштабирование. средний du. не, стоп, а нагрузка? | ||
− | + | + 18Т диски, 12Т вложения, 6Т письма, 20-40 иопс на диск. вложения отдельно, не зепто. 60 дисков на сата-полке. сата? | |
- zstd. 15т -> 30т -> 15т | - zstd. 15т -> 30т -> 15т | ||
- серверов 3к -> 1.5к. индексы в 250 | - серверов 3к -> 1.5к. индексы в 250 | ||
Строка 176: | Строка 176: | ||
- удаления накур. лишнее ио. | - удаления накур. лишнее ио. | ||
- ручной move in, fix. боязнь админов, ага. | - ручной move in, fix. боязнь админов, ага. | ||
− | + | + как смигрировать 50пб в 32 | |
− | + | + синк по смещениям? | |
− | + | + Вадим ты чота завернул блеа. 6 дисков 15 пар | |
− | + | + запись под локом. статус сервис лочит. епт. 72д по 6т. | |
− | + | + цеф им нинужен. как удаления из ец хз лол, он не ответил | |
− | + | ||
- большие файлы чанкуются по 64 мб. | - большие файлы чанкуются по 64 мб. | ||
- zeptoId какой-то еще последней записи. емое... в которой все. ааа. понятно. она с чанками | - zeptoId какой-то еще последней записи. емое... в которой все. ааа. понятно. она с чанками |
Версия 20:16, 6 декабря 2022
Топовая Бунинская конференция, самая распиаренная и самая отъевшаяся — к счастью, до вменяемых пределов, в отличие от еврогейских, где вообще всё коммерциализировано вусмерть и даже докладчики доплачивают за участие. :-)
Общее впечатление: на удивление, довольно бодро. Весенний хайлоад — 2021, перенесённый на весну 2022 — был значительно тухлее, на нём я тоже выступал, но о докладах даже заметок себе вменяемых не оставил.
Вообще, прошлые хайлоады я не мог отделаться от мысли, что каждый год выступают одни и те же лица с одними и теми же темами докладов — Сысоев и nginx, постгрес-про, mysql, куратор, erlyvideo, одноглазники с java-микросервисами, какое-нибудь badoo на php… в общем всё норм, но уже поднадоедало. Что случилось сейчас — не знаю, возможно, «одни и те же лица» уехали в сторону горы Арарат. :-) хотя Максим Лапшин с erlyvideo был. :-) но так или иначе, повторюсь — некое ощущение новизны всё-таки было. А может, это меня отпустило.
Проходила конференция снова в Крокусе, стоила для участников, кажется, 60к (в 2013 было 21к… инфляция :D). Организация была вполне приличная, всего хватало — и места, и плюшек, и еды, и гардеробов, и стоек регистрации. От практики раздачи тонн макулатуры, видимо, отказались, и слава богу, спину ей только оттягивать. Залов параллельно было аж 8, но, к счастью, «основных» 4 — в общем, угрызаемо.
Содержание
- 1 День 1
- 1.1 Exadata для PostgreSQL
- 1.2 Мы смогли запустить Debezium
- 1.3 GeeseFS — ФС из S3
- 1.4 Тарантул для самых маленьких
- 1.5 Angie — форк nginx (ООО Веб Сервер)
- 1.6 Стородж Яндекса может всё
- 1.7 Жизнь перф инженера в Pg Pro
- 1.8 Хранилище почты mail.ru
- 1.9 SPQR для постгри
- 1.10 Как сцилла стояла раком
- 1.11 ZFS в ZFS → WA и тормоза
- 2 День 2
День 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… в зависимости от применённого подхода к распределению данных. Так что на самом деле рассмотренный в докладе вопрос гораздо значительнее, чем может показаться на первый взгляд :-).
Жизнь перф инженера в 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.
Отличительные черты:
- Волюмы/бакеты.
- В zepto нет индексов (почти!). Объект идентифицируется прямо смещением внутри тома.
- А как же удаления, спросите вы, если смещение — это ID? А удаления реализуются через индекс удалений («индекс дырок»), добавляемый при сборке мусора. Видимо, вида «старое смещение → новое смещение». Ну такое… :) если сильно изрубить всё в труху удалениями, всё равно индекс большой получится.
- В zepto объекты нарезаются на странички по 4 КБ и от каждой странички считается контрольная сумма crc32.
- Размер одного бакета — 2 ГБ. Логично, ибо под смещение выделено 32 бита. Плюс ещё 32 бита — ID бакета. Соответственно, общий лимит места в zepto-кластере — 16 ЭБ; под почту, которой всего 15 ПБ, этого хватает с головой :)
- Бакеты складываются в 2 ТБ разделы дисков и один раздел (~1000 бакетов) обслуживается 1 процессом «bucketservice». В ноде 72 диска по 18 ТБ, но под Zepto на них обычно выделено только 4-6 ТБ, так что на одной машине живёт примерно 216 bucketservice-ов.
- Процесс-переупаковщик бакетов называется bucketcompactor.
- Репликация — клиентская, запись — кворумная. То есть клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов.
- Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.
- Консистентность удалений — если какой-то bucketservice лежит в момент удаления — другие сохраняют к себе запись типа «foreign delete», то есть «данный объект был удалён в другом месте» и после его поднятия досылают ему записи удалений.
- Восстановление — тупое, только полным копированием тома на отсутствующие/повреждённые реплики.
+ bucket-видимо pg. ан нет, это еблоб реплицированный. волюм seaweedfs. правда странички по 4 кб. есть crc на 4 кб. фоновые скрабы. нахуя 4кб.. если хедеры м елкие + версия бакета = оффсет в файле. о, дельты, привет! + zeptoproxy клиент прямо рядом с приложением + 1 диск = 1 bucketservice. разные порты. осд короче. фоновые - bucketcompactor - statusservice. индекс бакетов. дельтами получает. держит карту бакетов в памяти. api: дай бакет для записи, дай адрес по бакету. пошардирован по дц. мастер для своих бакетов %3 + размер бакета 2 ГБ. пиздец же, мало. а они довольны, типа меньше чем было + fallocate. врайты в конец. мало меты. мало лишних иопс + кворумная запись. пись. пись - x2, x3, x1.5 - xor. полторирование. ебать хитрая сосиска. после закрытия. ну видимо конвертация сосиски после. а шо с удалением из ec? - схема добавления дисков в кластер. жесткая. это как? а, видимо разделения места. я так умею на lpsolve, лолъ - пары это logical partitions - ретраи на пут, на гет. все ясно. а если данные убрали из памяти, стрим? + zeptoid=bid+recordid, 64bit. 2^64 байт? = 16 ЕБ. смещение что ли? почта = 15 пет, им похуй. ебааааать, индекс удалений. ну да, забавно сделано + delete = put в конец. lock. compact. по % удалений как и везде. а EC? + консистентность делете: ну это томбстоуны, понятно... а, не совсем. есть foreign del, форвард другому бакету - zeptoctl. move in = новая группа. тоже приоритет пустых. потом будет перекос по get-ам. есть масштабирование. средний du. не, стоп, а нагрузка? + 18Т диски, 12Т вложения, 6Т письма, 20-40 иопс на диск. вложения отдельно, не зепто. 60 дисков на сата-полке. сата? - zstd. 15т -> 30т -> 15т - серверов 3к -> 1.5к. индексы в 250 - облако 80 пб, х1.5. сниппеты поиска 2.4п. - гибридная схема тоже хотят. - удаления накур. лишнее ио. - ручной move in, fix. боязнь админов, ага. + как смигрировать 50пб в 32 + синк по смещениям? + Вадим ты чота завернул блеа. 6 дисков 15 пар + запись под локом. статус сервис лочит. епт. 72д по 6т. + цеф им нинужен. как удаления из ец хз лол, он не ответил - большие файлы чанкуются по 64 мб. - zeptoId какой-то еще последней записи. емое... в которой все. ааа. понятно. она с чанками
В общем, ждём ебилдов (c).
SPQR для постгри
Денис Волков, Кирилл Решке (Yandex Cloud) - SPQR: горизонтальное масштабирование PostgreSQL
Пытался смотреть доклад в режиме вытесняющей многозадачности параллельно со сцыллой.
Как сцилла стояла раком
Илья Орлов (STM Labs) - Укрощение мифического чудовища: реальный опыт промышленного использования ScyllaDB без прикрас
ZFS в ZFS → WA и тормоза
Андрей Копейко (VK) — Как «добиться» времени записи 200 мс на NVMe-дисках
Не смотрел, но упомяну, ибо смотрел коллега. Чуда, увы, не произошло, ничего гениального типа внутренних алгоритмов работы SSD в докладе не было. Вместо этого классическое: ZFS со сжатием, в нём Proxmox, в виртуалке опять ZFS со сжатием, в ней TimescaleDB опять со сжатием, а в неё заливаем 28 ТБ данных.
Вуаля, вот ваши тормозные чтения с NVMe. И заодно удроченный на 50 % паспортного TBW за 10 месяцев диск.
Ну а что вы хотели. WA оно такое. Надо было ещё Ceph поставить, смогли бы и секунды добиться… :)
День 2
?
Егор Хайруллин (Яндекс) - Как перейти от batch к streaming на примере рекламной контент-системы
Graphviz от безопасника ядра
Александр Попов (Positive Technologies) - Безопасность ядра Linux: в теории и на практике
Примитивные хаки k8s
Лев Хакимов - Хакнуть K8s: разбор пэйлоадов и способов защиты
DBA ловит тормоза диска через eBPF
Пётр Бобров (QIWI) - Мониторинг черных ящиков и котов в мешке через eBPF
MVCC в тарантуле
Александр Ляпунов (Tarantool) - Как работает MVCC в In-Memory-СУБД
Экодиктант за 2 месяца
Станислав Жуковский, Василий Шалимов (Старботс РФ) - Экодиктант 2021: highload-проект с нуля за 2 месяца
DNS-aaS через SDN
Георгий Меликов (VK Cloud) - Полная изоляция клиентов в облаке для сервисов без изоляции на примере DNS