Две базовые особенности Apache Cassandra

В статье пойдет речь о двух базовых вещах, которые, как ни странно, многие разработчики упускают из виду при написании клиентского кода, особенно когда работают с CQL:

  1. Cassandra — это хранилище типа ключ-значение.
  2. Cassandra — это распределенное децентрализованное хранилище.

Хранилище ключ-значение (key-value)

Очень важно понимать, что вы, по сути, работаете с Map (в терминах java), и чтобы получить данные из базы, вам нужен ключ.
При работе с CQL это может быть не так очевидно, по скольку CQL скрывает особенности реализации хранилища в угоду простоте использования и схожести с SQL, который в свою очередь позволяет делать выборки по любым полям. При проектировании модели данных всегда нужно держать в уме те варианты запросов, которые будут нужны для получения данных, и строить модель данных исходя из запросов на выборку.
Для Кассандры обычное дело денормализация данных и дополнительные таблицы (по сути индексы) обеспечивающие быстрый поиск по основной таблице.

Для данных с нетривиальной структурой такой подход усложняет процесс проектирования, саму модель данных и, соответственно, код который с ней работает, потому как многие вещи вам нужно реализовывать вручную. Однако, в большинстве случаев автоматические вторичные (secondary) индексы способны помочь без особых накладных расходов. Достаточно один раз создать такой индекс и Кассандра сама будет поддерживать его актуальность. Но у вторичных индексов есть свои ограничения. В будущих статьях я подробнее остановлюсь на индексах.

Распределенное децентрализованное (distributed) хранилище

Это второй пункт, который нужно всегда держать в уме при работе с Cassandra, иначе есть риск обрести головную боль в виде проблем с несогласованностью данных и производительностью системы.

Проблема с несогласованностью (inconsistency) может проявляться как «мигание» результатов возвращаемых запросом SELECT. Т.е. последовательный вызов запроса возвращает разные результаты. Чаще такая проблема воспроизводится при активной записи в базу.
Причина подобного поведения заключается в распределенной природе Cassandra, когда одни и те же данные должны лежать на нескольких узлах (node) кассандры, однако не на всех узлах они находятся в одинаковом согласованном состоянии к моменту выполнения запроса SELECT. Для такого поведения даже существует специальный термин — Eventually consistent или Согласованность в конечном итоге, означающий, что данные в какой то момент времени могут быть не согласованы, но станут таковыми в обозримом будущем.

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

Однако Кассандра позволяет очень гибко настраивать уровень согласованности данных (consistency level). При проектировании клиентского кода и запросов рекомендую уделять внимание этому вопросу и выбирать уровень согласованности исходя из того, насколько это необходимо и не забывать про теорему CAP.

Второй аспект это производительности. Производительность во многом определяется правильным дизайном данных и нужно учитывать не только особенности хранения как «ключ-значение» но и то, что данные (в соответствии с ключами) распределяются по различным узлам базы и стараться избегать запросов, которым нужно запрашивать большое количество узлов. Идеально, когда данные для запроса могут быть получены из одного узла.
Соответственно, неправильное использование таких операторов как ALLOW FILTERING и IN может пагубно сказаться на производительности. Подробнее об этих операторах расскажу в следующих статьях.

Итак, имея дело с Cassandra и CQL нужно не забывать чем является эта система и что лежит под капотом у CQL, чтоб правильно использовать ее преимущества и избежать многих проблем. В большинстве случаев в арсенале Кассандры есть средства для решения многих проблем, но не всегда эти средства очевидны, если не принимать во внимание то, что Кассандра это распределенное децентрализованное  key-value хранилище.

Ниже список полезных статей откуда можно почерпнуть дополнительные знания по теме:


Комментарии: