Распределённые блокировки
В данном разделе содержится информация об использовании Кипариса в качестве сервиса распределённых блокировок, аналога ZooKeeper.
Общие сведения
Для использования YTsaurus в качестве сервиса распределённых блокировок необходимо развернуть мастер-серверы кластера в нескольких локациях.
Локаций должно быть не менее трёх, в этом случае сервис переживёт отключение одной локации. Если мастер-серверы будут расположены в пяти локациях, то сервис переживёт отключение любых двух.
Устройство
В системе YTsaurus есть транзакции, которые бывают мастерными и таблетными. Мастерные транзакции реализуют пессимистическую модель блокировок, то есть взятие блокировки на узел Кипариса происходит синхронно и при этом проверяются возможные конфликты.
Пользуясь пессимистической моделью, можно сделать простую конструкцию, эмулирующую распределённую блокировку:
- Создаётся узел в Кипарисе (вне транзакций). Данный узел будет отвечать блокировке. Тип узла может быть любым, например
map_node
. - В том месте программы, где нужно взять блокировку на данный узел, создаётся транзакция. Под ней выполняется попытка взять эксклюзивную блокировку на узел.
- Если блокировку взять удалось, то можно выполнять код, защищённый данной блокировкой. При этом важно пинговать транзакцию. В случае если вызов ping не удался или транзакция была отменена — эксклюзивность выполнения теряется, соответственно, необходимо предпринять какие-то действия, например прервать выполняющийся процесс.
- Если блокировку взять не удалось, то нужно повторить процесс создания транзакции и взятия блокировки.
Как и в любой системе распределённых блокировок, если процесс (живущий под блокировкой) делает какие-то изменения в сторонней системе, которая никак не интегрирована с транзакциями YTsaurus, — полностью гарантировать эксклюзивность невозможно. Например, между соседними вызовами ping транзакция могла быть прервана и запущен параллельный процесс, взявший блокировку на этот же узел.
Когда изменения выполняются на том же кластере, где берётся блокировка, стоит в запросах к кластеру использовать опцию prerequisite_transactions
и указывать в ней транзакцию, под которой была взята блокировка. Тем самым система YTsaurus гарантирует, что запрос будет выполнен только при условии, что транзакция жива (и, соответственно, взята блокировка).
Использование
Для запуска процесса под блокировкой можно использовать команду run-command-with-lock, а можно реализовать логику со взятием блокировки самостоятельно в коде приложения.
Если процесс выполняет какие-то изменения на кластере и должен делать их эксклюзивно, то рекомендуется использовать блокировку прямо на данном кластере.
Квотирование
Запросы квотируются по пользователю кластера независимо от хоста источника запроса. По умолчанию квота на число запросов — 100 RPS. При её превышении запросы становятся в очередь, глубина очереди по умолчанию — 100 запросов. Если очередь заполняется, то при попытке отправить следующий запрос пользователь получит ошибку: Request queue size limit exceeded
. Лимиты могут быть увеличены администратором кластера.