Две базовые особенности Apache Cassandra
В статье пойдет речь о двух базовых вещах, которые, как ни странно, многие разработчики упускают из виду при написании клиентского кода, особенно когда работают с CQL:
- Cassandra - это хранилище типа ключ-значение.
- 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 хранилище.
Ниже список полезных статей откуда можно почерпнуть дополнительные знания по теме:
- Как устроена apache cassandra отличная статья о том, как Cassandra хранит данные, как распределяет данные по узлам, пара слов о согласованности.
- Моделирование данных в Cassandra 2.0 на CQL3 одна из моих любимых статей на тему правильного моделирования данных.
- SELECT…WHERE запросы в Cassandra 2.0 на CQL3 отличная статья о том как правильно использовать ключи в запросах
- ALLOW FILTERING explained статья на английском о том когда стоит а когда нет использовать ALLOW FILTERING
- Indexing официальная документация по индексам, об их ограничениях и о том как эффективно их использовать
- Configuring data consistency официальная документация на английском о настройке уровня согласованности
- Теорема CAP полезно знать перед тем как выбирать уровень согласованности
- Официальная документация для CQL3