Кассандра: Как использовать 'ORDER BY' без PRIMARY KEY, ограниченного EQ или IN? - PullRequest
1 голос
/ 11 марта 2019

У меня есть таблица в Scylla (совместимая с Cassandra база данных), определенная следующим образом:

create table s.items (time timeuuid, name text, primary key (time));

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

select * from s.items where time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

Но мне сказали, что ORDER BY is only supported when the partition key is restricted by an EQ or an IN. Чтобы обойти это, я могу сделать таблицу и запрос, подобный следующему:

create table s.items (yes boolean, time timeuuid, name text, primary key (yes, time));

select * from s.items where yes=true and time>7e204790-43bf-11e9-9759-000000000004 order by time asc;

Хотя это работает, это не кажется лучшим решением. Поскольку я довольно новичок в Scylla и CQL, есть ли лучший / правильный способ сделать это?

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Ваше решение добавить этот один логический ключ и всегда устанавливать его в "да" в основном создает один огромный раздел со всеми вашими данными.Это редко то, что вы действительно хотите.Если этот один раздел представляет собой все ваши данные, это означает, что даже если у вас есть 10-узловый кластер с 8 ЦП на каждом узле, только 3 ЦП из всех 80 в вашем кластере будут выполнять любую работу (поскольку каждый раздел принадлежитопределенный процессор, и с RF = 3, есть три реплики).

Если вам интересно, почему ваше оригинальное решение не работает, и Сцилла отказалась от «ORDER BY», то проблема в том, что, хотя Scyllaможет сканировать всю таблицу, чтобы найти записи после времени X (вам нужно добавить «РАЗРЕШИТЬ ФИЛЬТР» в запрос), у нее нет эффективного способа сортировать того, что он находит по времени.Внутренне различные разделы сортируются не по ключу раздела, а по «токену», хэш-функции ключа раздела.Это хеширование с его эффектом рандомизации важно для балансировки нагрузки между всеми процессорами в кластере, но не позволяет Scylla (или Cassandra) читать разделы в исходном порядке ключей.

Одна вещь, которую вы можете сделать, это сделатьто, что Алекс предложил выше, является промежуточным звеном между вашей первоначальной настройкой и вашим предлагаемым решением: не иметь один элемент на раздел или все элементы в одном разделе, но что-то посередине: например, представьте, что вваша рабочая нагрузка, каждый день вы собираете 100 МБ данных.Таким образом, вы используете номер дня в качестве ключа раздела (вместо вашего bool).Все данные одного конкретного дня будут находиться в одном разделе. Внутри раздела каждого дня различные записи (строки) будут отсортированы по порядку ключей кластеризации, который будет временем.С помощью этой настройки, чтобы получить все элементы после определенного дня, просто начните запрашивать каждый отдельный день, один за другим.Например, день запроса 134, затем день 135, они 136, затем и т. Д. Внутри каждого дня результаты будут уже отсортированы.Итак, проблема решена.

Этот метод является довольно известным моделированием данных "временных рядов".У Сциллы (и Кассандры) даже есть специальная стратегия уплотнения, настроенная для этого моделирования, TWCS (стратегия уплотнения с временным окном).

1 голос
/ 11 марта 2019

На подобные вопросы уже дан ответ. Например, здесь: Cassandra Data моделирование: отметка времени в качестве ключей раздела

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

...