我们目前正在研究Cassandra作为大型时间序列系统的数据库。
我已经通读了https://academy.datastax.com/resources/getting-started-time-series-data-modeling关于Cassandra中的时间序列数据建模。
我们所拥有的是许多气象站的高速时间序列数据。每个气象站都有许多"传感器",每个传感器收集三个指标:温度、湿度和光照。
我们试图将每个系列存储为一个大行。然而,我们预计在项目的整个生命周期内,每个站点将获得数十亿的读数,因此我们希望限制行大小。
我们希望每个(weather_station_id, year, day_of_year)
都有一行,也就是说,每天都有一个新行。然而,我们仍然希望分区键为weather_station_id
——也就是说,我们希望一个站点的所有读数都在同一节点上。
我们目前有以下模式,但我想得到一些反馈。
CREATE TABLE weather_station_data (
weather_station_id int,
year int,
day_of_year int,
time timestamp,
sensor_id int,
temperature int,
humidity int,
light int,
PRIMARY KEY ((weather_station_id), year, day_of_year, time, sensor_id)
) WITH CLUSTERING ORDER BY (year DESC, day_of_year DESC, time DESC, sensor_id DESC);
在前面提到的文档中,他们使用了"按日期限制分区行"的概念。然而,我不清楚他们的例子中的日期是否是分区键的一部分。
根据教程,如果我们选择weather_station_id作为唯一的分区,那么该行将耗尽。即C*具有每个分区20亿列的实际限制。
所以IMO,你的数据模型不好。
然而,我不清楚他们的例子中的日期是否是分区键的一部分。
教程使用
PRIMARY KEY ((weatherstation_id,date),event_time)
所以,是的,他们认为数据是分区键的一部分。
我们希望一个站点的所有读数都在同一个节点上。
我不知道你为什么不这样要求。您总是可以使用一年以上的多个查询来获取天气数据。
select * from weather_station_data where weather_station_id=1234 and year= 2013;
select * from weather_station_data where weather_station_id=1234 and year= 2014;
因此,考虑将您的结构更改为
PRIMARY KEY ((weather_station_id, year), day_of_year, time, sensor_id)
希望它能有所帮助!
在我看来,数据税模型并不是很好。这个模型的问题:
- 他们正在用气象站作为隔断钥匙。具有相同分区键的所有行都存储在同一台机器上。这意味着:如果你有10年的原始数据(100毫秒的步长),你会很快突破卡桑德拉斯的限制。10年×365天×24小时×60分钟×60秒×10(100毫秒步)×7列。上限是20亿。在我看来,如果你构建这个数据模型,你就不会使用cassandra的好处。您还可以为每个气象站使用mongo、mysql或其他数据库
更好的解决方案是:问问自己将如何查询这些数据。如果你说:我每年查询所有数据,也使用年份作为partion键。如果还需要查询一年以上的数据,可以创建两个不同年份的查询。这样有效,性能更好。(瓶颈可能只是连接到客户端的网络)
- 还有一点提示:Cassandra不像mysql。这是一个非规范化的数据库。这意味着:多次保存数据并不肮脏。这意味着:每年查询数据对您来说很重要,每小时、一年中的每一天或每sensor_id查询数据也很重要,您可以创建具有不同分区键和奇偶键顺序的列族。可以复制您的数据。Cassandra针对写性能进行了优化,而不是针对读性能。这意味着:通常最好按正确的顺序写入数据,而不是按正确的次序读取数据。在cassandra 3.0中,有一个新功能,称为物化视图,用于自动复制。如果你想:哦,不,我会复制所需的存储空间。记住:存储真的很便宜。用1tb买十块硬盘是可以的。它不花钱。性能很重要
我有一个问题要问你:你能汇总你的数据吗?Cassandra有一个名为counter的列类型。您可以创建一个java/scala应用程序,在生成数据时聚合数据。您可以为此使用流媒体框架:Flink或Spark。(如果你需要的不仅仅是计数。)。一种场景:你每小时和每一天都在汇总你的数据。您在流媒体应用程序中获取了数据。现在:您有一个小时数据的变量。你可以向上或向下计数。如果小时结束,则将此行放入小时列族和每日列族中。在你的日常专栏家庭中,你使用了一个计数器。我希望你能理解我的意思。