#cassandra #scylla
Вопрос:
У меня есть много быстро поступающих данных, которые организованы таким образом;
- Множество массивов 1D, по одному на логический объект, где важно положение каждого элемента в массиве, и каждый элемент вычисляется и создается отдельно параллельно, и поэтому не обязательно по порядку.
- Сами массивы данных не обязательно записываются по порядку.
- Длина массивов может варьироваться.
- Данные либо считываются как весь массив за один раз, поэтому имеет смысл хранить все вместе.
На мой взгляд, проблема в первую очередь вызвана тем, как данные становятся доступными для записи. Если бы все это было доступно вместе, я бы просто собрал всю партию вместе в одно и то же время и покончил с этим.
Для небольших нагрузок данных я могу обойтись без типа данных массива postgres. Одна строка на логический объект с ключом и столбцом массива. Это позволяет мне масштабироваться, имея по одному записывающему устройству на массив, записывая элементы в любом порядке, не блокируя никакого другого записывающего устройства. Это ограничено скоростью одного узла postgres.
В Кассандре/Сцилле, похоже, у меня есть варианты либо:
- Хранение каждого элемента в отдельной строке, которое было бы очень быстрым для записи, считывание было бы более громоздким, но выполнимым и потенциально включало бы множество очень широких сканирований,
- или преобразование массива в json/строку, чтение ячейки, изменение значения, а затем его переписывание, что было бы ужасно медленным и привело бы к большим затратам на сжатие
- или иметь буфер записи до тех пор, пока он не получит все значения массива, а затем записать массив за один раз, за исключением того, что автор не будет знать, как долго должен быть массив, и ему потребуется время на запись всего, что у него есть к этому времени, что в конечном итоге означает, что мне нужно будет обновить его в какой-то момент в будущем, если появятся поздние данные.
Какие еще у меня есть варианты?
Спасибо
Ответ №1:
Вариант 1, кажется, хорошо подходит: я предполагаю, что у каждого логического объекта есть уникальный идентификатор (или, лучше, uuid) В таком случае вы можете создать что-то вроде
CREATE TABLE tbl (id uuid, ord int, v text, PRIMARY KEY (id, ord));
Где uuid-это ключ раздела, а ord-ключ кластеризации (упорядочения), каждый «массив» является разделом, а каждое значение-строкой.
Это позволяет
- быстрое извлечение всего «массива», даже большого, с помощью подкачки
- быстрое извлечение индекса из массива
Комментарии:
1. Проблема с сохранением заказа в виде
int
заключается в том, что вам придется постоянно переписывать раздел при поступлении новых записей. Это также требует условного чтения перед записью, чтобы получить текущее значение, а затем установить его. Обратите также внимание, что @Blootac заявил, что элементы вычисляются параллельно, поэтому при записи они не в порядке. Ваше здоровье!2. Спасибо @ErickRamirez. Второй пункт верен. Не уверен, что я понял первый, «переписывание» происходит только при сжатии. Ни в коем случае весь раздел не хранится как есть в одном месте.
3. @ErickRamirez на самом деле, это не проблема. Предположим, что элементы были вычислены в порядке 3,1,2, мы знаем положение данных в массиве до того, как мы его запишем, поэтому он буквально просто хранит их в положении 3. Это не похоже на очередь или вектор, где мы должны вставлять вещи и заполнять пробелы. Пробелы или пустые позиции в массиве разрешены и обрабатываются. Вариант 1 будет работать, как и предлагал Цах Ливятан, при наличии общего идентификатора раздела все элементы будут расположены совместно. просто хотел проверить, нет ли очевидной закономерности, которую я упускаю.