Cassandra的时间序列数据:如何调整分区大小?

时间:2017-08-30 10:32:39

标签: cassandra time-series

我正在尝试使用Cassandra存储来自某些传感器的数据。 我读了很多关于Cassandra的时间序列数据模型的文章。我从Getting Started with Time Series Data Modeling开始,“时间序列模式2”看起来是最好的方式。 所以我创建了一个复制因子为2的密钥空间和一个像这样的表

CREATE TABLE sensors_radio.draw (
dvid uuid,
bucket_time date,
utc_time double,
fft_size int,
n_avg int,
n_blocks int,
power double,
sample_rate double,
start_freq double,
PRIMARY KEY ((dvid, bucket_time), utc_time)

其中dvid是唯一的设备ID,bucket_time是一天(例如2017-08-30),utc_time是时间戳。

我的查询是

SELECT utc_time,start_freq,sample_rate,fft_size,n_avg,n_blocks,power
FROM sensors_radio.draw 
WHERE dvid=<dvid> 
AND bucket_time IN (<list-of-days>) 
AND utc_time>=1.4988002E9 
AND utc_time<1.4988734E9;

如您所见,我需要从多天检索数据,这意味着要在我的群集中读取多个分区。在我看来,查询性能看起来很差,这是可以理解的,因为IN反模式。

编辑:我试图通过将我的查询分成多个来避免IN反模式,但我没有得到任何性能提升。

我考虑通过使用而不是作为bucket_time来增加分区大小,以使用我的查询查询单个分区。 但我担心分区会增长太多!通过阅读this question的答案,我发现在一个月内我的分区将拥有大约5亿个单元(所以小于20亿个单元),但当然它会超过100MB大小限制和100000行限制。

此方案中推荐的数据模型是什么?大磁盘大小分区是否存在问题?

提前致谢。

聚苯乙烯。我在由3个节点(8个核心,16GB内存)组成的集群上使用Cassandra 3.10

2 个答案:

答案 0 :(得分:3)

正如您所说,使用IN的查询可能非常慢,因为在您的情况下需要读取多个分区,但您的查询是从一个协调器节点处理的(如果可能,通常选择该节点作为负责分区的节点)

此外,大型分区过去一直是一场噩梦 - 在3.6及以后它应该没那么糟糕(见https://de.slideshare.net/DataStax/myths-of-big-partitions-robert-stupp-datastax-cassandra-summit-2016)。阅读性能和内存压力一直是严重的问题。

对我来说效果真的很好 - 但取决于你的用例 - 去使用足够小的&#39; buckets(day)并且只异步并行地发出一个月的31个查询并将它们加入到代码中。例如,有一些期货以这种方式支持你。这样,每个查询只会命中一个桶/分区,并且很可能群集中的所有节点并行处理您的查询。

答案 1 :(得分:0)

实际上您理解列值大小的含义是错误的。

限制为 20亿-与原始数量无关,这是常规列和聚类键的工作方式

为此Nv=Nr(Nc−Npk−Ns)+Ns

使用此公式

分区(Nv)中值(或单元格)的数量等于静态列数(Ns)加上行数(Nr)与每行值的数量的乘积。每行的值数定义为列数(Nc)减去主键列(Npk)和静态列(Ns)的数目。

简短说明将为number of raws multiply by number of regular columns

您的情况将是:

(500 000 000 * (9 - 3 - 0) + 0) = 3 000 000 000

所以您超出限额 20亿

以及计算磁盘大小的公式 Calculating Size on Disk

您在磁盘上的分区大小将会很大

(20 + 0 + (500000000 * 84) + (8 * 3000000000)) = 
66000000020 bytes (62942.50 Mb)

显然超过了 100 Mb 卡桑德拉限额

我使用开放源代码项目cql-calculator对它进行了计算。