CRDTs использовать математику для обеспечения согласованности между распределенным кластером, не беспокоясь о консенсусе и а ssociated latency/unavailability.
Набор значений, которые CRDT может принимать в любое время, относится к категории полурешетки (в частности, полурешетки соединения), которая представляет собой ПОЗЕТ (частично упорядоченное множество) с наименьшей функцией верхнего предела (LUB).
Проще говоря, ПОЗЕТ представляет собой набор предметов, в которых не все сопоставимы. Например. в массиве пар: {(2,4), (4, 5), (2, 1), (6, 3)}
, (2,4)
- < (4,5)
, но не может сравниться с (6,3)
(поскольку один элемент больше, а другой меньше). Теперь полурешетка представляет собой POSET, в котором заданы 2 пары, даже если вы не можете сравнить их, вы можете найти элемент, который больше, чем оба.
Другое условие заключается в том, что обновления этого типа данных должны увеличиваться, CRDT имеют монотонно увеличивающееся состояние, когда клиенты никогда не наблюдают откат состояния.
Этот excellent article использует массив, который я использовал выше в качестве примера. Для CRDT, поддерживающего эти значения, если 2 реплики пытаются достичь консенсуса между и (6,3)
, они могут выбрать LUB = (6,5)
в качестве консенсуса и назначить для него как реплики. Поскольку значения увеличиваются, это хорошее значение для расчета.
Существует два способа синхронизации CRDT между собой по репликам, они могут передавать состояние через периодически (конвергентный тип реплицированных данных) или могут передавать обновления (дельта) по мере их получения (коммутативный тип реплицированных данных). Первый использует большую пропускную способность.
SoundCloud's Roshi - хороший пример (хотя, по-видимому, он больше не работает), они хранят данные, связанные с меткой времени, где метка времени явно увеличивается. Любые обновления, входящие в временную метку, меньшую или равную той, которая хранится, отбрасываются, что гарантирует, что идемпотентность (повторяющиеся записи в порядке) и коммутативность (из-за отсутствия записи в порядке. Commutativity - a=b means b=a
, что в данном случае означает update1, за которым следует update2 то же, что и update2, а затем update1)
Писания отправляются во все кластеры, и если определенные узлы не могут ответить из-за проблемы, например, медленности или раздела, ожидается, что они будут позже догонять через read-repair
, что гарантирует, что значения сходятся. Конвергенция может быть достигнута с помощью двух протоколов, как я упоминал выше, распространения состояния или обновлений для других реплик. Я считаю, что Роши делает первое. Как часть read-repair
, состояние обмена репликами, и поскольку данные соответствуют свойству полурешетки, они сходятся.
PS. Системы, использующие CRDT, в конечном итоге согласуются, то есть они принимают AP (высокодоступные и устойчивые к перегородке) в CAP theorem.
Another excellent read on the subject.
Марк ответ принят, если он ответит на ваш вопрос. –