Мой Опыт Внедрения Apache Cassandra

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

В этой статье я расскажу о своем опыте внедрения C* в (относительно) загруженный проект веб-аналитики.

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



Мой опыт внедрения Apache Cassandra

Начнем с положительных сторон.

Как я уже говорил ранее, C* со своими основными задачами справляется на ура.

Он создан для быстрой записи, масштабируемости и отказоустойчивости, и в этом он, пожалуй, лучший: более простого управления кластером я еще не видел, и за все это время он меня ни разу не подвел.

Однако самая большая проблема с C* заключается в том, что его область применения намного уже, чем можно предположить в документации.

А потом я по пунктам расскажу почему.



CQL — это не SQL

Честно говоря, я даже не понимаю, почему разработчики C* решили создать CQL. Это сбивает с толку и дезориентирует, создавая ложное впечатление об особенностях работы C*.

Вот несколько фактов для вас:

  1. Основное заблуждение, в которое CQL вводит всех новичков, — это иллюзия, что вы сможете делать какие-то выборки.

    Это не верно.

    C* — это хранилище значений ключа.

    Вы не сможете получить подмножество строк в таблице.

    Либо один (по ключу), либо все.

    Чтобы обойти это ограничение, в C* есть «широкие строки» — возможность записи любых столбцов подряд (независимость от схемы, до 2 миллиардов уникальных столбцов подряд).

    Но это спасает только при особом подходе к планированию модели данных.

  2. CQL вводит понятия ключа раздела и ключа кластера в рамках PRIMARY KEY. Еще одно серьезное заблуждение о том, как работает эта база данных.

    Фактически, строка в C* определяется только через часть раздела.

    Все «записи», отличающиеся кластерным ключом, будут просто сложены друг за другом внутри одной строки.

  3. Составного ключа раздела нет. Самый простой способ понять поведение составного ключа — представить, что значения полей ключа перед сохранением объединяются.

    А строку можно получить только по полному значению ключа (как в redis, например).

  4. INSERT и UPDATE в C* — это одно и то же.

    Отныне и во веки веков.

  5. Коллекции в CQL — это просто синтаксический сахар, а записи в них хранятся в отдельных столбцах.

  6. Вторичные индексы — это тоже просто синтаксический сахар.

    C* создает новое семейство ключей (таблицу) для каждого вторичного индекса и дублирует записи там.

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



Особенности дизайна данных

Основным принципом проектирования данных на C* является «модель, управляемая SELECT».

Вы проектируете данные так, чтобы позже их можно было получить с помощью SELECT. В контексте хранилища с широкими строками «ключ-значение» это подразумевает очень сильную денормализацию.

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

А во многих проектах (где данных в объёме много) это даёт либо огромные накладные расходы при отображении/сокращении и агрегации, либо огромные накладные расходы по объёму хранимых данных.

И да, сразу стоит быть готовым к тому, что без распределенной агрегации (Hadoop, Spark, Hive и т. д.) эта база данных бесполезна.

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



Счетчики

Я отвожу этому типу данных в этой базе отдельный раздел, и вот почему: изначально, когда я начал внедрять C* в свой проект, я был очень рад: для веб-аналитики очень круто иметь атомарные счетчики, они сильно упрощают систему .

Но потом я понял простую истину: никогда, слышишь? НИКОГДА не используйте счетчики в C* (по крайней мере, в версиях до 2.1.* включительно).

Дело в том, что данный тип данных противоречит всей идеологии этой базы данных, и из-за этого у нее огромное количество проблем.

Если любого С*-специалиста спросить о счетчиках, он только злобно посмеется в ответ. Кратко говоря:

  1. В строке со счетчиками нельзя помещать какие-либо другие значения, кроме счетчиков
  2. Вы не можете помещать счетчики в коллекции (по причине, указанной выше)
  3. Сделать счетчик ключей кластера и раздела нельзя (по причине выше), сортировать по ним и ставить по ним вторичные индексы, конечно, тоже
  4. Вы не можете установить счетчик времени жизни
  5. У счетчиков возникают проблемы с репликацией (редко, но точно)
  6. Если вы удалите счетчик, вы долгое время не сможете его создать снова.

Суть несоответствия идеологии счетчиков и самой базы данных состоит в том, что все операции в C* идемпотентны (т. е.

повторное применение операции не меняет результат).

Именно это обеспечивает отказоустойчивую архитектуру в случае выхода из строя узлов, центров обработки данных, проблем со связью и т. д. Счетчики нарушают этот принцип и производятся внутри компании посредством «легких транзакций» — сначала подсчитывают значение, затем увеличивают его.

И это вызывает массу проблем.

В общем, если вам нужны счетчики, лучше использовать слой Redis и добавлять окончательное значение на C*.

Это все на данный момент. Выбирайте инструменты с умом.

Если что-то кажется слишком хорошим, чтобы быть правдой, возможно, так оно и есть.

Теги: #cassandra #apache cassandra #NoSQL #модные слова #NoSQL #Большие данные

Вместе с данным постом часто просматривают: