Бесконфликтные реплицированные типы данных (CRDT) vs Paxos или Raft

когда это хорошая идея использовать что-то вроде CRDT вместо paxos или raft?

7 ответов


Если вы можете использовать что-то вроде CRDT, сделайте это. Вы должны получить гораздо лучшую производительность. Он также позволяет интересные варианты использования, такие как работа в автономном режиме, а затем слияние позже. Однако не всегда возможно спроектировать вещи так, чтобы CRDT работал для вас. В этом случае, paxos может решить трудные проблемы для вас.

но даже если вы решили использовать paxos, как правило, вы должны ограничить, сколько работы выполняется непосредственно через алгоритм paxos. Вместо этого причины производительности вы хотите зарезервировать paxos для необходимых операций, таких как основные выборы, а затем позволить реплицированной основной установке обрабатывать большинство решений. (В среде с высокой пропускной способностью мастер, вероятно, сделает что-то вроде делегирования ответственности за определенные фрагменты конкретным детям, которые реплицируются друг с другом. Не позволяйте мастеру стать узким местом...)

тем не менее, гораздо легче утверждать, что вы будете махать волшебной палочкой паксоса, чем на самом деле делайте это на практике. В этом свете ты можешь найти ... http://static.googleusercontent.com/external_content/untrusted_dlcp/research.google.com/en/us/archive/chubby-osdi06.pdf чтобы быть интересным описанием трудностей, с которыми может столкнуться реализация paxos в реальном мире.


Я думаю, что этот парень знает о чем говорит:

блог

видео

заключение о распределенных системах


CRDTs и Paxos имеют разные цели и используются в разных сценариях. Они имеют общее, что они помогают программистам иметь дело с параллелизмом/репликацией. CRDTs-это типы данных, которые asume параллельные обновления будут происходить. Paxos-это протокол, который обеспечивает их обычай, обеспечивая полный порядок на них. Давайте рассмотрим это более подробно.

допустим, у нас есть реплицировать набор, который реплицируется в двух разных местах.

используя Паксос!--2--> гарантирует, что запись в набор будет осуществляться каждую реплику в том же порядке. В общем,это гарантирует, что все реплики согласуются с тем, как развивается состояние множества.

Если у вас есть, например, user1, выполняющий update1 в replica1, добавление элемента 1 в реплицируемый набор, в то время как user2 одновременно выполняет update2, добавляя element2 в replica2, Paxos заставит реплики согласиться с заданным порядком для этих обновлений или, возможно, согласиться на выберите одно из двух обновлений и отбросьте второе, в зависимости от того, как вы его используете и чего хотите достичь. Если результат Paxos, скажем, что update1 приходит до update2, каждая реплика обновит набор в этом порядке. Как следствие, пользователи, читающие набор одновременно с этими обновлениями, могут наблюдать, независимо от того, где (в какой реплике) они читают, только следующие состояния набора (предполагая, что набор был пуст в начале):

{} (пустой set)

{element1}

{element1, element2}

кроме того, эти состояния можно увидеть только в этом порядке, что означает, что как только состояние множества {element1, element2} (в каждой реплике), никакое последующее чтение не вернет {} или {element1}.

положительная сторона: этот набор прост в рассуждении, так как он эквивалентен набору, который не реплицируется.

отрицательные стороны: Недоступность: если реплики не могут разговаривать друг с другом (сеть partition), ваш набор не может быть обновлен, так как не может быть соглашения. Низкая производительность, высокая задержка: соглашение требует синхронизации реплик перед ответом клиенту. Это приводит к задержке, пропорциональной задержке между репликами.

CRDTs имеют более слабые гарантии. Набор CRDT не эквивалентно последовательного, один-копия одна. Он asumes, что нет согласия или общего порядка о том, как реплики обновляются.

CRDTs гарантирует, что если обе реплики набора видели одни и те же обновления (независимо от того, в каком порядке они их видят), тогда они будут показывать одно и то же состояние; реплики будут сходиться.

в нашем примере двух пользователей, выполняющих обновления одновременно, система, которая не запускает Paxos для заказа операций на множестве (это происходит, например, при возможной или причинной согласованности), позволит replica1 добавить элемент1, в то время как replica2 добавляет элемент2

таким образом, состояние в replica1 будет: {element1}

и состояние в replica2 будет: {element2}

в этот момент времени реплики расходятся. Позже, когда реплики синхронизируются, они будут обмениваться обновлениями, наконец, показывая это состояние:

состояние в replica1 будет: {element1, element2}

состояние в replica2 будет: {element2, element1}

в этот момент времени реплики сошлись.

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

{} (пустое множество)

{element1} (если они читают из replica1)

{element2} (если они читают из replica2)

{element1, element2}

{element2, element1}

отрицательная сторона: этот набор трудно рассуждать, так как он показывает состояния, которые не могли произойти в последовательном наборе. В нашем например, мы наблюдали только случай двух параллельных добавлений к множеству, что является простым. Одновременное добавление и удаление более сложны есть много типов данных с различными проблемами:

комплексное исследование конвергентных и Коммутативных реплицированных типов данных

положительные стороны: Высокая доступность: если реплики не могут разговаривать друг с другом (сетевой раздел), ваш набор может быть обновлен. Реплики синхронизируются при обратном подключении. Высокая производительность, низкая задержка: реплики немедленно отвечают клиентам и синхронизируются в фоновом режиме после ответа клиенту.


существует недостаток в Примере CRDT Treedoc. Каждый узел требует определитель контекста для случая, когда две системы вставьте в то же время с одинаковым ключом.

после этого системы больше не могут вставлять между записями, которые имеют идентичные ключи, но разные disambiguators, так как это требует, чтобы система вставляла другой идентичный ключ, но контролировала порядок disambiguator. В disambiguators не плотная, так что это не всегда возможно. Если disambiguators были еще одним деревом, вы решаете одну проблему, но затем нужен другой механизм разрешения конфликтов на глубину ниже ... так далее.

эта не упомянутая проблема, плюс тот факт, что вам нужно сделать двухфазную фиксацию, чтобы привести в порядок метаданные, заставляет меня думать, что CRDTs все еще работают.


У нас есть несколько показателей:

  • пропускная способность (CRDT и Paxos одинаковы, потому что все запросы реплицируются на всех репликах в конце концов независимо от CRDT или Paxos);
  • задержка (CRDT лучше, чем Paxos, потому что он записывает на меньшее количество реплик);
  • надежность (CRDT слабее, чем Paxos, потому что он записывает на меньшее количество реплик (меньше большинства), которые могут привести к потере состояния);
  • последовательность (CRDT слабее, чем Paxos, потому что он позволяет одновременную запись без точки синхронизации (в основном без перекрывающихся реплик), в то время как Paxos пишет всегда требует перекрывающейся реплики для сериализации).

мое предложение заключается в том, что мы должны использовать Paxos, когда реплики находятся недалеко друг от друга (например, в центре обработки данных), и использовать CRDT, когда разбиение сети является нормальным (например, отключенный мобильный).


комментарий к ответу @btilly:

вопрос в теме связан с различными моделями согласованности и, следовательно, шаблонами проектирования:

CRDT и Paxos очень разные вещи, и использование должно быть решено на основе ваших требований к архитектуре. Я считаю, что лучший способ справиться с этим-рассмотреть случаи использования, когда эти алгоритмы были успешно применены.

шаблоны использовать:

CRDT может использоваться для синхронизации данных между клиентами (т. е. мобильными устройствами) и серверами, совместного редактирования в реальном времени, значений синхронизация в реализациях dist-db и во всех других случаях, когда возможная согласованность прекрасна.

PAXOS в основном используется в проприетарных системах, поддерживающих инфраструктуру систем (например, Chubby), или для реализации синхронизации в распределенных системах баз данных, таких как BigTable, Datastore, Spinnaker, Spanner и т. д.

плот более популярен в инфраструктурных проектах OSS, таких как ETCD, Consul, ...

(Не помню, на чем основаны CockroachDB и TiDB)

там также BFT, но его используется меньше.

p.s. Паксос != ZooKeeper. ZooKeeper использует другой алгоритм, называемый ZAB, и не является реплицированной машиной состояний, а реплицированной машиной моментальных снимков с одним писателем и расслабленной моделью чтения. Google основан на Paxos, но является его собственностью.

p.s.s. Интересно, как Паксос развивался все эти годы. За последние 20 лет было изобретено множество вариантов обработки различных оптимизаций краевых случаев, размеров кворумов и кластеров реконфигурация.


когда это уместно. Тем не менее, PaxOS не так уж плох, поскольку его пропускная способность обычно такая же, как и с CRDT, не говоря уже о том, что надежность намного выше (CRDT может привести к потере состояния), и его латентность не так уж плоха, поскольку она требует только большинства ответов реплик вместо всех.