Кассандра - получить все данные за определенный промежуток времени - PullRequest
1 голос
/ 01 мая 2019

Можно ли запросить базу данных Cassandra, чтобы получить записи для определенного диапазона?

У меня есть такое определение таблицы

CREATE TABLE domain(
domain_name text,
status int,
last_scanned_date long
PRIMARY KEY(text,last_scanned_date)
)

Мое требование - получить все домены, которые не сканируются за последние 24 часа. Я написал следующий запрос, но этот запрос неэффективен, так как Кассандра пытается получить весь набор данных из-за ALLOW FILTERING

SELECT * FROM domain where last_scanned_date<=<last24hourstimeinmillis> ALLOW FILTERING;

Тогда я решил сделать это в двух запросах

1-й запрос:

SELECT DISTINCT name from domain;

2-й запрос: Используйте оператор IN для запроса доменов, которые не сканируются последние 24 часа

SELECT * FROM domain where 
domain_name IN('domain1','domain2') 
AND 
last_scanned_date<=<last24hourstimeinmillis> 

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

Есть ли лучший подход, чем этот?

Ответы [ 2 ]

1 голос
/ 01 мая 2019

Cassandra может эффективно выполнять запросы диапазона только внутри одного раздела.То же самое для использования агрегатов, таких как DISTINCT.Так что в вашем случае вам понадобится только один раздел, который будет содержать все данные.Но это плохой дизайн.

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

Другая проблема с вашей схемой заключается в том, что у вас есть last_scanned_date в качестве столбца кластеризации, и это означает, что при обновлении last_scanned_date вы фактически вставляете новую строкув базу данных - вам нужно явно удалить строку для предыдущего last_scanned_date, в противном случае запрос last_scanned_date<=<last24hourstimeinmillis> всегда будет извлекать старые строки, которые вы уже отсканировали.

Частично ваша проблема с вашим текущим дизайном может быть решена с помощьюиспользуя Spark, который способен эффективно сканировать полную таблицу с помощью сканирования диапазона токенов + сканирования диапазона для каждой отдельной строки - это вернет только данные в заданном временном диапазоне.Или, если вы не хотите использовать Spark, вы можете выполнить сканирование диапазона токенов в своем коде, что-то вроде this .

1 голос
/ 01 мая 2019

Вам следует обновить определение таблицы структуры. В настоящее время вы выбираете доменное имя в качестве ключа раздела, в то время как в одном разделе Cassandra не может быть более 2 миллиардов записей.

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

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

Пройдите следующие концепции, прежде чем доработать свой дизайн.

https://docs.datastax.com/en/cql/3.3/cql/cql_using/useCompositePartitionKeyConcept.html

https://docs.datastax.com/en/dse-planning/doc/planning/planningPartitionSize.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...