Spec-Zone.ru › RethinkDB ruby

Гарантии согласованности

  • Настройки
  • Гарантии линейной и атомарной согласованности
  • Гарантии доступности
  • Баланс безопасности и производительности
  • Примечания

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

Настройки

  • Подтверждения записей устанавливаются на уровне таблицы с помощью настройки write_acks, либо с помощью команды config, либо записью в table_config системную таблицу. По умолчанию значение majority, что означает, что записи будут подтверждены, когда большинство (голосовых) реплик подтвердят их запись. Другой возможный вариант - single, что означает, что записи будут подтверждены, когда подтвердит одна реплика.
  • Долговечность устанавливается на уровне таблицы с помощью настройки durability, снова используя либо reconfigure, либо записью в table_config системную таблицу. В режиме долговечности hard, записи записываются на диск до отправки подтверждения; в режиме soft записи подтверждаются немедленно после хранения в памяти. Режим soft быстрее, но немного менее устойчив к сбоям. По умолчанию hard.
  • Режим чтения устанавливается для каждого запроса с помощью необязательного аргумента, read_mode (или readMode), к таблице. У него есть три возможных значения:
    • single возвращает значения, которые находятся в памяти (но необязательно записаны на диск) на первичной реплике. Это значение по умолчанию.
    • majority возвращает только значения, которые безопасно сохранены на диске на большинстве реплик. Это требует отправки сообщения каждой реплике при каждом чтении, поэтому это самый медленный, но наиболее согласованный режим.
    • outdated возвращает значения, которые находятся в памяти на произвольно выбранной реплике. Это самый быстрый, но наименее согласованный режим.

Обратите внимание, что изменения игнорируют флаг read_mode и всегда ведут себя так, как если бы он был установлен на single.

Линейная и атомарная гарантии согласованности

При следующих настройках RethinkDB гарантирует линейность отдельных атомарных операций с отдельными документами:

  • write_acks: majority
  • durability: hard
  • read_mode: majority

Это означает, что каждое чтение будет видеть все предыдущие успешные записи, и ни одно чтение никогда не увидит определённо проваленную запись. (См. примечание о определённо проваленных и неопределённых записях ниже.)

Гарантия линейности относится к атомарным операциям, а не к запросам. Один запрос RethinkDB не обязательно выполняется как одна атомарная операция. Возможно, что запрос:

r.table("foo").get("bar").eq(r.table("foo").get("bar")).run(conn, callback);

может вернуть false! Каждая отдельная операция get атомарна, но сам запрос — нет. Чтобы прочитать и изменить документ в одной атомарной операции, используйте команды update или replace.

r.table("foo").get(id).update({hits: r.row("hits") + 1}).run(conn, callback);

Это также может быть использовано для реализации регистрового устройства проверки и установки. Следующий запрос атомарно проверит, равно ли поле check значению old_value, и изменит его на new_value, если это так:

r.table("foo").get(register_id).update({
    check: r.branch(r.row("check").eq(old_value), new_value, r.row("check"))
}).run(conn, callback);

Операции RethinkDB никогда не являются атомарными по нескольким ключам. По этой причине RethinkDB не может считаться базой данных ACID.

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

r.table("foo").filter({
    id: register_id, foo: old_val
}).update({foo: new_val}).run(conn, callback);

table.filter({id: register_id, foo: old_val}).update({foo: new_val})

Это поведение может измениться в будущем. См. Github issue #3992 для отслеживания обсуждения.

Гарантии доступности

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

Переконфигурация таблицы (изменение количества фрагментов, балансировка и т. д.) вызывает кратковременную потерю доступности в различные моменты во время переконфигурации.

Если первичная реплика потеряна, но более половины голосующих реплик по-прежнему доступны, произвольная голосующая реплика будет избрана в качестве первичной. Новая первичная реплика будет появляться в table_status, но поле primary_replica из table_config не изменится. Если старая первичная реплика снова станет доступной, система вернётся к ней. При изменении первичной реплики будет небольшой период недоступности.

Если половина или больше голосующих реплик фрагмента потеряны, единственный способ восстановить доступность — запустить reconfigure с параметром emergency_repair. Обратитесь к документации по reconfigure для получения дополнительной информации.

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

Голосующие и не голосующие? По умолчанию все реплики являются «голосовыми» репликами, что просто означает, что они учитываются в любой операции, для которой требуется большинство доступных реплик. Однако скорость, с которой реплики «голосуют», зависит от задержки сети; если у вас есть удалённый дата-центр с большей задержкой, вы можете установить его реплики в не голосующие, чтобы улучшить производительность, но с потерей гарантированной доступности в этом дата-центре. Вы можете установить реплику как «не голосующую», изменив ее конфигурацию таблицы с помощью reconfigure.

Баланс безопасности и производительности

По умолчанию RethinkDB отдаёт предпочтение безопасности над производительностью, за исключением одного случая: read_mode по умолчанию single вместо majority. Режим чтения majority требует отправки запроса всем репликам и ожидания ответа большинства, что значительно снижает производительность.

В обычном режиме чтения single производит те же результаты, что и majority, но может возвращать устаревшие результаты в случае сбоя сети или сбоя. Также возможно, что чтение в режиме single может вернуть результаты неполной записи, которая позже будет отменена.

То же самое относится к режиму записи single и режиму долговечности soft. В обычном режиме они дают те же результаты, что и majority и hard, но в случае сбоя сети или сервера недавние операции записи, выполненные в этих режимах, могут быть потеряны.

Обратите внимание, что write_acks и durability фактически не влияют на то, как выполняется запись; они только влияют на то, когда подтверждение возвращается клиенту.

Чтения в режиме "outdated" вернут устаревшие данные даже при нормальной работе, но данные обычно будут устаревшими менее чем на секунду. В случае сбоя сети или сервера данные могут быть гораздо более устаревшими. Преимущество запуска чтений в режиме "outdated" заключается в том, что задержка и пропускная способность часто лучше, чем в режиме "single", помимо различий в доступности, описанных в предыдущем разделе.

Примечания

Использование параметра emergency_repair для таблицы аннулирует все гарантии.

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

Автоматическое переключение RethinkDB имеет ограничения в случаях непереходных сбоев подключений, то есть сервер А может связаться с Б, Б может связаться с С, но А не может связаться с С. Подробности см. в документации по переключению.

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/consistency/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API