2016-03-23 2 views
0

Я знаю, что нормализация в Кассандре считается анти-шаблоном, но что можно сделать, если требование к хранилищу, которое оно подразумевает, слишком велико?Нормализация в Кассандре

К примеру, в настоящее время мы имеем большую таблицу «каналы», которые распределены по нескольким адресатам, так что текущая схема что-то вроде этого:

CREATE TABLE feed_items_duplicated(recipient_id int, feed_id timeuuid, 
    <data columns d1 to dn> 
    PRIMARY KEY ((recipient_id), feed_id); 

В этой схеме все красиво и фиды легко извлекается для одного получателя с использованием запроса одного диапазона над подачи ID:

SELECT * from feed_items_duplicated where recipient_id = 123 
    and feed_id > minTimeuuid('2013-09-30 22:19:06+0100'); 

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

Для того, чтобы содержать требования к хранению, мы думали другого варианта

CREATE TABLE feed_items(recipient_id int, feed_id timeuuid, 
    PRIMARY KEY ((recipient_id), feed_id); 
CREATE TABLE feed_data(feed_id timeuuid, <data columns d1 to dn> 
    PRIMARY KEY (feed_id); 

Это будет по-прежнему требует выполнения запроса выше дополнительного запуска запроса после этого:

SELECT * from feed_data where feed_id in (f1, f2, f3...); 

Так Вопрос 1: это хорошая идея для выполнения вышеуказанного запроса, поскольку он, скорее всего, ударит по всем узлам в кластере? Насколько это плохо по сравнению с выполнением выделенного запроса для каждого f1-fn параллельно?

Другой подход будет создание произвольного ключа кластеризации в пределах небольшого ограниченного диапазона (позволяет сказать, [1-20]) для feed_data стола так, что мы будем иметь только до 20 запросов следующего типа для выполнения:

SELECT * from feed_data where group_id = 1 and feed_id in (f1, f3, ...); 
SELECT * from feed_data where group_id = 2 and feed_id in (f2, ...); 

Этот подход ограничивает каждый запрос одним исполнительным узлом, но с таким ключом разделения с малой мощностью можно гарантировать, что данные будут распределены поровну между узлами?

ответ

0

вопрос 1: стоит попробовать, если возможная деградация времени доступа приемлема для получателей. Существует ряд рекомендаций и предупреждений о предложениях «in» в запросах CQL от DataStax и other nice guys. Вместо «in» запросов я предпочел бы думать о on-board caching.

вопрос 2: Если ваши столбцы данных [d1 ... dn] малы и не меняются резко от одного к другому, то я думаю, что это не проблема. Я думаю, что группировка данных - хорошая идея, если она приносит вам возможность повторного использования данных. Таким образом, вы можете упорядочить данные вашего фида, например: feed1 = bundle1 + bundle2, feed2 = bundle1 + bundle3 и т. Д., Где bundle1 = data-item1 + data-item2, bundle2 = data-item3 и т. Д.

от себя: если вы не уверен в стратегии оптимизации структуры данных, то, может быть, стоит попробовать ввести какую-то политику выселения для ваших данных фида? Как TTL или smth еще. Итак, вы можете оставить свои таблицы «реального времени» такими, какие они есть, и переместить устаревшие данные в более экономичное пространство или даже удалить его.

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