Как стать автором
Обновить

Реализация глобальных индексов в распределённой системе

Уровень сложностиСредний
Время на прочтение17 мин
Количество просмотров4.2K
Всего голосов 22: ↑22 и ↓0+25
Комментарии3

Комментарии 3

Отличная статья!
Решения вроде как простые и известные, и грабли многие известные. Но опыт все равно интересный, и написано хорошо.

По поводу метрики о не уникальности значений бакета.

Это можно сделать приблизительно достаточно легко.

Можно поддерживать структу данных в памяти, типо "Find top k (or most frequent) numbers in a stream". Можно использовать вероятностную структуру которая не будет хранить все данные.

Дальше делим количество топ 10 на общее

В целом, мы можем и в ручном режиме найти тяжёлые бакеты. По метрикам тарантула на инстансах глобального индекса увидеть перекос количества записей, а дальше на реплике по каждому бакету посчитать count записей (это достаточно быстро, потому что на поле с бакетом висит локальный индекс для решардинга). В тарантуле это будет что-то вроде такого наколеночного кода:

box.space._bucket
    :pairs()
    :map(function(t) return tostring(t[1]), box.space.index_space.index.bucket_id:count({ t[1] }) end)
    :tomap()

Дальше мы из этого списка сможем найти бакеты с самым большим количеством записей.

Но чтобы понять какими данными в итоге перекосило придётся уже сканить эти самые толстые бакеты.

Что касается подсчёта дублей в потоке (как я понимаю Count sketch имеется ввиду), это выглядит рабочим вариантом. Только если у нас структура будет лежать в памяти, мы будем терять её с рестартами, а если персистить в спейс, потеряем в производительности. Можно и не персистить, но тогда большие индексы которые лежат и не обновляются выпадут из внимания. Но в каких-то кейсах такой подход действительно может сработать. Спасибо за вариант.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий