Насколько я понял из этого ответа, если кворум записи не достигнут, Кассандра не откатывает записи из базы данных, в которой запись сохранялась.
Какой смысл вообще иметь кворум записи? Чем это отличается от записи с максимальными усилиями или отправки записи на все узлы и ожидания только одного успеха?
Смысл использования QUORUM
для записи состоит в том, чтобы в случае успеха записи гарантировать, что последующие чтения с QUORUM
будут последовательными.
Это правда, что записи не откатываются, и в Cassandra есть механизмы, которые в конечном итоге распространяют записи на все реплики - подсказки, исправления, исправления чтения. Однако ни один из этих механизмов не дает гарантии, что результат запроса на чтение с использованием QUORUM
вернет последнюю версию данных.
С другой стороны, если запись с помощью QUORUM
успешна, то чтение с помощью QUORUM
для одних и тех же данных всегда будет согласованным, поскольку по крайней мере 1 реплика, участвующая в запросе на чтение, хотя также участвует в последней записи QUORUM
, возвращает до- данные даты. Даже в сценарии, когда только одна реплика, участвующая в чтении QUORUM
, является согласованной, Cassandra устранит несоответствия с помощью блокирующего восстановления чтения, прежде чем возвращать результаты.
Если вы используете согласованность записи ниже, чем QUORUM
, даже если вы используете QUORUM
для чтения, нет никакой гарантии, что запрос на чтение будет прочитан из реплик, которые успешно выполнили оператор записи.
Если альтернативно вы пишете с уровнем согласованности ALL
, то вы теряете высокую доступность в Cassandra — все, что нужно для простоя, — это один недоступный узел.
Формула, гарантирующая согласованность данных при чтении:
read_consistency_level + write_consistency_level > replication_factor
И обычно LOCAL_QUORUM
для уровней согласованности чтения и записи является оптимальной точкой доступности и согласованности данных.
Надеюсь, это поможет.
Хотя путь мутаций одинаков на уровне базы данных для любого уровня согласованности записи, детали для успешной записи на уровне приложения лежат в зависимостях. Предполагая, что в конечном итоге приложение считывает QUORUM
любые данные, если соответствующие мутации были отправлены с меньшим количеством QUORUM
, набор результатов может быть противоречивым при чтении. Если запись была отправлена с QUORUM
, драйверы и приложение могут использовать повторные попытки, чтобы обеспечить надежную согласованность данных для QUORUM
чтения, и набор результатов не может быть противоречивым.
В вашем понимании есть фундаментальная ошибка. Важным моментом репликации данных в Cassandra является то, что записи отправляются во ВСЕ реплики в кластере.
Например, если пространство ключей имеет 3 реплики в 2 контроллерах домена, мутации в запросе на запись отправляются во ВСЕ 6 реплик (3 реплики x 2 контроллера домена). Чтобы запрос на запись с согласованностью QUORUM
считался успешным, по крайней мере 4 (из 6) реплик должны подтвердить запись в течение тайм-аута запроса на запись.
ЕСЛИ недостаточно реплик подтверждают запись, координатор ответит клиенту/драйверу ошибкой UNAVAILABLE
. Теперь вот недостающая часть: используемый вами драйвер должен принять решение о том, что делать дальше, в зависимости от того, как вы его настроили.
Для целей данного обсуждения я буду использовать Java-драйвер Cassandra, поскольку он является самым популярным. При сбое запроса драйвер Java иногда повторяет запрос в соответствии с настроенной политикой повтора. Поведение по умолчанию (DefaultRetryPolicy
) в случае ошибки записи UNAVAILABLE
(недостаточное количество реплик, подтвердивших запись) заключается в повторении запроса на следующем узле в плане запроса. Если повторная попытка не удалась, то вы, как разработчик, должны решить, как ваше приложение справится с ошибкой, например. выдайте соответствующий DELETE
, если откат требуется бизнес-правилами вашего приложения.
Суть в том, что уровень согласованности важен, поскольку он определяет, будет ли запрос на запись успешным или нет. Без него ваше приложение не сможет увидеть состояние запроса, и было бы невозможно определить, что делать дальше.
Если вы хотите узнать больше о том, как драйвер Java Cassandra обрабатывает сбои, см. страницу Повторы в документации. Ваше здоровье!
Вы не могли бы объяснить лучше. Это именно тот кусочек, которого мне не хватало. Спасибо!
Спасибо за ответ. Я рад, что мне это удалось. Ваше здоровье!
Я определенно что-то упускаю. Я до сих пор не понимаю причину кворума записи, когда Cassandra не обрабатывает запросы на запись, которые не достигают кворума, по-другому. В таком случае я просто не понимаю смысла называть это Кворумом записи. Это то же самое, что распределять запросы на запись по всем репликам и требовать подтверждения только от одной из реплик. Я просто хочу понять, что обрабатывается по-другому, когда кворум не достигается.