Редкие базы данных: Cassandra

Как Riak, но немного круче.
18 августа 2016225057Андрей Никифоров208329

Здравствуйте!

В первой статье о редких базах данных мы говорили о Riak. Сегодня речь пойдет о похожей, но более распространенной базе данных Cassandra. Она похожа на Riak, но более гибкая. Написана на Java, первая версия вышла в 2008 году.

См. также: Редкие базы данных: Riak

Хранение

Cassandra хранит данные не в простом формате ключ-значение, а в многоуровневой хеш-таблице. Каждое значение, записанное в БД, принадлежит к колонке, ключу, колоночному семейству и пространству ключей. Это немного похоже на реляционные БД.

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

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

Согласованность

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

Для каждого конкретного запроса на чтение или запись можно задать свой уровень согласованности данных. Вот они:

  • ONE — координатор шлёт запросы всем узлам-реплик, но, дождавшись подтверждения от первого же узла, возвращает управление пользователю.
  • TWO — то же самое, но координатор дожидается подтверждения от двух первых узлов, прежде чем вернуть управление.
  • THREE — аналогично, но координатор ждет подтверждения от трех первых узлов, прежде чем вернуть управление.
  • QUORUM — собирается кворум: координатор дожидается подтверждения записи от более чем половины узлов-реплик + еще одного узла.
  • LOCAL_QUORUM — координатор дожидается подтверждения от более чем половины узлов-реплик в том же центре обработки данных, где расположен координатор (для каждого запроса потенциально свой). Позволяет избавиться от задержек, связанных с пересылкой данных в другие центры обработки данных.
  • EACH_QUORUM — кооринатор дожидается подтверждения от более чем половины узлов-реплик в каждом центре обработки данных независимо.
  • ALL — координатор дожидается подтверждения от всех узлов-реплик.
  • ANY — даёт возможность записать данные, даже если все узлы-реплики не отвечают. Координатор дожидается или первого ответа от одного из узлов-реплик, или когда данные сохранятся при помощи направленной отправки на координаторе. Только для запросов на запись.

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

Восстановление данных

Три механизма внутреннего восстановления данных.

Чтение с восстановлением
Во время чтения данных значения с разных реплик сравниваются, и значение с максимальной меткой времени распространяется на остальные узлы.

Направленная отправка
Если во время записи один из узлов был недоступен, копия данных сохраняется на координаторе и отправляется позже. При уровне согласованности ANY можно записать данные, даже если все узлы были недоступны — данные сохраняются на координаторе и рассылаются по узлам потом.

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

Запись на диск

Когда клиент отправляет запрос на запись, данные не попадают на диск сразу. Сперва они пишутся в таблицу в оперативной памяти, и в commit-лог. В памяти данные хранятся примерно так же, как и на диске, а вот commit-лог похож на последовательность запросов.

Commit-лог используется для восстановления таблиц при аварийном завершении процесса Cassandra. В штатном режиме данные на диск пишутся из таблицы в памяти.

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

Транзакционность

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

  • атомарность — все колонки в одной записи за одну операцию будут или записаны, или нет;
  • согласованность — запросы с строгой согласованностью взамен доступности;
  • изолированность — начиная с версии 1.1, появилась поддержка изолированности, когда во время записи колонок одной записи другой пользователь, который читает эту же запись, увидит или полностью старую версию записи или, уже после окончания операции, новую версию, а не часть колонок из одной и часть из второй;
  • долговечность обеспечивается наличием журнала закрепления, который будет воспроизведён и восстановит узел до нужного состояния в случае какого-либо отказа.

См. также: Транзакции, ACID, CAP

Cassandra — мощный инструмент хранения данных, который используют крупные компании вроде Cisco, IBM, Cloudkick, Reddit, Digg, Rackspace и Twitter. Крупнейший кластер серверов содержит 400 машин и хранит 300Тб данных. Насколько Cassandra мощная, настолько и избыточная для небольших и средних проектов, как и Riak.

 

Новые комментарии