用于实时数据的 Cassandra 数据建模

Cassandra data modeling for real time data

我目前有一个应用程序将事件驱动的实时流数据持久保存到列族,该列族的建模方式如下:

CREATE TABLE current_data (
    account_id text, 
    value text,
    PRIMARY KEY (account_id)
)

每个 accountId 每 X 秒发送一次数据,因此我们每次收到事件时都会覆盖现有行。此数据包含当前的实时信息,我们只关心最近的事件(旧数据没有用,这就是我们插入现有密钥的原因)。 从应用程序用户端 - 我们通过 account_id 语句查询 select。

我想知道是否有更好的方法来模拟这种行为,并且正在研究 Cassandra 的最佳实践和类似的问题 ()。

想过这样的事情:

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)。

问题是第二个数据模型比第一个更好,如果有的话。据我了解,主要优势在于读取 - 因为数据是按时间排序的,所以我需要做的只是一个简单的

SELECT * FROM metrics WHERE account_id = <id> LIMIT 1

而在第一个数据模型中,Cassandra 实际上读取了覆盖相同键的所有行,然后通过其写入时间戳选择最后一个(如果我错了请纠正我)。

谢谢。

首先,我建议您查看有关 read path.

的官方文档

data is ordered by time

这仅在第二种情况下是正确的,当 Cassandra 读取单个 SSTableMemTable(检查流程图)时。

Cassandra actually reads ALL rows that where overwritten the same key and then chooses the last one by its write timestamp

这发生在文档中的按时间戳合并单元格步骤(再次检查流程图)。请注意,在第一种情况下,每个 SSTable 的行数都是一个。

在这两种情况下,主要驱动因素是在读取过程中必须检查多少个 SSTable。它在某种程度上独立于每个 SSTable 包含的记录数。

但是在第二种情况下,您有更大的 SSTabes,这会导致更长的 SSTable 压缩。此外,TTL 过期会执行额外的写入操作。所以第一种情况更可取。