7 декабря 2013 в 15:52

SELECT...WHERE запросы в Cassandra 2.0 на CQL3 tutorial

Cassandra (далее C*) ограничивает WHERE запросы из-за своей внутренней структуры. Эта статья вам покажется сложной, запутанной, если вы не читали первую статью из цикла, где я рассказывал как устроена С*. Прочтите её, пожалуйста, прежде чем приступать к этой.

Цель этой статьи — выступать справочником для C* новичков.

Некоторые отличия CQL от SQL


В SELECT запросах Cassandra Query Language (CQL) отсутсвутют привычные нам SQL операции JOIN, GROUP BY. А операция WHERE сильно урезана. В SQL вы можете фильтровать по любой колонке, тогда как в CQL только по распределительным ключам (partition key), кластерным ключам (clustering columns) и вторичным индексам.
Заметка: В С* 2.0 можно создавать вторичные INDEX-ы у любой колонки наподобие SQL индексов. Фактически же, вторичные индексы Кассандры — это скрытая от вас дополнительная таблица, поэтому производительность WHERE запросов по ним хуже запросов по ключевым колонкам.


Disclaimer


  • CQL видоизменяется от релиза к релизу. Данная статья отображает состояние версии 3. Писалась когда последняя версия была 3.1.2.
  • Все примеры производятся над таблицей ad_click, созданной в предыдщуей, второй по счету, статье. Также там объяснена терминология используемая в этой статье. Тоже рекомендую хотя бы взглянуть.
CREATE TABLE ad_click (
  reseller_id text,
  day text, -- day in the format of 'YYYY-MM-DD'
  time timestamp,
  ad_id text,
  amount float,
  PRIMARY KEY ((reseller_id, day), time, ad_id) -- распределительный ключ (reseller_id,day) и кластерные ключи (time,ad_id)
)
WITH CLUSTERING ORDER BY (time DESC);


Фильтрация данных используя WHERE


Грубо говоря слово «фильтрация» тут неуместно. Правильнее сказать поиск. C* почти не даёт возможности фильтровать.

Каждый WHERE запрос говорит Кассандре найти ноду, в которой хранится строка и передать туда запрос.

Сравнение колонок друг с другом

Так как JOIN-ов нет, то и сравнивать колонки друг с другом нельзя.
SELECT * from ad_click WHERE 
maxTimeuuid(day) = maxTimeuuid(3141592653589); -- ОШИБКА;


AND, OR

Множественные условия WHERE запросов нельзя объединять оператором OR, работают только AND. И всего несколько операторов сравнения работает, да и то не всегда.

Равенство =

Использование операторов равенства (=) почти не ограничено. Оно ограничено колонками-ключами и колонками-индексами. А также нужно обязательно сравнить все предыдущие колонки-ключи, прежде чем сравнить следующий.

Правильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND -- OK
day = '2013-11-29' AND -- OK
time = 3141592653589 AND -- OK
ad_id = '890_567_234'; -- OK

Неправильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND 
day = '2013-11-29' AND 
amount = 0; -- ОШИБКА! Это не ключевая колонка.

SELECT * FROM ad_click WHERE 
day = '2013-11-29' AND -- ОШИБКА! Забыли сравнить колонку reseller_id.
time = 3141592653589 AND 
ad_id = '890_567_234';

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND 
day = '2013-11-29' AND 
ad_id = '890_567_234'; -- ОШИБКА! Забыли сравнить колонку time.


Включение IN

Использование оператора включения (IN) ограничено последней колонкой в распрделительном ключе и последней колонкой в кластерном ключе.

Правильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND 
day IN ('2013-11-28', '2013-11-29') AND -- OK
time = 3141592653589 AND 
ad_id IN ('890_567_234', '890_567_010'); -- OK

Неправильно:
SELECT * FROM ad_click WHERE 
reseller_id IN ('supaboobs') AND -- ОШИБКА! Это не последняя колонка распределительного ключа.
day = '2013-11-28' AND 
time = 3141592653589 AND
ad_id = '890_567_234';

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-28' AND 
time IN (3141592653589) AND  -- ОШИБКА! Это не последняя колонка кластерного ключа.
ad_id = ('890_567_234');


Оперторы сравнения = > >= < <=


Синтаксис сравнений

Имя колонки должно быть слева от оператора сравнения, значение — справа.
Правильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND -- OK
day = '2013-11-29'; -- OK

Неправильно:
SELECT * FROM ad_click WHERE 
'supaboobs' = reseller_id AND  -- ОШИБКА! Нарушен порядок оператора сравнения.
'2013-11-29' = day AND -- ОШИБКА! Нарушен порядок оператора сравнения.
3141592653589 < time;  -- ОШИБКА! Нарушен порядок оператора сравнения.


Возможности сравнений

Их можно использовать в последней колонке вашего CQL запроса, причём колонка должна быть исключительно кластерной.

Правильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time >= 3141592653589; -- OK

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time = 3141592653589 AND
ad_id > '890_567_234'; -- OK

Неправильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time >= 3141592653589 AND  -- ОШИБКА! Это не последняя колонка запроса.
ad_id = '890_567_234';

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time >= 3141592653589 AND
ad_id < '890_567_234';  -- ОШИБКА! Предыдущий не фильтровался операцией равенство.

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
ad_id < '890_567_234';  -- ОШИБКА! Пропущена фильтрация по колонке time.

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day < '2013-11-29'; -- ОШИБКА! Это не кластерная колонка.


Обходной манёвр — ALLOW FILTERING

Можно не указывать распределительный ключ, а оставить только кластерный, поставив в конец запроса ALLOW FILTERING. Все остальные ограничения сохраняются.
ВАЖНО! Timeout в этом случае очень вероятен, потому что вы пробегаемся по всем нодам, по всем строкам.


Правильно:
SELECT * FROM ad_click WHERE 
time = 3141592653589 AND -- OK
ad_id > '890_567_234' -- OK
ALLOW FILTERING;

SELECT * FROM ad_click WHERE 
time >= 3141592653589 AND -- OK
time <= 3141592653589 -- OK
ALLOW FILTERING;

Неправильно:
SELECT * FROM ad_click WHERE 
time >= 3141592653589 AND
ad_id > '890_567_234' -- ОШИБКА! Нельзя больше двух сравнений.
ALLOW FILTERING;

SELECT * FROM ad_click WHERE 
time >= 3141592653589 AND
time <= 3241592653589 AND
ad_id = '890_567_234'  -- ОШИБКА! Предыдущий не фильтровался операцией равенство.
ALLOW FILTERING;


Вторичные индексы

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

Чтобы создать вторичный индекс следует выполнить комманду:
CREATE INDEX on ad_click (amount);


Правильно:
SELECT * FROM ad_click WHERE 
amount = 0.0075; -- OK

SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time = 3141592653589 AND
ad_id = '890_567_234' AND
amount = 0.0075; -- OK

Неправильно:
SELECT * FROM ad_click WHERE 
reseller_id = 'supaboobs' AND
day = '2013-11-29' AND
time = 3141592653589 AND
ad_id = '890_567_234' AND
amount > 0.0; -- ОШИБКА! Для вторичных индексов разрешен только оператор равенства.


Заключение


Надеюсь у вас больше не возникнет вопросов «почему мой SELECT не работает?»

Источники




Предыдущая статья цикла.
Василий Боровяк @koresar
карма
28,0
рейтинг 0,0
Похожие публикации
Самое читаемое Разработка

Комментарии (62)

  • +3
    Спасибо большое за серию статей, очень интересно.
    Напишите пожалуйста какие плюсы у Касандры и чем она вам так нравится.
    Насколько я понял, за счёт избыточности хранения данных и заранее указанных индексов, которые она хранит в B-Tree или подобном, она очень быстро записывает и очень быстро читает.
    Расскажите свои общие ощущения.
    • +2
      Она мне нравится скоростью записи. Я сейчас работаю надо проектом, где будет несколько тысяч записей с секунду (показания с датчиков снимать). Эти показания надо будет анализировать на паттерны плохого поведения, а значит и скорость чтения нужна большая.

      Ощущения такие:
      1) Порог входа выше, чем в RDBMS. Возможностей меньше.
      2) Зато не будет проблем с репликацией. Не будет проблем с аптаймом. Сервера не будут перегреваться. :)
      3) Благодаря CQL переход с RDBMS получился более быстрый и гладкий, чем через чертов Thrift. :) Т.е. CQL снизил для меня порог входа.
      4) У С* огромное множество тонких настроек и мелких фичей, которые ещё более ускоряют производительность (но это глубокая тема). Поэтому, мне кажется, что даже если и будут проблемы с производительностью, то от них можно будет избавиться.
      • 0
        Такое ощущение, что возможностей у самой модели не меньше, функционал сервера в последующих версиях наверняка будет развиваться.
        Жаль, пока удобного клиента нет.
  • +2
    У меня только один вопрос — почему Cassandra? Чем она Вас так привлекает?:)
    • +1
      1) Гибкий уровень репликации в особенности, когда у вас несколько датацентров
      2) Multi-master на запись без проблем с администрированием при mysql-multimaster
      3) Очень быстрые вставки. Мы туда валим все логи с серверов в режиме реального времени со скоростью 100Гб/сутки. Смысл конечно не в том, чтобы тупо хранить логи, а в том, что при этом происходит индексирование по hex-последовательностям (например, guid) после чего тут же доступен поиск логов по ним. Удобно искать проблемы связанные с конкретным запросом — видишь сразу же логи всех сервисов, а не лазишь по шарам на куче серверов с grep
      • 0
        Спасибо. У меня примерно тот же ответ. Плюс, гляньте чуть выше мой первый комментарий под статьёй.
        • +1
          Вот у нас опыт с ней не очень:
          1) либо вы платите DataStax за суппорт и настройку, либо получаете огромную головную боль для опсов
          2) не понятно зачем было косить под SQL с их CQL учитывая что они отличаются чуть ли не во всём
          3) форсированный лимит результата в 10.000 записей, для простейшего findAll надо будет писать доп. код итеративного прохода, блокировок и прочего
          4) очень, ОЧЕНЬ требовательна к ресурсам. Мы живем на AWS, где с C* ситуация такая — либо ты берёшь Medium инстансы как самый минимальный вариант (даже для dev окружения), либо… а без вариантов впринципе.
          5) банально нет простого(!) способа получить количество записей в пространстве.
          6) вытекает из 3 — большие запросы часто падают с timeout error, с дефолтными настройками (в том числе от DataStax-a)

          в итоге мы ушли на старую добрую MongoDB, и вы не представляете какое это счастье:)
          • 0
            В целом да, у кассандры довольно ограниченная область применения и без костылей типа атомарных вставок (данные + инкремент счетчика), чтобы получить №5 не обойтись.
            Скажем кассандра хороший выбор, если важна сохранность данных + хороший uptime сервиса + скорость записи, а вовсе не «выжать из железа по-максимуму»
          • 0
            1) Извините, но мне кажется, что у вас банально не хватило человеческих ресурсов, чтобы разобраться с БД по-нормальному.
            2) Снижается порог входа для девелоперов. Для меня было ключевым моментом.
            3) Вы не нашли стримминг. v1: wiki.apache.org/cassandra/Streaming, v2: wiki.apache.org/cassandra/Streaming2
            4) Тут согласен. Если иметь сильную нагруженность (тысячи-миллионы операций в сек.) то нужно хорошее железо и пара десяток нод. Но если у вас до тысячи операций, то нужно было оптимизнуть либо модель, либо настройки самой С*.
            5) Да. Я сейчас этой же проблемой борюсь. Через месяц надеюсь разродиться ещё одной статьёй.
            6) ;)

            Я работал с Монго. Самая простая БД для девелопмента. Если в моём следующем проекте будет невысокая нагруженность, то только Монго и буду использовать.
            • 0
              1) как раз причина отказа от С* — нежелание держать целую команду разработчиков только для тюнинга С*
              2) в итоге различий между CQL и SQL столько, что порог только возрастает — почти все стандартные подходы для SQL не работают для CQL
              3) я то нашёл. А вот например разработчикам JPA решения для С* ( github.com/impetus-opensource/Kundera ) потребовалось на это время, а для нас время — деньги
              4) другие БД в условиях «до тысячи опсеков» справляются на дефолтных настройках:)

              я не пытаюсь спорить или убеждать, лишь рассказываю о нашем опыте:) И хочется чтобы люди, которые читают комментарии, знали эти проблемы и видели, что для использования С* им потребуется большое кол-во человекочасов для того чтобы разобраться с ней и поддерживать дальше. Это имхо среди разработчиков в нашей фирме:)
              • 0
                1) Значит верно поступили.
                2) Порог понижается по сравнению с thrift, но порог явно выше SQL порога.
                3) Ясно. Кстати, Object Mapping с кассандрой слабо вяжется в принципе.
                4) Естественно.

                Кассандра — это не универсальня БД как, например, Монго или RDBMS. Кассандра — узкоспециализированная БД.
                У меня ощущение, что вы там пытались применить С* для проекта с невысокой нагруженностью. Угадал?
                • 0
                  не угадали:) один из проектов — 100 миллионник:) а про «до 1000 запросов» — это чисто с точки зрения универсальности БД:)
                  • 0
                    100 миллионов записей/чтений в секунду?
                    Какая БД? :)
                    • 0
                      нет нет, что вы) аудитория больше 100 миллионов:)
                      • 0
                        Ааа. Тогда вам действительно не так уж нужна С*. Монго — верный вариант.
          • +1
            Очень странный опыт. Прокомментирую:

            1. Если все хотя бы прочтут документацию (которая, между прочим, достаточно неплохая), то глупой головной боли станет меньше гораздо. Знаю кучу примеров, где даже дефолтные настройки работали замечательно для разных сценариев.

            2. Это чисто маркетинговый ход, потому что Thrift реально очень сильно увеличивал порог вхождения и вдобавок открывал «доступ к телу» (деталям хранения данных). Это позволяло профессионалам делать очень быстрые и качественные выборки, а остальным мучиться даже с банальными задачами.

            3. А где это вас форсируют? Вообще, выборка 10K записей одновременно уже является большим антипаттерном и C* тут ни при чем. Представьте себе, что вычитка идет для 100 или 1000 запросов от пользователей и в каждом по 10K записей. Словить OOM (out of memory error) очень и очень просто.

            4. Я бы не сказал, что medium — это очень требовательна к ресурсам. Причем, тут даже больше важны нe RAM и CPU, а скорость дисков. Мы тоже живем на AWS и PIOPS EBS volumes решают проблему более чем полностью.

            5. Опять фантазии какие-то. Точное значение понятное дело получить нельзя, но его и в RDBMS нельзя получить, потому что пока делается запрос еще куча записей может добавиться. А в C* для каждой «таблички» ведется статистика по количеству записей как мета-информация и ее можно легко получить. А если хотите чуть точнее, то заведите отдельную «табличку» со счетчиками и обновляйте ее.

            6. Больших запросов быть не должно в подобном хранилище, это навязывается моделью хранения и доступа к данным.

            Ну и наконец, подошли к MongoDB. :) Тут даже сравнивать бессмысленно, потому что MongoDB работает в режиме single master и выбирает замену при падении основного мастера, а в C* все ноды совершенно независимы и кластер продолжает писать практически с той же скоростью при выпадении любой ноды.
            • 0
              и часто у вас инстансы прод базы падают? ;)
              • +1
                Они у нас распределены по разным availzbility зонам. Это помогает чувствовать себя спокойнее. Было пару раз во время проблем у Амазона что вырубалась сеть на паре нод и EBS волумы отказывали. При этом кластер совершенно спокойно продолжал работать.
      • +1
        Для логов лучше наверное использовать специализированную систему, например связку logstash + elasticsearch + kibana. Там гораздо больше возможностей, да и скорость ничуть не меньше. Зато загрузка логов происходит полностью асинхронно и не завязана на затыки в производительности обработчика логов.
  • 0
    Было бы хорошо если-бы вы описали как сконфигурировать сервер, скока памяти, какие оптимальные параметры, которые существенно могут сказатся на производительности.

    Читал документацию на офф сайте datastax но некоторые вещи понимаются только на практике.

    Спасибо за посты.
    • 0
      Так собственно вот тут рекомендованные настройки
      По памяти прикол в том, что дефолтные настройки самые оптимальные и под Java Heap нет смысла выделять больше 8Гб, т.к. иначе нужно быть мега гуру в настройке сборщика мусора ибо стандартный работает с большим кол-вом памяти плоховато.
      Зато относительно просто настроить несколько кластеров на одном и том же железе и раскидывать keyspace-ы по разным кластерам.
      Кроме того в последних версия всякие структуры типа кэшей умеют храниться вне Java Heap, так что все может быть очень индивидуально.
      • 0
        Я вот из под lxc кручу, но касандра оч любит ядра цп и пожирает их довольно не плохо, если поднимать 2 ноды на тачке с 8 ECPU то на каждого выделять по 4 или же пусть ОС сама решает и отдать всем все ECPU?
        Машинка у меня 32 GB, Core i7 (8 ecpu), 480 gb ssd
        • 0
          Там скорее нужно смотреть на параметры кассандры касательно кол-ва потоков под всякие нужды типа compaction.
          Если у вас 8 CPU, и слабый диск, то 8 параллельных потоков ждущих диска не будут работать хорошо.
          • 0
            У него SSD. :) Диск не будет проблемой.
          • 0
            Диски у меня вообще в релакс режиме, такое ощущение :) а вот LA вырастает будь здоров, к примеру на данной тачке по 140-180 при этом загрузка каждого ecpu под 90-100%.
            Я к тому что в диск дело не уперлось, вот как с ecpu быть лучше?
            • 0
              Эксперимент «что лучше — два кластера по 2 cpu или один с 4» не проводил, но чисто из общих соображений колдовать с 2-мя кластерами из-за cpu смысла не вижу. Там почти все критические операции регулируются кол-вом потоков в пересчете на кол-во cpu, так что все доступные ядра могут будут сожраны, это да :)
              Опять же все зависит от сценария использования. При правильных настройках и схеме данных GC включается не так часто.
              • 0
                Подтверждаю.
                Более того, на некоторых видео от Datastax упоминяют, что реальный выигрышь от использования С* начинается с шести нод.
                • 0
                  Это все-же хорошо, но вопрос как лучше разделить ECPU? У меня сейчас 2 физ тачки описанные выше, памяти хватает на 6 нод, если им отдать по 8 ГБ как в доках, но вот как в LXC разделить ECPU :)

                  Конечно буду пробовать различные варианты, но все-же мало-ли кто тут пробовал уже и знает как лучше ))
                  • 0
                    Извините, не отвечу. Найдёте ответ — дайте знать. :)
  • 0
    За статью спасибо, скоро всем придется писать код для кассандры под CQL, т.к. новые клиентские библиотеки мода делать только на CQL.
    Только вот накой разработчикам cassandra так дался этот CQL?
    Сделать язык запросов похожий на SQL, чтобы снизить порог вхождения для разработчиков? Так это сомнительная идея.
    Если не знать как устроена кассандра — легко написать такой запрос, что он будет тупо все данные лопатить.
    Кроме того как можно заметить из статьи — там сплошные ограничения на синтаксис, который еще и меняется от версии к версии.
    Старый добрый thrift API хоть и не такой красивый, но хотя бы отражал реальные возможности для запросов.
    • +1
      Это замануха :)
    • 0
      У CQL кроме простоты есть ещё пара фичей, которых нет у Thrift. Например прекомпилирование запросов (prepared statements).
      Тут оба ответа замечательно всё раскладывают по полочкам: stackoverflow.com/questions/15701263/advantages-of-using-cql-over-thrift
      • 0
        Как я понял, прекомпилирование запросов — это штука, чтобы компиляция CQL запросов сама по себе не тормозила.
        Thrift ни в какой компиляции просто не нуждается.
        А по сути там ответ сводится к фразе «it just allows you to think about the model in a more organized way».
        Ну ок :)
  • 0
    Вот одно меня сильно смущает в Cassandra — RangeScan это практически не реализуемая вещь в ней. И никакие индексы не помогут. То есть реально, чтобы доступиться к данным тебе нужна вторая система, которая даст тебе построить ключ. В противном случае запросы будут таймаутиться.
    • 0
      Ну, или просто у вас неправильная схема/модель. :)
      Range Scan делается не так просто, как в SQL, но зато скорость ошеломляющая.
      • 0
        Для того чтобы схема была неправильная надо чтобы она была =). Но ее нет, так как нормально кассандра так и не заработала.
        Если честно, очень долго пытался придумать схему в которую уляжется таблица с 8 ключами и двумя колонками со статой. Строк около 2-ух миллиардов. Как только надо вернуть пару миллионов строк, все как-то нехорошо себя чувствует.
        Фильтрация по одному или нескольким ключам.
        • 0
          Ну, давайте разберём вашу задачу. Опишите что у вас там, а я попробую подсказать.
          • 0
            Да собственно вся задача. Есть статистика, агрегированная хадупом до ключей (дата, страна, регион, модель телефона итд).
            В Постгресе занимает около 3 терабайт.
            Нужно фильтровать (агрегировать планировал с помощью teiid)
            • 0
              Что мешает хранить в кластерных ключах все те вещи, по которым нужно делать Range Scan?
              • +1
                Ничего =)
                Оно просто таймаутится когда пытаешься достать больше 100к строк =)

                Проблема в том что распределительный ключ указать нереально. Ибо он может быть любым.
                Ну либо туда можно положить что-то денормализованное (типа id клиента который можно вычислить во время запроса кодом) — но тогде получается огромной ширины строка, и тоже все плохо.
                • 0
                  Во-первых, оно не должно таймаутится пока данные идут. А не идти они могут когда включается ALLOW FILTERING.
                  В-третьих, в С* есть стриминг данных специально для таких случаев. И многие основные драйверы языков поддерживают его. Дерзайте.
              • 0
                Наверное стоит добавить, что ключи не иерархичны. Например провайдер может быть в нескольких странах.
              • 0
                Скорее так, во второй кассандре можно делать индексы по кластерным ключам, и фактически это должно было дать мне возможность фильтровать по ключам без сурогатного (который приходилось делать в 1.2.* а индексы делать по остальным ключам). Но вторая кассандра не дала мне этой радости увы. Все так же таймаутится.
  • 0
    Медленно но верно nosql идет в сторону sql.
  • 0
    Жаль, что в Casandra нет возможности засунуть Json объекты и делать по ним отборы как в mongodb. Или я ошибаюсь?
    • 0
      Нет возможности такой. Какого уровня вложености ваши JSON объекты?
      Если они одноуровневые — то легко написать самому враппер.
      Если больше одного уровня, то тут незадача, да.
      • 0
        в том и дело, чтобы не думать вообще про структуру — может прийти и такой и такой и все в одном потоке
        • +1
          Я вас не понимаю.
    • 0
      Посмотрите в сторону github.com/ebuddy/c-star-path
    • 0
      Уже есть: https://cassandra.apache.org/doc/cql3/CQL.html#json
  • 0
    Ещё интереснее стало, спасибо большое. По ощущениям, ограничения понятны и следуют из архитектуры хранения.

    Наверное, и оптимизатор запросов Кассандре не нужен: что она не может сделать очевидным образом, она не делает вообще :).
    • 0
      Прекрасно! Рад что вам нравится. Рад что вы поняли дизайн это БД. Приятно почитать такие комментарии. :)
  • +2
    Я вот сколько занимаюсь кассандрой, до сих пор не в курсе — почему C*?
  • +1
    Cassandra действительно классная и узкоспециализированная БД. Используем для хранения кучи лайков на 6 ec2-нодах. И сейчас разрабатываем версию с сохранением в неё пользовательских фидов/новостей. Производительность отличная, масштабируемость тоже. Ветка 2.0 пока не нравится какими-то странными частыми затупами, иногде хочется откатиться на 1.2. Но конечно надо чётко понимать, для чего её использовать и как она устроена внутри, чтобы эффективно решать задачи, ну в общем как и почти с любой nosql базой.
  • 0
    Спасибо за статьи. Но почему-то вообще не рассмотрен ORDER BY.
    У меня очередь на кассандре, где у каждой задачи меняется поле updated (дата). Так вот непонятно как сделать выборку ORDER BY updated DESC. Я так понимаю, что изначально при создании таблицы не получится указать WITH CLUSTERING ORDER BY updated DESC; так как это поле нельзя сделать кластерным ключем, так как нужно менять его после каждого обращения к задаче. Что в этом случае можно сделать?
    • +2
      Очереди на кассандре — это антипаттерн. Мы вот обожглись и уже в процессе переезда с неё.
      Ну если только на маленьких объемах будет работать, у нас GC сходил с ума из-за чтений томбстоунов, которые при таком паттерне неизбежны
      • 0
        А какие объемы можно считать маленькими? И что вы имеете ввиду под томбстоунами? (этот термин мне знаком только из маркетинга, но вот в контексте IT слышу впервые)
        • +1
          Сложно сказать, сколько это. Странно, что Вы не знаете что такое tombstones, работая с кассандрой
          • 0
            А ну это если данные надо удалять. У меня данные удалять не нужно.

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