Изменения

Перейти к: навигация, поиск

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

2811 байтов добавлено, 21:10, 6 декабря 2022
Нет описания правки
Вышло в общем-то очередное [https://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf Haystack]/[https://github.com/chrislusf/seaweedfs SeaweedFS]-подобное хранилище. В Яндексе MDS, про который шла речь в докладе Вадима выше, тоже похожий (упоминания также есть в [https://habr.com/ru/company/yandex/blog/311806/ статьях на хабре]).
'''Общие черты:''' 
* Append-only volume-ы с переупаковкой. То есть, объекты хранятся в дописываемых всегда в конец больших файлах-томах вперемешку с заголовками, при удалении из тома сразу не удаляются, а только помечаются удалёнными — а потом, когда количество удалённого превышает определённый %, приходит отдельный процесс (называемый по вкусу compaction/defrag/gc/repack) и перезаписывает том целиком, на этот раз действительно удаляя удалённые объекты. Волюмы fallocate-ятся, чтобы исключить фрагментацию места в ФС.
* Есть «шарды», являющие собой группы из N (2, 3 или ещё скольки-то) таких томов на разных машинах, связанных репликацией вместе. То есть, запись идёт в пары или тройки томов. В терминологии Ceph шард — по сути, PG (placement group). В терминологии zepto — «бакет» (и сам волюм тоже, видимо, называется «бакет»).
* Есть «прокси», предоставляющие 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-ов.
** Процесс-переупаковщик бакетов называется bucketcompactorБольшие объекты нарезаются на части по 64 МБ, сначала пишутся части, в конце — индекс, ссылающийся на эти части.* Репликация — клиентская, запись — кворумная. То есть клиент (прокся) напрямую соединяется с несколькими серверами * После заполнения бакет закрывается и пишет свои данные на каждыйв него больше не пишут, а только удаляют и считает запись успешной при записи на 2 из 3 серверовпотом переупаковывают. Процесс-переупаковщик бакетов называется bucketcompactor.
* Распределение объектов — перед каждой записью идём в statusservice и спрашиваем у него, в какой бакет писать. При этом бакет на запись блокируется. При удалении аналогично, тоже блокировка. После записи разблокируем и обновляем версию бакета в statusservice. Версией служит просто последнее смещение в бакете.
* Репликация — клиентская, запись — кворумная. То есть клиент (прокся) напрямую соединяется с несколькими серверами и пишет свои данные на каждый, и считает запись успешной при записи на 2 из 3 серверов. При неуспехе — повторная попытка в другой бакет.** Консистентность удалений — если какой-то bucketservice лежит в момент удаления — другие сохраняют к себе запись типа «foreign delete», то есть «данный объект был удалён в другом месте» и после его поднятия досылают ему записи удалений.** Восстановление — тупое, только полным копированием тома на отсутствующие/повреждённые реплики. Причём вообще, вроде, в разрезе разделов, а не отдельных волюмов.* Слой управления (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, но этого нет. Кодируется каждый объект отдельно.
<pre>
+ 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?
+ запись под локом. статус сервис лочит. епт. 72д по 6т.
+ цеф им нинужен. как удаления из ец хз лол, он не ответил
- + большие файлы чанкуются по 64 мб.- + zeptoId какой-то еще последней записи. емое... в которой все. ааа. понятно. она с чанками
</pre>

Навигация