我目前有一个应用程序,它将事件驱动的实时流数据保存到列族中,该列族建模如下:
CREATE TABLE current_data (
account_id text,
value text,
PRIMARY KEY (account_id)
)
每个accountId每隔X秒发送一次数据,因此我们每次收到事件时都会覆盖现有行.这些数据包含当前的实时信息,我们只关心最近的事件(不使用旧数据,这就是我们插入现有密钥的原因).
从应用程序用户端 – 我们通过account_id语句查询select.
我想知道是否有更好的方法来模拟这种行为,并且正在考虑Cassandra的最佳实践和类似问题(How to model Cassandra DB for Time Series, server metrics).
想到这样的事情:
CREATE TABLE current_data_2 (
account_id text,
time timeuuid,
value text,
PRIMARY KEY (account_id, time) WITH CLUSTERING ORDER BY (time DESC)
)
不会发生覆盖,每次插入也将使用TTL(可以是几分钟的TTL)完成.
问题是,如果有的话,第二个数据模型比第一个更好.根据我的理解,主要优势将在READS中 – 因为数据是按时间排序的,所以我需要做的只是一个简单的
SELECT * FROM metrics WHERE account_id = <id> LIMIT 1
而在第一个数据模型中,Cassandra实际读取覆盖相同密钥的所有行,然后通过其写时间戳选择最后一行(如果我错了,请纠正我).
谢谢.
最佳答案 首先,我建议您查看有关
read path.的官方文档
data is ordered by time
这只适用于第二种情况,当Cassandra读取单个SSTable和MemTable时(请查看流程图).
Cassandra actually reads ALL rows that where overwritten the same key
and then chooses the last one by its write timestamp
这发生在文档中的“按时间戳合并单元格”步骤中(再次检查流程图).请注意,在每个SSTable中,第一种情况下的行数将为1.
在两种情况下,主要驱动因素是您在读取期间需要检查多少SSTable.它与每个SSTable包含的记录数有些独立.
但在第二种情况下,你有更大的SSTabes,导致更长的SSTable压缩. TTL到期也执行额外写入.所以第一种情况有点可取.