我是Cassandra的新手,我正在构建一个聊天应用程序。假设我必须将聊天消息存储在数据库中,我希望使用Cassandra,因为它允许快速写入。我的"消息"表的数据模型如下:
消息标识
发件人用户标识
收件人用户标识
通道标识
消息文本
现在,我想以某种方式将其进行分片,以便可以从单个分片访问特定频道(1:1或群聊)的聊天历史记录。因此,理想情况下,我希望根据channel_id对DB进行分片。以下是我面临的挑战:
1.我不能使"channel_id"成为分区键,因为它可以有重复项(一个通道可以有多个消息),而且如果分区键只由一列组成,Cassandra不允许重复项。
1.我可以使用"channel_id + message_id"作为分区键,这将是唯一的,但是Cassandra将对channel_id + message_id的组合进行散列,并且可以将来自同一个通道的消息放置在不同的分片上,所以我必须再次执行scatter gather。
以下是我的问题:
1.有没有办法覆盖Cassandra(或任何非关系数据库)的分区/分片逻辑?我可以编写自己的分区逻辑来决定我想在应用逻辑中写入的分片吗?我知道Redis允许客户端分区(参见此处)。Cassandra也允许这样的操作吗?
1.一般问题-通常,在设计系统时,我们会尝试将数据进行分片,以便最大限度地减少最频繁查询的分散收集机会。(和其他非关系数据库)不允许分区键重复,我们还能怎样实现这样设计呢?(* 请注意,使用多个列作为分区键不会因为Cassandra将散列这些列值的组合,并将它们放在不同的分片上,如上面的示例所示 )。
有人能帮助我理解如何最好地对此建模吗?如果我的理解有误,请纠正我。( 如前所述,我对Cassandra和一般的非关系数据库都是新手 *)
1条答案
按热度按时间qyzbxkaa1#
1.Cassandra划分
在Cassandra中,表的主键由两部分组成:* * 分区键**(可以是由一列组成的简单键,也可以是由多列组成的复合键)和可选的群集键(也称为排序键)。
分区键负责跨节点的数据分布,即决定"碎片"。
群集键负责分区内的数据排序。
示例:
在此示例中,* col_A * 和 * col_B * 的值确定分区,而 * col_C * 和 * col_D * 仍然是主键的一部分,但仅定义该分区内数据的顺序。
在您的示例中,可以将 * channel_id * 作为 * partition key *,然后将 * message_id * 作为 * clustering key *,它将对该分区(shard)中的记录进行排序。
表格可能如下所示:
示例数据:
1.自定义分区
基于分区键值确定服务器端数据放置的东西称为 * partitioner *,可以在服务器上的 * cassandra. yaml * 文件中配置。
基本上,分区器是一个函数,用于从分区键中导出表示行的令牌,通常是通过散列,然后每行数据根据令牌的值分布在集群中。
cassandra提供了以下可以在cassandra. yaml文件中设置的分区器。
您可以在这里阅读更多关于分区的信息:https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/architecture/archPartitionerAbout.html