我们有成千上万的传感器来产生我们想要存储在卡桑德拉的测量时间序列数据。我们目前每天存储5亿条记录,这一数量将在下一次以5-10的倍数增长。
我们主要使用最新的测量数据。旧的测量数据几乎不被读取。
作为压实策略,我们采用DTCS。设置一个ttl不是一个选项,因为我们需要为归档目的存储测量数据。
我还不知道如何处理“旧数据几乎冷”的事实。
更新:我想避免的是:在我的Cassandra集群中有20 TB,其中使用了18 TB,比方说,一年只使用一次,如果有的话。我不想为不需要的18种结核病买单。设置一个ttl不是一个选项,因为我们应该能够读取数据,例如从2013年3月开始(这样的请求的额外费用是可以的)。如果我们设定为6个月,那么我们就不能正确地做到这一点。
我们目前正在评估两种设计方案,并寻找最具成本效益的:
(在这两种情况下,每行最多有500 K列,大部分都小于100 K)
2的缺点是,我们将有<100个键空间而不是1,并且读取数据时的复杂性会增加。2.的优点是,我们可以每月快照/备份/删除/恢复它们,据我理解,如果采用选项1,这是不容易做到的。这样,我们就不需要对Cassandra集群进行大小调整,就可以保存真正冷的兆字节数据。
我的问题是:是2.我们用例的合理选择,还是在Cassandra?中这是一种反模式?
谢谢你的帮助!
发布于 2016-04-11 14:44:45
通常,您不希望在单独的键空间中有旧的冷数据,因为这将变得很难维护(正如您所提到的)。现在,由于您如何对数据进行分区,您的挑战似乎是非常宽的行。相反,我会建议你按月“桶”数据。这可以通过修改分区键来完成,如下所示:
PRIMARY KEY ((year,month,sensor_id), measurement_date)额外的括号是CQL语法,用于将多个列声明为分区键。这意味着您必须提供一年、一个月和一个sensor_id才能读取此表。但是,请记住,在Cassandra中,主键(与关系数据库不同)定义了数据在集群中的分布方式。因此,实际上,我们所做的是在它自己的行列中,用一年的时间来对抗传感器数据。因此,我们基本上是用多个键空间来实现您所想的,但是以一种更多的Cassandra和开发人员友好的方式。
要将数据插入到此表中将非常容易。假设measurement_date是一个timeuuid (否则您可能要覆盖数据),下面是您的代码应该做的一般流程:
- INSERT INTO time\_series (year,month,sensor\_id, measurement\_date) VALUES (2016,4,'sensor\_id','generated timeuuid here');
正如我之前提到的,从表中读取数据应该是非常直接的。如果您想要更多的信息,我有一个更长的响应,这与您的数据建模问题这里有关。
由于您每天要编写500 K的测量数据,所以您希望进一步存储这些数据(请参阅上面的答案,以获得更多的详细信息),因为一般来说,当集群列超过10k时,C*的性能就会很差。
最后,您可能需要阅读优化冷态SS表,因为它提供了一些很好的信息。例如,您可以调优cold_reads_to_omit,这样就不会浪费时间来压缩非常冷的表。对于DTCS,您可以设置max_sstable_age_days以停止压缩一定年龄的SS表,从而在冷表上保存IO。
更新:存储大小管理:如果您想继续只使用一个表来处理所有的事情,那么您可以调整一些东西。首先,确保表使用的是压缩(理想情况下是lz4),接下来,您可以降低复制因子,这也会节省空间。我想,如果您对旧数据和新数据有不同的键空间,那么每个数据都可以有一个不同的RF来节省空间。
对于您正在推送和需要存档的数据量,我鼓励您查看时间序列数据库(TSDB),如Graphite和InfluxDB。对于您的目标和挑战,TSDB将比按摩Cassandra来执行timeseries数据更容易使用和执行。
发布于 2016-04-11 12:39:18
不建议在相同的键空间或表序列中对数据进行分区,因为两者都是为了保存有关数据的模式和元数据详细信息而设计的,而实际的数据分区应该基于分区/群集键来实现。
虽然使用快照备份数据不像预期的那样按月进行,但您可能可以使用增量备份与自定义解决方案一起存储一个月的刷新马厩。对于删除数据,使用TTL仍然是处理时间序列数据和确保磁盘空间不耗尽的最常见方式。
https://stackoverflow.com/questions/36545345
复制相似问题