2015-06-05 6 views
1

Мы ищем инструмент (желательно с открытым исходным кодом), который помогает нам выполнять сложные запросы (расширенная фильтрация и объединение, без необходимости полного SQL) в режиме реального времени.Комплексные запросы в реальном времени на Cassandra

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

Чтобы быть более конкретным, нам нужно загрузить n разделов одной таблицы и объединить их с помощью столбца кластеризации.

Variables Table: 
Variable ID: Partition key 
Person ID: Clustering key 
Variable Value 

Desired output columns: 
Person ID, Variable 1 Value, Variable 2 Vale, ..., Variable N Value 

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

Мы протестировали Spark, но разбиение коннектора Spark C * основано на первичном ключе, поэтому каждый Идентификатор переменной будет загружен в другом искровом узле, и процесс соединения будет очень медленным (все данные будет путешествовать по всему искровому кластеру).

Любые советы? известных инструментов?

+0

Возможный дубликат https://stackoverflow.com/questions/16790297/inner-join-in-cassandra-cql – Raedwald

ответ

0

Я считаю, что у вас есть несколько вариантов для выполнения этой задачи:

  • Пересмотрите схему базы данных, денормализовать его. var_id:person_id:value строки не лучшая схема таблицы, если вы хотите запросить по person_id (и это пахнет очень плохо, как entity-attribute-value db antipattern):

EAV дает гибкость разработчику определить схему по мере необходимости и это хорошо в некоторых случаях. С другой стороны, он плохо работает в случае неопределенного запроса и может поддерживать другие плохие методы. Другими словами, EAV дает вам достаточно веревки, чтобы повесить себя и в этой отрасли, все должно быть рассчитано на самый низкий уровень сложности, потому что парень, заменяющий вас на проекте, скорее всего, будет идиотом.

Вы можете использовать схему с несколькими столбцами (Cassandra может обрабатывать их много):

create table person_data (
    person_id int primary key, 
    var1 text, 
    var2 text, 
    var3 text, 
    var4 text, 
    .... 
); 

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

  • Создайте дополнительный индекс person_id (даже это ключ кластеризации уже). Вы можете запросить все данные для конкретного пользователя без использования соединений, но с некоторыми вопросами:

    • Как ваш запрос будет поражать несколько разделов, то потребуется не один диск искать, но ряд из них, так что ваши Задержка запроса может быть выше, чем вы ожидаете.
    • вторичные индексы не являются бесплатными: C * должен выполнять больше работы под капотом, если вы вставляете строку в таблицу с индексированными столбцами.
  • Использовать внешний индекс как ElasticSearch/Solr, если вы планируете иметь много сложных запросов, которые не вписываются в cql3.

+0

Спасибо за ответ shutty. Моя модель использования заключается не в том, чтобы получить все переменные для человека, а для того, чтобы получить все значения персонажа подгруппы переменных. Вход представляет собой список переменных, а вывод - список лиц и его значений для каждой переменной. Мне кажется разумным использовать переменные в качестве ключей разделов, но, возможно, я пропустил какой-то важный момент здесь. –

+0

Решение с колоночной переменной отклонено, поскольку переменные очень динамичны и кажутся плохими проектами для использования неограниченного количества столбцов, динамически создаваемых кодом приложения. Мы также тестировали коллекции Cassandra, и они действительно выполняли очень плохо (чтобы сохранить переменные на карте), а некоторые возможности CQL недоступны с использованием коллекций. –

Смежные вопросы