Что такое протокол репликации CouchDB? Это как Git?

Есть ли техническая документация, описывающая, как работает репликация между двумя кушетками?

Каков основной обзор репликации CouchDB? Каковы некоторые примечательные характеристики?

Ответ 1

К сожалению, нет подробной документации, описывающей протокол репликации. В CouchDB есть только эталонная реализация, и Filipe Manana переписывает то же самое, что, вероятно, станет новым внедрением в будущем.

Однако, это общая идея:

Ключевые моменты

Если вы знаете Git, то знаете, как работает репликация Couch. Репликация очень похожа на нажатие или вытягивание с помощью распределенных исходных менеджеров, таких как Git.

Репликация CouchDB не имеет собственного протокола. Репликатор просто подключается к двум БД в качестве клиента, затем читает с одного и записывает в другой. Репликация Push - это чтение локальных данных и обновление удаленного БД; репликация тиража - это наоборот.

  • Забавный факт 1. Репликатор на самом деле является независимым приложением Erlang в своем собственном процессе. Он подключается к обеим кушеткам, затем считывает записи из одного и записывает их в другой.
  • Забавный факт 2: CouchDB не имеет возможности узнать, кто является обычным клиентом и кто является репликатором (не говоря уже о том, является ли репликация толчком или тягой). Все это похоже на клиентские подключения. Некоторые из них читают записи. Некоторые из них записывают записи.

Все течет из модели данных

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

  • Каждая запись в CouchDB полностью независима от всех остальных. Это отстой, если вы хотите сделать JOIN или транзакцию, но это потрясающе, если вы хотите написать репликатор. Просто выясните, как копировать одну запись, а затем повторите это для каждой записи.
  • Как и Git, записи имеют историю изменений связанного списка. Идентификатор ревизии записи - это контрольная сумма его собственных данных. Последующие идентификаторы ревизий представляют собой контрольные суммы: новых данных, а также идентификатор ревизии предыдущего.
  • В дополнение к данным приложения ({"name": "Jason", "awesome": true}) каждая запись хранит эволюционную шкалу всех предыдущих идентификаторов ревизий, ведущих к себе.

    • Упражнение: Сделайте минутку спокойного размышления. Рассмотрим любые две разные записи: A и B. Если идентификатор ревизии появляется на временной шкале B, то B определенно эволюционировал от A. Теперь рассмотрим Git сглаживание быстрой перемотки вперед. Ты слышал это? Это звук вашего разума.
  • Git на самом деле не является линейным списком. У него есть вилки, когда у одного родителя есть несколько детей. У CouchDB тоже есть.

    • Упражнение: Сравните две разные записи: A и B. Идентификатор версии не отображается на временной шкале B; однако, один идентификатор ревизии, C, находится как в временной шкале A, так и в B. Таким образом, A не эволюционировал из B. B не эволюционировал от A. Но скорее, A и B имеют общего предка C. В Git, это "вилка". В CouchDB это "конфликт".

    • В Git, если оба ребенка продолжат разрабатывать свои временные рамки самостоятельно, это круто. Форки полностью поддерживают это.

    • В CouchDB, если оба ребенка продолжат развивать свои временные рамки самостоятельно, это тоже круто. Конфликты полностью поддерживают это.
    • Интересный факт 3: CouchDB "конфликты" не соответствуют конфликтам Git ". Контекст Couch - это расходящаяся история изменений, что Git вызывает" fork". По этой причине сообщество CouchDB произносит "конфликт" с молчаливым n: "co-flicked".
  • Git также имеет слияния, когда у одного ребенка есть несколько родителей. У CouchDB тоже есть это.

    • В модели данных нет слияния. Клиент просто отмечает одну временную шкалу как удаленную и продолжает работать с единственной временной шкалой.
    • В приложении это похоже на слияние. Обычно клиент объединяет данные с каждой временной шкалы в зависимости от приложения. Затем он записывает новые данные на график. В Git это похоже на копирование и вставку изменений из ветки A в ветвь B, затем переход к ветки B и удаление ветки A. Данные были объединены, но не было git merge.
    • Эти поведения различны, потому что в Git важна сама шкала времени; но в CouchDB данные важны, а временная шкала - случайная, она просто поддерживает репликацию. Это одна из причин, почему встроенная ревизия CouchDB не подходит для хранения данных ревизий, таких как страница вики.

Заключительные примечания

По крайней мере одно предложение в этой записи (возможно, это одно) является полным BS.

Ответ 2

Спасибо Джейсону за отличный обзор! Дженс Альфке, который работает над TouchDB и его репликацией для Couchbase, (неофициально) описал алгоритм репликации CouchDB, если вы заинтересованы в технические подробности того, как работает "стандартный" репликатор CouchDB.

Подводя итог описанным выше шагам:

  • Выясните, как прошла предыдущая репликация.
  • Получить исходную базу данных _changes с этой точки
  • Используйте revs_diff в пакете изменений, чтобы увидеть, какие из них необходимы для целевого
  • Скопируйте любые отсутствующие метаданные ревизии и текущие данные документа + вложения из источника в цель, отправляя на bulk_docs как для оптимизации, так и для хранения документов иначе, чем обычная обработка MVCC на более высоком уровне, на PUT.

Я подробно рассмотрел многие подробности и рекомендую прочитать также оригинальное объяснение.

Ответ 3

Документация для CouchDB v2.0.0 более подробно описывает алгоритм репликации. У них есть диаграммы, примеры промежуточных ответов и примеры ошибок. Они используют язык "ДОЛЖЕН", "ДОЛЖЕН" и т.д. IETF RFC.

Спецификации для 2.0.0 (еще не выпущенные по состоянию на январь 2016 года) немного отличаются от 1.x, но основы все еще описаны в @natevw.