Обновить

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

Уровень сложностиСредний
Время на прочтение17 мин
Охват и читатели11K
Всего голосов 22: ↑22 и ↓0+26
Комментарии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 имеется ввиду), это выглядит рабочим вариантом. Только если у нас структура будет лежать в памяти, мы будем терять её с рестартами, а если персистить в спейс, потеряем в производительности. Можно и не персистить, но тогда большие индексы которые лежат и не обновляются выпадут из внимания. Но в каких-то кейсах такой подход действительно может сработать. Спасибо за вариант.

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

Информация

Сайт
arenadata.tech
Дата регистрации
Дата основания
2016
Численность
501–1 000 человек
Местоположение
Россия
Представитель
Arenadata