如何对聚合计数进行Cassandra数据建模?

时间:2015-12-11 16:00:16

标签: cassandra-2.0 datastax spark-cassandra-connector

假设我有客户订单数据进入我的服务,我想对这些数据进行一些报告。所有客户订单都保存在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. 然后我读了第三张表中的计数器,并在第二张表中插入一条新记录。

  4. 当我需要查找具有给定订单数量的所有客户时,我只查询第二个表。

    这个问题是计数器不是原子的和一致的。如果我将计数器更新为3,则无法保证当我下次读取它以更新第二个表时它将是3.它可能是2.即使我在更新计数器之前读取计数器它从几个步骤可能是一些价值。所以也不保证。 请注意,我知道Cassandra的计数器的局限性,我不会问如何解决计数器的问题。

    我宁愿给出这个例子,以便就如何对数据建模以及能够对其进行聚合计数提出一些一般性建议。我当然可以使用Spark直接在我的示例中的第一个表上进行聚合查询。但在我看来,可能有一些更聪明的方法来做到这一点,Spark也会涉及将整个表数据带入内存。

1 个答案:

答案 0 :(得分:0)

您是否考虑过使用CQL Batch命令。 https://docs.datastax.com/en/cql/3.1/cql/cql_reference/batch_r.html

您可以将此操作与所有步骤一起使用,以将所有步骤保留在一个逻辑原子事务中,其中它们都将成功或失败。但是,此功能确实会降低性能。