Как и большинство NoSQL-решений, C* подвержен одной крайне неприятной эпидемии: это отличный инструмент для узкого класса задач, но позиционируется евангелистами как очередная серебряная пуля для хранения данных.
В этой статье я расскажу о своем опыте внедрения C* в (относительно) загруженный проект веб-аналитики.
Оно будет полезно всем, кто сталкивается с выбором масштабируемого хранилища данных, и развенчает мифы и заблуждения об этом инструменте.
Начнем с положительных сторон.
Как я уже говорил ранее, C* со своими основными задачами справляется на ура.
Он создан для быстрой записи, масштабируемости и отказоустойчивости, и в этом он, пожалуй, лучший: более простого управления кластером я еще не видел, и за все это время он меня ни разу не подвел.
Однако самая большая проблема с C* заключается в том, что его область применения намного уже, чем можно предположить в документации.
А потом я по пунктам расскажу почему.
CQL — это не SQL
Честно говоря, я даже не понимаю, почему разработчики C* решили создать CQL. Это сбивает с толку и дезориентирует, создавая ложное впечатление об особенностях работы C*.Вот несколько фактов для вас:
- Основное заблуждение, в которое CQL вводит всех новичков, — это иллюзия, что вы сможете делать какие-то выборки.
Это не верно.
C* — это хранилище значений ключа.
Вы не сможете получить подмножество строк в таблице.
Либо один (по ключу), либо все.
Чтобы обойти это ограничение, в C* есть «широкие строки» — возможность записи любых столбцов подряд (независимость от схемы, до 2 миллиардов уникальных столбцов подряд).
Но это спасает только при особом подходе к планированию модели данных.
- CQL вводит понятия ключа раздела и ключа кластера в рамках PRIMARY KEY. Еще одно серьезное заблуждение о том, как работает эта база данных.
Фактически, строка в C* определяется только через часть раздела.
Все «записи», отличающиеся кластерным ключом, будут просто сложены друг за другом внутри одной строки.
- Составного ключа раздела нет. Самый простой способ понять поведение составного ключа — представить, что значения полей ключа перед сохранением объединяются.
А строку можно получить только по полному значению ключа (как в redis, например).
- INSERT и UPDATE в C* — это одно и то же.
Отныне и во веки веков.
- Коллекции в CQL — это просто синтаксический сахар, а записи в них хранятся в отдельных столбцах.
- Вторичные индексы — это тоже просто синтаксический сахар.
C* создает новое семейство ключей (таблицу) для каждого вторичного индекса и дублирует записи там.
Особенности дизайна данных
Основным принципом проектирования данных на C* является «модель, управляемая SELECT».Вы проектируете данные так, чтобы позже их можно было получить с помощью SELECT. В контексте хранилища с широкими строками «ключ-значение» это подразумевает очень сильную денормализацию.
Вы не просто денормализуете данные, как это было раньше в реляционных базах данных, вы фактически создаете отдельную таблицу для каждого запроса .
А во многих проектах (где данных в объёме много) это даёт либо огромные накладные расходы при отображении/сокращении и агрегации, либо огромные накладные расходы по объёму хранимых данных.
И да, сразу стоит быть готовым к тому, что без распределенной агрегации (Hadoop, Spark, Hive и т. д.) эта база данных бесполезна.
Разработчики обещают в следующей версии операторы для агрегации данных в CQL, но слишком на них полагаться не стоит. Исходя из архитектуры этой базы данных понятно, что они будут работать только в пределах одной строки.
Счетчики
Я отвожу этому типу данных в этой базе отдельный раздел, и вот почему: изначально, когда я начал внедрять C* в свой проект, я был очень рад: для веб-аналитики очень круто иметь атомарные счетчики, они сильно упрощают систему .Но потом я понял простую истину: никогда, слышишь? НИКОГДА не используйте счетчики в C* (по крайней мере, в версиях до 2.1.* включительно).
Дело в том, что данный тип данных противоречит всей идеологии этой базы данных, и из-за этого у нее огромное количество проблем.
Если любого С*-специалиста спросить о счетчиках, он только злобно посмеется в ответ. Кратко говоря:
- В строке со счетчиками нельзя помещать какие-либо другие значения, кроме счетчиков
- Вы не можете помещать счетчики в коллекции (по причине, указанной выше)
- Сделать счетчик ключей кластера и раздела нельзя (по причине выше), сортировать по ним и ставить по ним вторичные индексы, конечно, тоже
- Вы не можете установить счетчик времени жизни
- У счетчиков возникают проблемы с репликацией (редко, но точно)
- Если вы удалите счетчик, вы долгое время не сможете его создать снова.
повторное применение операции не меняет результат).
Именно это обеспечивает отказоустойчивую архитектуру в случае выхода из строя узлов, центров обработки данных, проблем со связью и т. д. Счетчики нарушают этот принцип и производятся внутри компании посредством «легких транзакций» — сначала подсчитывают значение, затем увеличивают его.
И это вызывает массу проблем.
В общем, если вам нужны счетчики, лучше использовать слой Redis и добавлять окончательное значение на C*.
Это все на данный момент. Выбирайте инструменты с умом.
Если что-то кажется слишком хорошим, чтобы быть правдой, возможно, так оно и есть.
Теги: #cassandra #apache cassandra #NoSQL #модные слова #NoSQL #Большие данные
-
22 Года На Орбите
19 Oct, 24 -
Вышла Бета-Версия Resharper 6
19 Oct, 24 -
Оптимизация Затрат На Sms
19 Oct, 24 -
Еженедельный Подкаст №68
19 Oct, 24