用于汇总时间序列数据的 Cassandra 数据模型
Posted
技术标签:
【中文标题】用于汇总时间序列数据的 Cassandra 数据模型【英文标题】:Cassandra Data Model for sumed time series data 【发布时间】:2014-11-21 00:01:00 【问题描述】:C* 中的时间序列建模很简单,但如果您想添加一些粒度怎么办?
我们有一个看起来像这样的表
CREATE TABLE sales (
c_id text,
purchased_at timestamp,
revenue_cents integer,
PRIMARY KEY (channel_id, purchased_at)
);
现在我们要选择过去 365 天内的所有销售额,并将时间粒度设置为一周。我们可以在前端对其进行求和,但就我们将选择数十万行而言,这似乎是一种非性能,尤其是在选择速度最重要的情况下。
一个简短的例子:
在我们的sales
表中,我们插入以下销售额
INSERT INTO sales (c_id, purchased_at, revenue_cents) VALUES (1, '2014-12-15 07:01:00', 200);
INSERT INTO sales (c_id, purchased_at, revenue_cents) VALUES (1, '2014-12-17 08:01:00', 400);
INSERT INTO sales (c_id, purchased_at, revenue_cents) VALUES (1, '2014-12-24 20:01:00', 400);
INSERT INTO sales (c_id, purchased_at, revenue_cents) VALUES (1, '2014-12-16 10:01:00', 600);
每天可能有数千笔销售额,所以如果我们想制作一张关于去年收入多少的图表,请使用如下查询:
SELECT revenue_cents FROM sales WHERE c_id='1' AND purchased_at > '2014-01-01 00:00:00';
我们会像一百万行一样返回,这还不够快。我们也不知道每次销售时的信息,我们只需要第 225 天(或第 44 周或第 6 个月)的信息。因此,如果我们运行上面的查询并希望它以某种方式按月分组,我们将返回 11/12 行,并且将收入美分全部汇总。我知道 C* 不能直接做到这一点,但不知何故这可以,对吧?
因此,我的问题是,如何才能做到这一点?
【问题讨论】:
【参考方案1】:也许类似于"Time Series Pattern 2 Partitioning to limit row size",但使用一年中的一周而不是一年中的某一天作为日期,对您有用。也许您可以使用一些 Cassandra 功能在本页描述的分区行上进行切片:http://www.datastax.com/documentation/cql/3.1/cql/cql_using/use-slice-partition.html。例如:
创建表销售 ( c_id 文本, 购买时间戳, 收入_美分大整数, 周整数, 主键((c_id,周),购买的_at) );使用composite PRIMARY KEY 定义将对一周内的所有数据进行分组。
INSERT INTO sales (c_id, week, purchase_at,income_cents) VALUES ('wholesale', 50, '2014-12-15 07:01:00', 1234804938237367); INSERT INTO sales (c_id, week, purchase_at,income_cents) VALUES ('retail', 50, '2014-12-17 08:01:00', 253480493823736700); INSERT INTO sales (c_id, week, purchase_at,income_cents) VALUES ('retail', 51, '2014-12-22 20:01:00', 3480493823736700); INSERT INTO sales (c_id, week, purchase_at,income_cents) VALUES ('retail', 50, '2014-12-16 10:01:00', 250480493823736700); 选择 * 从销售 WHERE c_id='零售' 和周=50; c_id |周 |购买_at |收入美分 --------+------+--------------+------- ------------- 零售 | 50 | 2014-12-16 10:01:00-0800 | 250480493823736700 零售 | 50 | 2014-12-17 08:01:00-0800 | 253480493823736700【讨论】:
嗨猫爪,感谢您的回答,但就我而言,我们仍然会SELECT
数千行而不是每小时几行,对吧?
您好 Michael Hirn,抱歉,答案不够充分。我想我不明白你的问题并添加了一个例子。希望一些讨论会导致解决方案。
感谢您这么快的回复,我用一个例子更新了这个问题,现在问题变得更加清晰了。
嗯,@catpaws 的回答是对的。为了让 Cassandra 具有水平可扩展性和巨大的吞吐量,了解这里的工作原理至关重要。如果您当前的列族架构不符合您的要求(或本例中的查询),那么它可能是错误的并且必须重新设计。在这种情况下,Cassandra 似乎是一个正确的选择,但对于当前的 CF 模式,除非减少客户端的结果,否则无事可做。这里可以做的是使用计数器创建另一个 CF,例如 sales_by_week
、sales_by_month
、sales_by_day
。以上是关于用于汇总时间序列数据的 Cassandra 数据模型的主要内容,如果未能解决你的问题,请参考以下文章