Хранение временных рядов взвешенного графа в Cassandra

Я новичок в Cassandra, и я хочу провести мозговой штурм с сохранением временных рядов взвешенных графиков в Cassandra, где вес ребер увеличивается каждый раз, но также обновляется как функция времени. Например,

w_ij(t+1) = w_ij(t)*exp(-dt/tau) + 1

Мой первый снимок включает две таблицы CQL v3:

Сначала я создаю ключ раздела, объединяя идентификатор графа и два узла, инцидентных на конкретном ребре, например Г-В1-В2. Я делаю это для того, чтобы иметь возможность использовать директиву «ORDER BY» для второго компонента составных ключей, описанного ниже, который является временной меткой типа. Назовите эту строку EID для "edge id".

TABLE 1
- a time series of edge updates
- PRIMARY KEY: EID, time, weight


TABLE 2
- values of "last update time" and "last weight"
- PRIMARY KEY: EID
- COLUMNS: time, weight

После каждого тика я извлекаю и обновляю значения времени и веса, хранящиеся в ТАБЛИЦЕ 2. Я использую эти значения для вычисления дельты времени и нового веса. Затем я вставляю эти значения в ТАБЛИЦУ 1.

Есть ли в этой стратегии ужасные недостатки? Как следует это сделать? Я уже знаю, что процедура обновления ТАБЛИЦЫ 2 не идемпотентна и может привести к несогласованности, но пока я могу с этим согласиться.

ИЗМЕНИТЬ. Я мог бы объединить две таблицы в одну таблицу временных рядов.


person Daniel Gabriele    schedule 04.07.2013    source источник


Ответы (3)


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

person Theo    schedule 05.07.2013

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

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

Если ваши запросы позволяют использовать эту модель данных, я бы попытался построить решение с одним семейством столбцов.

person Phil P.    schedule 05.07.2013

Я бы не стал читать, прежде чем писать на Кассандре, потому что это действительно не очень подходит. Чтение стоит дорого, значительно дороже, чем запись, и для поддержания производительности вам понадобится большое количество узлов для относительно небольшого количества запросов. То, что вы предлагаете, на самом деле не подходит для Кассандры, поскольку, похоже, нет никакого способа избежать чтения, прежде чем писать. Даже если вы используете одну таблицу, вам все равно нужно будет получить последние записи обновления для выполнения записи. Хотя это, безусловно, можно сделать, я думаю, что для этой работы есть более эффективные инструменты. Сказав это, это было бы вполне возможно, если бы вы могли хранить все данные в таблице 2 в памяти и потенциально использовать кеш строк. Пока таблица 2 не настолько велика, чтобы вместить большинство строк в памяти, чтение будет происходить значительно быстрее, что может компенсировать необходимость выполнять чтение при каждой записи. Однако это было бы довольно сложно, и вам нужно было бы убедиться, что в памяти хранится только «время последнего обновления» для каждой строки, и к диску редко нужно прикасаться.

В любом случае, другой дизайн, на который вы, возможно, захотите взглянуть, - это реализация, в которой вы не только используете Cassandra, но и кеш перед Cassandra для хранения последнего обновленного времени. Это может быть запущено вместе с Cassandra или на отдельном узле, но может быть хранилищем в памяти только последнего времени обновления, и когда вам нужно обновить строку, вы запрашиваете кеш и записываете свою полную строку в Cassandra (вы даже можете написать время последнего обновления, если хотите). Вы можете использовать что-то вроде Redis для выполнения этой функции, и тогда вам не нужно будет беспокоиться о надгробиях или принудительном хранении всего в памяти и т. Д. И т. Д.

person Kurt    schedule 10.06.2016