如何在Cassandra中实现自定义分区逻辑?

ivqmmu1c  于 2023-03-08  发布在  Cassandra
关注(0)|答案(1)|浏览(218)

我是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和一般的非关系数据库都是新手 *)

qyzbxkaa

qyzbxkaa1#

1.Cassandra划分
在Cassandra中,表的主键两部分组成:* * 分区键**(可以是由一列组成的简单键,也可以是由多列组成的复合键)和可选的群集键(也称为排序键)。
分区键负责跨节点的数据分布,即决定"碎片"。
群集键负责分区内的数据排序。
示例:

create table example (
  col_A text,
  col_B text,
  col_C text,
  col_D text,
  col_E text,
  col_F text,
  PRIMARY KEY((col_A, col_B), col_C, col_D)      
);

在此示例中,* col_A * 和 * col_B * 的值确定分区,而 * col_C * 和 * col_D * 仍然是主键的一部分,但仅定义该分区内数据的顺序。
在您的示例中,可以将 * channel_id * 作为 * partition key *,然后将 * message_id * 作为 * clustering key *,它将对该分区(shard)中的记录进行排序。
表格可能如下所示:

CREATE TABLE messages (
  channel_id text,
  message_id text,
  from_user_id text,
  message_text text,
  to_user_id text,
  PRIMARY KEY (channel_id, message_id)
) WITH CLUSTERING ORDER BY (message_id ASC)

示例数据:

select * from messages;

 channel_id | message_id | from_user_id | message_text | to_user_id
------------+------------+--------------+--------------+------------
          1 |        m-1 |          u-1 |          foo |        u-2
          1 |        m-2 |          u-2 |          bar |        u-1
          2 |        m-1 |         u-11 |      foo bar |       u-10
          2 |       m-10 |         u-10 |          bar |       u-11
          2 |       m-11 |         u-11 |          foo |       u-10

select * from messages where channel_id = '1';

 channel_id | message_id | from_user_id | message_text | to_user_id
------------+------------+--------------+--------------+------------
          1 |        m-1 |          u-1 |          foo |        u-2
          1 |        m-2 |          u-2 |          bar |        u-1

1.自定义分区
基于分区键值确定服务器端数据放置的东西称为 * partitioner *,可以在服务器上的 * cassandra. yaml * 文件中配置。
基本上,分区器是一个函数,用于从分区键中导出表示行的令牌,通常是通过散列,然后每行数据根据令牌的值分布在集群中。
cassandra提供了以下可以在cassandra. yaml文件中设置的分区器。

  • Murmur3分区程序(默认):基于MurmurHash散列值在群集上均匀分布数据。
  • 随机分配器:基于MD5哈希值在群集中均匀分布数据。
  • 字节有序分区程序:按关键字节保持数据在词汇上的有序分布

您可以在这里阅读更多关于分区的信息:https://docs.datastax.com/en/cassandra-oss/3.x/cassandra/architecture/archPartitionerAbout.html

相关问题