当前位置: 首页 > 知识库问答 >
问题:

Cassandra:低基数分区

夹谷和韵
2023-03-14

假设我有一张桌子,像这样:

CREATE TABLE Users (
  user UUID,
  seq INT,
  group TEXT,
  time BIGINT,
  PRIMARY KEY ((user), seq)
);

这遵循了所需的Cassandra模式,跨分区分布良好(假设默认的Murmur3哈希分区器)。

但是,我也需要(很少)按时间顺序执行范围查询。这在Cassandra中似乎是不可能的。实际上,我确实需要按组访问数据,所以(group, time)是可以接受的。由于似乎没有办法让辅助索引有多个列,我想正确的做法是将其反规范化,如下所示:

CREATE TABLE UsersByGroupTime (
  user UUID,
  seq INT,
  group TEXT,
  time BIGINT,
  PRIMARY KEY ((group), time)
) WITH CLUSTERING ORDER BY (time ASC);

除了< code>group基数很低,比方说< code>('A ',' B ',' C'),并且在用户之间分布不均匀之外,这完全按照它应该的方式工作。由于对该表的查询很少,所以我不担心热节点,但我担心不均匀的分布,甚至可能是单个节点得到全部。

这是一种常见的情况吗?有没有办法缓解这种情况,或者有其他解决方案?

共有1个答案

牟稳
2023-03-14

帮助避免卡桑德拉时间序列模型中出现热点的一种技术是使用“时间桶”。从本质上讲,您要做的是确定“快乐中等”水平的时间精度,该水平提供了足够的数据分布,同时也是已知的和半方便查询的。

出于这个示例的目的,我将选择年和月(“yyyyMM”)。注意:我不知道年和月对你是否合适...这只是一个例子。一旦您确定了您的时段,您可以将它添加为一个附加的分区键,如下所示:

CREATE TABLE UsersByGroupTime (
  user UUID,
  seq INT,
  group TEXT,
  time TIMEUUID,
  yearmonth BIGINT,
  PRIMARY KEY ((group, yearmonth), time)
) WITH CLUSTERING ORDER BY (time DESC);

插入一些行后,类似这样的查询将会起作用:

aploetz@cqlsh:stackoverflow2> SELECT group, yearmonth, dateof(time), time, seq, user 
FROM usersbygrouptime WHERE group='B' AND yearmonth=201505;

 group | yearmonth | dateof(time)             | time                                 | seq | user
-------+-----------+--------------------------+--------------------------------------+-----+--------------------------------------
     B |    201505 | 2015-05-16 10:04:10-0500 | ceda56f0-fbdc-11e4-bd43-21b264d4c94d |   1 | d57ba8a4-db24-440c-a983-b1dd6b0d2e27
     B |    201505 | 2015-05-16 10:04:09-0500 | ce1cac40-fbdc-11e4-bd43-21b264d4c94d |   1 | 66d07cbb-a2ff-4d56-8fa1-14dfaf684474
     B |    201505 | 2015-05-16 10:04:08-0500 | cd525760-fbdc-11e4-bd43-21b264d4c94d |   1 | 07b589ac-4d5f-401e-a34f-e3479e269e01
     B |    201505 | 2015-05-16 10:04:06-0500 | cc76c470-fbdc-11e4-bd43-21b264d4c94d |   1 | 984f85b5-ea58-4cf8-b512-43abacb227c9

(4 rows)

现在,这可能会也可能不会帮助您进行查询,因此您需要花一些时间来确保选择适当的时间范围。但是,这在环中的数据分布方面确实有帮助,您可以通过令牌函数看到这一点:

aploetz@cqlsh:stackoverflow2> SELECT group, yearmonth, token(group,yearmonth)
FROM usersbygrouptime ;

 group | yearmonth | token(group, yearmonth)
-------+-----------+-------------------------
     A |    201503 |    -3784784210711042553
     A |    201504 |     -610775546464185720
     B |    201505 |     6232834565276653514
     B |    201505 |     6232834565276653514
     B |    201505 |     6232834565276653514
     B |    201505 |     6232834565276653514
     A |    201505 |     8281745497436252453
     A |    201505 |     8281745497436252453
     A |    201505 |     8281745497436252453
     A |    201505 |     8281745497436252453
     A |    201505 |     8281745497436252453
     A |    201505 |     8281745497436252453

(12 rows)

请注意如何为每个组/年月对生成不同的令牌,即使其中一些具有相同的组(“A”)。

 类似资料:
  • null 火花:1.3 卡桑德拉:2.1 连接器:1.3.1 火花节点(5)和CASS*集群节点(4)运行在不同的数据中心 代码提取。请使用以上链接下载代码以获取更多详细信息 步骤1:将数据加载到8个spark分区中 加载Rdd值

  • 作为卡桑德拉数据分区的后续,我得到了vNodes的想法。感谢“西蒙·丰塔纳·奥斯卡森” 当我尝试使用vNodes进行数据分区时,我有几个问题, 我尝试观察2节点中的分区分布() 因此,根据我在两个节点中的观察,随着一个范围的扩展,节点61的值从-9207297847862311651到-9185516104965672922。。。 注意:分区范围从9039572936575206977到90199

  • 我理解了与Cassandra分区键、复合键、集群键的区别。但是没有找到足够的信息来理解cassandra中如何处理分区 在cassandra中,分区密钥的范围像分区/碎片一样存储在节点上。我的理解是否正确 每个分区键在数据库中是否有不同的文件(在系统级别)。。?如果是这样的话,读取速度不是会变慢吗 如果每个分区键在数据库中没有不同的文件。怎么处理的。。?

  • 我正在尝试使用cassandra实现分页,但我在Stackoverflow上没有得到任何成功的解决方案。我遇到的突出错误是“对第一个页面以外的页面进行分页查询需要具有有效分页状态的CassandraPageRequest”。请协助。

  • 有人知道如何在Spring Data Cassandra中实现分页吗? 我已经尝试了所有可能的方法来实现表的分页。其中一个stackoverflow答案说它不是直接提供的。在Spring Boot应用程序中对Cassandra中的SELECT查询结果进行分页 根据文档(https://docs.spring.io/spring-data/cassandra/docs/current-snapsho

  • 我正在使用带有datastax驱动程序的Cassandra数据库。我需要从Cassandra批量读取2000行的内容。我的用例是,我在请求中获取id列表,这些id是我在Cassandra中的分区键。我想知道生成2000个线程并从Cassandra并行获取数据是否是个好主意(在这种情况下,读取数据将有效,因为它只到达一个节点),或者是否有可能找到一种方法来对存在于同一节点中的id进行分组,以便我可以