我正在尝试使用 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
最佳答案
正如您所说,使用 IN 的查询可能会非常慢,因为在您的情况下需要读取多个分区,但您的查询是从一个协调器节点处理的(如果可能的话,通常会选择该节点作为负责处理分区的节点) .
此外,大分区在过去一直是一场噩梦 - 在 3.6 及更高版本中,它应该不会那么糟糕(请参阅 https://de.slideshare.net/DataStax/myths-of-big-partitions-robert-stupp-datastax-cassandra-summit-2016 )。读取性能和内存压力一直是严重的问题。
什么对我来说非常有效 - 但取决于您的用例 - 去使用“足够小的”存储桶(天),并在一个月内异步并行发出 31 个查询,然后将它们重新加入到您的代码中。例如,在 Java 中就有 Futures 支持你。这样,每个查询只会命中一个存储桶/分区,并且集群中的所有节点很可能并行处理您的查询。
关于Cassandra 用于时间序列数据 : how to size the partition?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45958085/