好的 Cassandra table 结构

Good Cassandra table structure

我有两列,即 UserId(128 个字符)和数据(100 个字符)。 查询,

Select data from SimpleTable where user_guid = 'xyzabc123457789sda',

将其存储在 cassandra 中的简单 table 结构为:

class SimpleTable(Model):
    user_id = columns.Ascii(primary_key=True)
    data = columns.Ascii()

如果我有 1000 万用户,那么我将有 1000 万个分区,这通常不是问题。但是,还有一个替代版本:

class SimpleTable(Model):
    bucketid = int(primary_key=True, partition_key=True)
    user_id = columns.Ascii(primary_key=True)
    data = columns.Ascii()

现在,如果我对 bucketid 进行客户端级抽象,即固定允许的最大桶数并根据 user_id 的前 n 位的哈希值计算 bucketid,我的分区数量有限,并且这种方法的巨大优势在于,现在我可以使用未记录的批处理优化对 table 的写入(更少的网络开销,更快的写入(可能)),因为我可以使用 bucketid 为大量用户批量写入请求。 假设集群中有 10 个节点,最大桶数为 1024,有 1000 万用户,即每个分区大约有 1 万个用户。理论上我基本上可以为 10k 用户批量写入。 (批处理的好数字要低得多) 读取还是一样,只是需要像这样计算bucketid:

Select data from SimpleTable where bucketid = '999' and 'user_id' = 'xyzabc123457789sda'

第二种方法对我来说似乎是个不错的方法,但我是不是漏掉了什么? 我是否认为唯一的权衡是计算 bucketId 和使用 cassandra 批处理进行写入?

要考虑的另一件事是分区的大小限制。 Cassandra 的硬限制为每个分区(数据)2GB 和每个分区 20 亿个单元格(列)。这就是为什么随着时间的推移分区增长会成为一个问题。

最常见的“时间证明”方法是按时间“分桶”。幸运的是,你似乎对这个概念很满意。唯一的区别是“时间桶”只是使用时间组件(月、周等)作为复合分区键,而不仅仅是 bucketid。需要考虑的事情。

基本上,如果您的 data 列很小并且永远不会超过 10k rows/partition,您的“分桶”解决方案应该没问题。