Apache Cassandra 替代时间序列模型,一行中有许多列

its*_*ata 4 time-series cassandra

我们成功地使用瘦行方法在 cassandra 中存储时间序列(包括分桶)。尽管如此,我正在为我们寻找高效的存储模型(例如,更少的存储消耗......)。一个用例是将每个值的每一秒存储到一个表中。

最后一种方法(宽行多列)对我来说就像一个完整的反模式(不是理论上,而是在实践中)。有人有这种方法的经验并且可以证实我对此的看法吗?

1) Skinny Row宽行(灵活,可以过滤时间戳)

CREATE TABLE timeseries (
    id int,
    date date,
    timestamp timestamp,    
    value decimal,
    PRIMARY KEY ((id, date), timestamp)
) WITH CLUSTERING ORDER BY (timestamp DESC)
Run Code Online (Sandbox Code Playgroud)

2) 包含一天所有值的 Blob/JSON(更少的存储消耗,没有对节点上的时间戳进行过滤)

CREATE TABLE timeseries(
    id int,
    date date,
    json text, -- [{'secondOfDay': 0, 'value': 12.34}, {...} or BLOB
    PRIMARY KEY ((id, date))
) 
Run Code Online (Sandbox Code Playgroud)

3)宽行窄行多列

CREATE TABLE timeseries(
    id int,
    date date,
    "0" decimal, "1" decimal,"2" decimal, -- ... 86400 decimal values
                   -- each column index is the second of the day
    PRIMARY KEY ((id, date))
) 
Run Code Online (Sandbox Code Playgroud)
  • 单列上的插入(例如,一天中仅插入几秒钟)似乎使节点承受大量负载。也许在插入之前加载了整行?
  • 但确实很好的存储消耗
  • 如果一行未完全填满,则会触发墓碑警告:错误“在查询 'SELECT * FROM ...' 期间扫描了 100001 个墓碑”--> 这是不行的

Ash*_*lam 5

我建议您使用第一个数据模型。

您的第一个和第三个数据模型在 cassandra 的内部结构中是相似的。你对 cassandra 中宽行和窄行的理解是错误的。第一个数据模型是宽行,第二个和第三个数据模型是瘦行。

第一个数据模型内部结构:

{"key": "1:2017-06-09",
 "cells": [["2017-06-09 15\\:05+0600:","",1496999149885944],
           ["2017-06-09 15\\:05+0600:value","3",1496999149885944],
           ["2017-06-09 15\\:05+0600:","",1496999146862326],
           ["2017-06-09 15\\:05+0600:value","2",1496999146862326],
           ["2017-06-09 15\\:05+0600:","",1496999142150486],
           ["2017-06-09 15\\:05+0600:value","1",1496999142150486]]},
{"key": "1:2017-06-10",
 "cells": [["2017-06-09 15\\:06+0600:","",1496999171997567],
           ["2017-06-09 15\\:06+0600:value","4",1496999171997567]]}
Run Code Online (Sandbox Code Playgroud)

Cassandra 将分区 ( id, date) 键中的每个单元格存储到单个行中,并将聚类键 ( timestamp) 值存储为每个单元格的键。这就是为什么这个模型被称为宽行。

所以你可以看到第一个和第三个数据模型是相似的。因此,如果您使用第一个模型而不是第三个模型,则不必为值的每个条目创建新列

并且不要使用第二个模型,对于每个插入,您必须读取整个值并附加新值并再次重新插入。这是一个非常糟糕的设计,一种反模式。并且 cassandra 还建议将列值设置为 1 MB。

单列值不得大于2GB;实际上,“MB 的个位数”是一个更合理的限制,因为没有流或随机访问 blob 值。

来源:https : //wiki.apache.org/cassandra/Cas​​sandraLimitations

如果要减少磁盘空间,可以使用COMPACT STORAGE选项。下面的结果表明,紧凑型存储最多可减少 35% 的磁盘空间

在此处输入图片说明

来源:http : //blog.librato.com/posts/cassandra-compact-storage

笔记 :

  • 使用 WITH COMPACT STORAGE 指令可防止您定义多个不属于复合主键的列。主键不是复合的紧凑表可以有多个不属于主键的列。

  • 使用复合主键的紧凑表必须至少定义一个集群列。创建紧凑表后,不能添加或删除列。除非您指定 WITH COMPACT STORAGE,否则 CQL 创建一个具有非紧凑存储的表。

  • 集合和静态列不能与 COMPACT STORAGE 表一起使用。

来源:http : //docs.datastax.com/en/cql/3.3/cql/cql_using/useCompactStorage.html