Как выполнить моделирование данных Cassandra для совокупного подсчета?

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

TABLE customer_orders

store_id uuid,
customer_id text,
order_id text,
order_amount int,
order_date timestamp,

PRIMARY: KEY (store_id, customer_id)

Но я также хотел бы найти всех клиентов с заданным количеством заказов. В идеале я хотел бы иметь это в готовой к запросу таблице в Cassandra. Например, «получить всех клиентов, у которых есть 1 заказ».

Поэтому у меня есть такая таблица:

TABLE order_count_to_customer

store_id uuid,
order_count int,
customer_id text

PRIMARY KEY ((store_id, order_count), customer_id)

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

Поэтому я создаю третью таблицу:

TABLE customer_to_orders_count

store_id uuid,
customer_id text,
orders_count counter,

PRIMARY KEY (store_id, orders_count)

Когда приходит заказ:

  1. Я сохраняю его в первой таблице

  2. Затем обновите счетчик в третьей таблице, увеличив его на 1.

  3. Затем я читаю счетчик в третьей таблице и вставляю новую запись во вторую таблицу.

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

Проблема в том, что счетчики не являются атомарными и непротиворечивыми. Если я обновлю счетчик, скажем, до 3, нет никакой гарантии, что когда я прочитаю его в следующий раз, чтобы обновить вторую таблицу, это будет 3. Это может быть 2. Даже если я прочитаю счетчик до того, как я обновлю счетчик, он может быть некоторым значением на несколько шагов назад. Так что тоже никакой гарантии. Обратите внимание, что я знаю об ограничениях счетчиков в Cassandra и не спрашиваю, как решить проблему со счетчиками.

Я скорее привожу этот пример, чтобы попросить несколько общих советов о том, как смоделировать данные, чтобы иметь возможность выполнять их совокупный подсчет. Конечно, я могу использовать Spark для выполнения агрегированных запросов непосредственно к первой таблице в моем примере. Но мне кажется, что можно было бы сделать это более умным способом, а также Spark потребовал бы переноса всех данных таблицы в память.


person Milen Kovachev    schedule 11.12.2015    source источник


Ответы (1)


Думали ли вы об использовании команды CQL Batch. https://docs.datastax.com/en/cql/3.1/cql/cql_reference/batch_r.html

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

person bechbd    schedule 22.12.2015