Pull to refresh
4K+
4
Никита Иващенко@phiker

Старший разработчик в команде S3

34,1
Rating
1
Subscribers
Send message

Здравствуйте! Затронули очень интересный краевой случай, а что если бакет занимает существенный процент от всего кластера и его нельзя никуда перенести - так как нигде столько свободного места нет. Либо бакет вообще занимает весь кластер и продолжает расти, что тогда делать?

Проблема не то, чтобы уникальная. Точно так же можно растить экземпляр PostgreSQL, пока не упрётесь в место, а потом, скорее всего, пошардируете базу. С бакетами можно поступить аналогично - пошардировать. Если речь идёт про какое-то коробочное хранилище, то придётся делать это руками: создавать mybucket-1, …, mybucket-N в разных кластерах. Но эта логика шардирования протекает в клиентский код, что не очень удобно, мягко говоря. В таком случае клиентское приложение знает детали реализации хранилища и отвечает самостоятельно за маршрутизацию до объектов. Намного проще будет клиентам, если эта логика скрывается и вы работаете якобы с одним бакетом mybucket

В нашей схеме шардировать бакеты довольно удобно. Например, клиент всё так же ходит в s3front и обращается к бакету mybucket, а s3front по определённому правилу понимает, что требуемый объект лежит в шарде, предположим, mybucket-42 в зоне B, и отправляет запрос в эту зону. Таким образом основные доработки нужны на уровне метаданных для корректной маршрутизации запросов, а кластеры Ceph могут оставаться в тех же размерах

Тут есть несколько моментов. Начнём с того, что мы используем S3-протокол, поэтому, чтобы узнать, что лежит в бакете в кластере-источнике, нужно использовать ListObjectsV2 или аналог. Листинг фактически однопоточный, поэтому эта фаза миграции будет запущена только на одном поде. Мы можем залистить страницу объектов, перенести пачку этих объектов, проверить, что всё перенеслось без ошибок и пойти дальше, ошибки куда-то сохранить. Если вдруг под упал, то после старта достаём ContinuationToken и продолжаем работу. Вполне понятный вариант

Но это однопоточная схема, а хочется переносить объекты в несколько подов. Получается, нужно организовать передачу этой пачки или постоянного потока объектов из листинга другим подам, чтобы они начали переносить параллельно. Причём ContinuationToken описывает позицию в листинге, а не состояние переноса: как только объекты внутри страницы везутся конкурентно, по токену уже не понять, что залистили, что успели перенести, а что упало с ошибкой. В этот момент можно рассматривать разные схемы, но один из вариантов будет просто листить все объекты в персистентное хранилище и параллельно начать их переносить, как у нас и реализовано

Ну и некоторые фазы опираются на сравнение двух снапшотов листинга. Например, релистинг, который ищет объекты, собранные из частей мультипарта

Архитектур S3-совместимых хранилищ, конечно, много. Можно разделять слой метаданных и бинарных данных, как это делаем мы. Можно хранить метаданные рядом с бинарными данными, как MinIO. Есть хранилища, которые прям заточены под маленькие объекты, к примеру SeaweedFS, но везде свои нюансы

Справедливо, что Ceph ограничивает размер зоны, и хочется подумать, как снять это ограничение. Причём сам Ceph как хранилище бинарных данных у нас не вызывает вопросов. Для снятия ограничений я бы думал не в сторону замены Ceph, а в сторону шардированных бакетов, которые могут жить в нескольких зонах (и, соответсвенно, в нескольких кластерах Ceph) сразу. Для этого не нужно заменять Ceph или менять размеры его кластеров, основные вопросы лежат в области метаданных и маршрутизации запросов в нужную зону

Information

Rating
222-nd
Works in
Registered
Activity