Может работать в двух режимах:
- Режим шардинга
- Режим решардинга
Режим решардинга определяется по факту наличия двух функций выбора шарда (prev
& curr
).
Весь функционал шардинга расположен в одном файле shard.lua
.
Подключение производится при выполнении директивы в Вашем init.lua
:
require 'shard'
После этого момента становятся доступными функции box.shard.*
.
Пользователь определяет текущую функцию определения номера шарда (curr
),
а так же список шардов. Это действие необходимо провести при конфигурировании
каждого шарда.
Далее при запросах по ключу в запросе при помощи вызова функции curr
определяется номер шарда, на котором расположены нужные данные и выполняется
запрос к этому шарду при помощи библиотеки box.net.box
.
Помимо обычной функции curr
пользователь определяет еще и функцию prev
,
которая по аналогии с функцией curr
возвращает номер шарда по ключу. Но эта
функция описывает предыдущую схему шардинга.
Далее при запросах работает следующий алгоритм:
- ключ извлекается из запроса
- определяется номер шарда
curr
. - выполняются операции с шардом
curr
, если данных наcurr
нет, то выполняется операции с шардомprev
.
Для того чтобы выполнить решардинг нужно произвести следующие операции:
- для всех хостов определить функции
curr
иprev
, а так же обновить список шардов. - Запустить процесс
copy
на всех хостах (этот процесс будет вытеснять данные с хостаprev
на хостcurr
) - По завершении процесса копирования, необходимо удалить функцию
prev
из конфигурации всех шардов - Запустить процесс
cleanup
на всех шардах для удаления устаревших данных.
Условия запуска:
- текущий шард помечен как
rw
- на шарде прописаны обе функции
curr
иprev
Процесс запускается при вызове функции box.shard.copy()
,
далее этот процесс обходит все спейсы тарантула и для каждой записи каждого
спейса выполняет вычисление номера шарда curr
, а так же (при необходимости)
номера шарда prev
.
В случае если prev
указывает на текущий шард, а curr
указывает на другой
шард, то выполняет copy_from
(которая по сути является insert nothrow
) тапла на шард curr
(удаление тапла на своем шарде не производит).
В случае если на шарде curr
есть тапл с таким ключом, то insert
не производится.
Функция box.shard.copy()
возвращает список таплов каждый из которых содержит
два поля:
- номер обработанного спейса
- количество скопированных в нем записей (может быть 0)
Условия запуска:
- текущий шард помечен как
rw
- на шарде прописана только одна функция -
curr
(то есть режим решардинга отключен)
Процесс запускается при вызове функции box.shard.cleanup()
, далее
этот процесс обходит все спейсы тарантула и для каждой записи каждого спейса
выполняет вычисление номера шарда curr
. Если номер шарда curr
для записи
не равен текущему номеру шарда me
, то производится удаление этой записи.
Функция box.shard.cleanup()
возвращает список таплов, каждый из которых
содержит два поля:
- номер обработанного спейса
- количество удаленных в нем записей.
Конфигурирование выполняется одной функцией:
box.shard.schema.config({параметр = значение})
Конфигурирует (или переконфигурирует) шардхост (или прокси-хост), принимая следующие параметры:
list
- список шардов и их типыme
- номер текущего шарда в списке доступов (либо 0, если данный шард является прокси)mode
- режим работы текущего шарда (ro
,rw
)curr
- функция, возвращающая по номеру спейса ключу номер шарда на котором должна быть расположена запись в текущей схеме шардирования.prev
- функция, возвращающая по номеру спейса и ключу номер шарда на котором должна быть расположена запись в предыдущей схеме шардирования.
Вызов функции box.shard.schema.config
реконфигурирует только те параметры
которые переданы при данном вызове.
Прочие параметры оставляет в предыдущем состоянии.
Список шардов представляет собой lua
табличку, которая представляет собой
массив массивов, описывающих шарды.
Каждая запись, описывающая шард имеет следующие поля:
- режим работы шарда
mode
. Может иметь значения:ro
- шард только для чтения,rw
- шард для записи и чтения. - вес шарда (число 0 - 1000)
- Параметры для коннекта к шарду (
host
,port
)
Примечания:
- в описаниях каждого шарда не может быть более одного шарда в режиме
rw
- модифицирующие операции всегда обращаются к хостам
rw
. Немодифицирующие могут обращаться к хостамro
илиrw
в зависимости от семантики вызова.
Выполняет запрос данных по ключу (ключ возможно составной). Вычисляет по
переданным space:key
значение номера шарда curr
и переадресует этот запрос
на нужный шард.
В случае, если режим решардинга работает, а записи с данным ключем нет,
то переадресует запрос так же шарду prev
.
Примечания:
- в случае составного ключа он все должен быть полным (то есть выборки по частично определенному ключу нескольких записей невозможны)
- функция
select
может обращаться к хостам "только для чтения". При этом используется алгоритм выбора хоста в соответствии с весом хоста, определенным при конфигурировании.
То же что и box.shard.select
, но может принять параметр mode
,
который указывает что предпочтительнее при выборке. mode
может принимать
следующие значения:
ro
- означает что предпочтительно делать выборку с хостов, помеченных как "только для чтения".rw
- означает что необходимо сделать выборку исключительно с хостов, помеченных как "для чтения и записи".
Вызов box.shard.eselect('ro', ...)
полностью эквивалентен вызову
box.shard.select
.
Вставляет тапл по следующему алгоритму:
- извлекает ключ из переданного тапла
- вычисляет по ключу номер шарда (
curr
) - передает управление хосту
curr
для выполнения дальнейших операций - на хосте
curr
: если запись с таким ключом есть, то возвращает ошибку - на хосте
curr
: делает запросselect
на хостprev
, если тот определен. - на хосте
curr
: в случае если на хостеprev
данная запись существует, то возвращает ошибку, иначе делаетinsert
.
Вставляет (возможно заменяя) запись по следующему алгоритму.
- извлекает ключ из переданного тапла
- вычисляет по ключу номер шарда (
curr
) - передает управление на хост
curr
для выполнения дальнейших операций - делает вставку
replace
на шардеcurr
Удаляет запись
- передает управление хосту
curr
- выполняет удаление на
prev
- выполняет удаление на
curr
return exists_from_curr or exists_from_prev
- передает управление хосту
curr
- если запись присутствует, то выполняет
return update( ... )
- выбирает запись с хоста
prev
- если запись присутствует, то выполняет
return update( ... )
- выполняет
insert( {selected} ); return update( ... )
- выбирает случайный шард
- выбирает хост в пределах выбранного шарда, удовлетворяющий
mode
- делает вызов указанной функции на выбранном хосте