#sql #cassandra #nosql #data-modeling
#sql #cassandra #nosql #моделирование данных
Вопрос:
Я подумываю об использовании cassandra для хранения моих данных. У меня есть server_id, start_time, end_time, messages_blob.
CREATE TABLE messages (
server_id uuid,
start bigint,
end bigint,
messages_blob blob,
PRIMARY KEY ((server_id), start,end)
) WITH CLUSTERING ORDER BY (start,end);
У меня есть два типа запросов:
- получить все идентификаторы server_id и messages_blob при времени запуска> 100 и времени запуска <300.
- получить все messages_blob для группы server_id одновременно.
Может ли приведенная выше схема помочь мне в этом? Мне нужно очень быстро поместить миллиарды записей в эту таблицу и выполнить чтение после того, как все вставки произошли. Запросов на чтение не слишком много по сравнению с записями, но мне нужно вернуть данные как можно быстрее.
Ответ №1:
С этой структурой таблицы вы можете выполнить только 2-й запрос — вам просто нужно будет выполнять запросы для каждого server_id
отдельно, лучше всего через асинхронный API.
Для 1-го запроса эта структура таблицы не будет работать, поскольку Cassandra должна знать ключ раздела ( server_id
) для выполнения запроса — в противном случае потребуется полное сканирование, которое завершится, когда у вас будет достаточно данных в таблице.
Для выполнения этого запроса у вас есть несколько вариантов.
Добавьте еще одну таблицу, которая будет иметь start
ключ раздела as, и там вы сможете хранить первичные ключи записей в первой таблице. Что-то вроде этого:
create table lookup (start bigint, server_id uuid, end bigint,
primary key(start, server_id, end));
для этого потребуется, чтобы вы записали данные в 2 таблицы, или, возможно, вы можете использовать materialized view для этой задачи (хотя это может быть проблематично, если вы используете OSS Cassandra, поскольку там много ошибок). Но вам нужно быть осторожным с размером раздела для этой справочной таблицы.
Используйте Spark для сканирования таблицы — поскольку у вас есть start
первый столбец кластеризации, тогда Spark сможет выполнять нажатие на предикаты, и фильтрация будет происходить внутри Casasndra. Но это будет намного медленнее, чем использование таблицы поиска.
Кроме того, будьте очень осторожны с большими двоичными объектами — Cassandra плохо работает с большими двоичными объектами, поэтому, если у вас есть двоичные объекты размером более 1 МБ, вам нужно разделить их на несколько частей или (лучше) сохранить их в файловой системе или в каком-либо другом хранилище, например, в S3, и сохранитьв Cassandra только метаданные.
Комментарии:
1. Я не был ясен в своем вопросе. Сейчас я его отредактировал. В первом запросе я хочу, чтобы на самом деле были server_id и messages_blob, а не просто server_ids. Имеет ли это какое-либо значение? Размер большого двоичного объекта невелик (до 32 КБ), но я не хочу дублировать большой двоичный объект в двух таблицах.
2. Вы не получите его с помощью одного выбора без дублирования данных, но вы можете сделать 2 выбора — один для получения идентификатора сервера, а другой — для получения большого двоичного объекта — это все равно будет быстро…