Удалить строки и производительность удаления столбцов

Я создаю модель данных для приложения временных рядов на Cassandra 2.1.3. Мы будем сохранять X объем данных для каждого пользователя системы, и мне интересно, как лучше всего подойти к проектированию для этого требования.

Опция 1:

Используйте «сегмент» в ключе раздела, чтобы данные за период X попадали в ту же строку. Что-то вроде этого:

((id, bucket), timestamp) -> data

Я могу удалить одну строку сразу за счет сохранения этой концепции ведра. Это также ограничивает диапазон, который я могу запросить на timestamp, что, вероятно, приведет к нескольким запросам.

Вариант 2:

Храните все данные в одной строке. N удалений на столбец.

(id, timestamp) -> data

Запросы диапазона снова просты. Но как насчет производительности после удаления многих столбцов?

Учитывая, что мы планируем использовать TTL для истечения срока действия данных, какая из двух моделей обеспечит наилучшую производительность? Является ли надгробная плита накладной для Варианта 1 ‹‹ Варианта 2 или в любом случае будет надгробие на столбец в обеих моделях?

Я стараюсь не хоронить себя на могильном кладбище.


person maasg    schedule 16.03.2015    source источник


Ответы (2)


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

Обычно я склоняюсь к варианту №1, особенно если ваш TTL одинаков для всех операций записи. Кроме того, если вы используете LeveledCompactionStrategy или DataTieredCompactionStrategy, Cassandra отлично справится с сохранением данных из одного раздела в одной SSTable, что значительно повысит производительность чтения.

Если вы используете вариант № 2, данные для одного и того же раздела, вероятно, могут быть распределены по нескольким уровням (при использовании LCS) или просто по нескольким sstables, что может привести к чтению из большого количества SSTables, в зависимости от характера ваших запросов. . Существует также проблема горячих точек, когда вы можете перегрузить определенные узлы cassandra, если у вас действительно широкий раздел.

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

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

Что касается производительности, считаете ли вы вероятным, что вам нужно будет читать кросс-разделы, когда ваше приложение делает запросы? Например, если у вас есть запрос на «последние 1000 записей», а раздел обычно шире, вам может потребоваться сделать только 1 запрос для варианта № 1. Однако, если вы хотите получить запрос типа «дайте мне все записи», вариант № 2 может быть лучше, так как в противном случае вам нужно будет делать запросы для каждого сегмента.

person Andy Tolbert    schedule 16.03.2015

После создания описанных выше таблиц:

CREATE TABLE option1 (
                 ...   id bigint,
                 ...   bucket bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY ((id, bucket), timestamp)
                 ... ) WITH default_time_to_live=10;

CREATE TABLE option2 (
                 ...   id bigint,
                 ...   timestamp timestamp,
                 ...   data text,
                 ...   PRIMARY KEY (id, timestamp)  
                 ... ) WITH default_time_to_live=10;

Я вставил тестовую строку:

INSERT INTO option1 (id,bucket,timestamp,data) VALUES (1,2015,'2015-03-16 11:24:00-0500','test1');
INSERT INTO option2 (id,timestamp,data) VALUES (1,'2015-03-16 11:24:00-0500','test2');

... подождал 10 секунд, запросил с включенной трассировкой и увидел одинаковые счетчики надгробий для каждой таблицы. Так что, в любом случае, это не должно вас сильно беспокоить.

Настоящая проблема заключается в том, что если вы думаете, что когда-нибудь достигнете предела в 2 миллиарда столбцов на раздел, то вариант № 1 является безопасным. Если у вас много данных, вариант № 1 может работать лучше (потому что вы избавитесь от необходимости просматривать разделы, которые не соответствуют вашему bucket), но на самом деле любой из них должен подойти в этом отношении.

тл;др;

Поскольку вопросы производительности и надгробий будут одинаковыми независимо от того, какой вариант вы выберете, я думаю, что вариант № 2 лучше, просто из-за простоты запросов.

person Aaron    schedule 16.03.2015
comment
В вариантах № 1 и № 2 количество надгробий будет одинаковым (в зависимости от эффективности уплотнения, что может быть не так), но сколько вам нужно прочитать, вероятно, будет отличаться в зависимости от вашего запроса. Например, если ваша корзина «день», и вы читаете запросы по дням, с вариантом № 1 вам не нужно будет читать данные надгробий за предыдущие дни, тогда как с вариантом № 2 вам нужно читать до того места, где данные внутри раздела, если есть надгробия за предыдущие дни, предшествующие этим данным (хотя интервал индекса столбца может помочь с этим). - person Andy Tolbert; 17.03.2015
comment
@AndyTolbert Хороший вопрос. Я сделал наблюдение, основываясь только на модели, но вы абсолютно правы в том, что дополнительное ведро секционирования сократит чтение надгробий. - person Aaron; 17.03.2015