我正在尝试使用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
答案 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亿
您在磁盘上的分区大小将会很大
(20 + 0 + (500000000 * 84) + (8 * 3000000000)) =
66000000020 bytes (62942.50 Mb)
显然超过了 100 Mb 卡桑德拉限额
我使用开放源代码项目cql-calculator对它进行了计算。