Разрешение конфликтов в Tarantool (как исправить репликацию в режиме мастер-мастер в случае конфликтов) - PullRequest
2 голосов
/ 24 июня 2019

Как я могу реализовать разрешение конфликтов при использовании Tarantool в мультимастерном сценарии?

Я разрабатываю сервис, который должен быть высокодоступным, поэтому решил использовать nginx в качестве балансировщика нагрузки (с директивой резервного копирования) для двух узлов tarantool (с отключенной опцией только для чтения). Он повторяет неудачные запросы к другому узлу, но в случае сетевых проблем (например, между узлами tarantool) могут возникнуть конфликты.

Как мне реализовать один из следующих сценариев:

  1. Выберите новый кортеж на каждом узле
  2. Пользовательская логика (может быть другое пространство для конфликтов и т. Д.)

Другой вопрос, как я могу определить уникальный составной индекс, допускающий значение NULL (значение NULL может встречаться несколько раз)

| id | user_id | type | {some data} |

Индексы:

id - PK
user_id + type - unique nullable tree index (type is nullable)
user_id has non unique tree index

Ответы [ 2 ]

2 голосов
/ 11 июля 2019

Относительно 2) (комбинация on_ctl_init + _space: on_replace), есть еще одна хитрость: вам нужно использовать box.on_commit, чтобы получить доступ к создаваемому пространству. Результирующий фрагмент будет следующим:

local my_space_name = 'ny_space'
local my_trigger = function(old, new) ... end
box.schema.on_ctl_init(function()
    box.space._space:on_replace(function(_, new_space)
        if new_space.name == my_space_name then
            box.space[my_space_name]:before_replace(my_trigger)
        end
    end)
end)
2 голосов
/ 25 июня 2019

1) Вам необходим триггер before_replace для пространства, в котором может возникнуть конфликт, для реализации правил разрешения конфликтов вашего приложения.

https://www.tarantool.io/en/doc/2.1/book/box/box_space/#box-space-before-replace

В триггере вы можете сравнить старую и новую записи реплики и выбрать, какую из них использовать (или полностью пропустить обновление, или объединить две записи вместе).

2) Вам необходимо установить триггер в нужное время, прежде чем пространство начнет получать какие-либо обновления. Способ, которым вы обычно устанавливаете триггер before_replace, является правильным при создании пространства, поэтому вам нужно, чтобы триггер установил другой триггер в системном пространстве _space, чтобы зафиксировать момент, когда ваше пространство было создано, и установить триггер там. Это может быть триггер on_replace, https://www.tarantool.io/en/doc/2.1/book/box/box_space/#box-space-on-replace разница между before_replace и on_replace заключается в том, что * on_replace вызывается после вставки строки в пространство, и before_replace вызывается раньше. 3) Чтобы установить триггер _space: on_replace (), вам также необходимо выбрать правильное время. Лучшее время для использования - это когда _space только что создан, что является триггером box.ctl.on_schema_init (). https://www.tarantool.io/en/doc/2.1/book/box/box_ctl/#lua-function.box.ctl.on_schema_init

...