Большой двоичный объект моделирования данных Cassandra

#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);
  

У меня есть два типа запросов:

  1. получить все идентификаторы server_id и messages_blob при времени запуска> 100 и времени запуска <300.
  2. получить все 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 выбора — один для получения идентификатора сервера, а другой — для получения большого двоичного объекта — это все равно будет быстро…