1833 字
约 6 分钟
1
Cassandra 分区键:是什么、有什么作用、如何选型?

Cassandra 分区键:是什么、有什么作用、如何选型?

一句话总结

分区键(Partition Key)决定一条数据被存到 Cassandra 集群里的哪个节点上——它是 Cassandra 分布式存储的"路由地址"。

一个类比:快递分拣中心

把 Cassandra 集群想象成全国快递网络,每个节点是一个分拣中心。

  • 快递员收件时看邮编(分区键)→ 决定包裹发往哪个分拣中心(节点);
  • 到了分拣中心后,包裹按货架编号(聚类键)摆放,方便快速取出;
  • 你要查一个包裹,只需要报出邮编,快递系统直接定位到对应中心,不用全国每个中心都翻一遍。

所以:分区键 = 邮编,聚类键 = 货架号。

一、分区键是什么

Cassandra 的表结构和 MySQL 最大的区别是:主键不是随便定的,它直接决定了物理存储布局。

CREATE TABLE notes_by_user (
    user_id    uuid,        -- 分区键
    created_at timestamp,   -- 聚类键
    note_id    uuid,        -- 聚类键
    content    text,
    PRIMARY KEY (user_id, created_at, note_id)
);

规则:PRIMARY KEY 的第一个(组)字段就是分区键,其余是聚类键(Clustering Key)。

  • PRIMARY KEY (a) → 分区键是 a,没有聚类键;
  • PRIMARY KEY (a, b, c) → 分区键是 a,聚类键是 b、c;
  • PRIMARY KEY ((a, b), c) → 复合分区键是 (a, b),聚类键是 c(注意双重括号)。

写数据时,Cassandra 对分区键做哈希,得到一个 token 值,token 落在哪个节点的 token 范围内,数据就存到哪个节点(并同步到副本)。同一分区键的所有行,永远存储在同一组节点上,物理上挨在一起。

二、分区键的作用

作用 说明 类比
① 数据分布(负载均衡) 分区键哈希决定数据落在哪个节点,让数据均匀铺满集群 包裹按邮编分到不同中心,避免一个中心爆仓
② 数据定位(查询路由) 查询带分区键,直接定位节点,不用全集群扫描 报邮编直接锁定分拣中心
③ 物理局部性 同一分区键的行存在一起,按聚类键排序,一次读整个分区 = 一次高效顺序读 同一邮编的包裹放同一货架区
④ 副本放置 分区键的 token 决定主副本和 RF 个副本落在哪些节点,这是容错的基础 同邮编包裹在多个中心各留一份备份
⑤ 水平扩展依据 集群加节点时,按 token 范围重新分配分区 新增一个分拣中心,邮编区间重新划分

反过来看它的"代价":查询如果不带分区键,Cassandra 就不知道数据在哪,只能全集群扫(ALLOW FILTERING,性能灾难)。这是 Cassandra 和 MySQL 最根本的思维差异——先想清楚怎么查,再定主键。

三、如何选择分区键(核心方法)

第 1 步:列出业务的核心查询模式

Cassandra 的设计准则是 "查询驱动建模"(Query-First Design)。先问:我的查询永远会带哪个字段的等值条件?

  • 笔记应用:查"某个用户的笔记列表" → 分区键 user_id;
  • 物联网:查"某个设备某段时间的数据" → 分区键 device_id,聚类键 timestamp;
  • 订单系统:查"某个用户的订单" → 分区键 user_id。

第 2 步:检查这个字段的"基数"和"分布均匀性"

分区键的取值必须又多又均匀,否则会形成热点:

  • ❌ 用 status(只有"待处理/处理中/完成"3 个值)做分区键 → 所有数据挤在 3 个节点上,集群 100 台也白搭;
  • ✅ 用 user_id、device_id 这类基数大、天然均匀的字段。

判断口诀:取值越分散越好,越"热门"越危险。

第 3 步:控制分区大小(别让一个分区无限膨胀)

一个分区的物理上限约 2GB(硬限制),生产上建议单个分区 < 100MB、行数 < 10 万。分区太大会导致:单节点压力大、读写超时、无法扩展。

两个典型解法:

① 时间桶(Time Bucketing)——把无限增长的分区切成小段:

-- 按天分桶:每天一个分区
PRIMARY KEY ((device_id, day), timestamp)
-- 写入时 day = '2026-10-08',分区永远只有一天的数据

② 复合分区键——用多个字段组合定位:

-- 用 (user_id, year) 避免单用户多年数据撑爆一个分区
PRIMARY KEY ((user_id, year), created_at)

第 4 步:确认"同一分区内要一起读的数据"放一起

需要一次查出来的数据,分区键必须相同。比如"一篇笔记的正文 + 全部评论",都挂同一个 note_id 分区,一次查询就全拿到了。

四、常见误区(踩坑清单)

  • ❌ 分区键选唯一性过强的字段(如给每行一个 UUID 当分区键)→ 每行一个分区,无法批量读,分区数量爆炸,得不偿失;
  • ❌ 分区键是常量(如 PRIMARY KEY (1, ...))→ 所有数据进一个分区,集群形同虚设;
  • ❌ 查询不带分区键 → 全集群扫描,性能灾难;
  • ❌ 分区键选完才发现不够均匀 → 分区键无法通过 ALTER 修改,只能重建表迁移数据,所以选型要慎重;
  • ❌ 忘了聚类键的顺序:聚类键决定分区内排序,(created_at, note_id) 和 (note_id, created_at) 查询能力完全不同,要按"范围查询最常用的字段在前"来排。

五、选择分区键的决策清单

  1. 查询驱动:我的最高频查询,固定用哪个字段做等值过滤?→ 它大概率是分区键;
  2. 基数大且均匀:这个字段取值够分散、没有明显的"爆款值"吗?
  3. 分区别太大:单分区预估 < 100MB / 10 万行吗?不行就上时间桶或复合分区键;
  4. 一次查询要读的数据:是不是都放进了同一个分区?
  5. 想清楚再定:分区键定了基本改不了,先建模验证再上线。

六、总结

  • 分区键 = "数据放哪 + 查询找哪"的钥匙,选对了,集群性能飞起;选错了,100 台节点也救不回来;
  • 分区键的五大作用:数据分布、查询路由、物理局部性、副本放置、水平扩展依据;
  • 选型四步:查询驱动 → 检查基数均匀性 → 控制分区大小 → 同读数据放同分区;
  • 警惕四大坑:唯一性过强、常量分区键、查询不带分区键、分区键无法 ALTER 修改。

Cassandra 圈子里有句老话:"先写查询,再建表"——理解了这句话,你就理解了分区键的本质。

Cassandra 分区键:是什么、有什么作用、如何选型?
https://www.clxhxhhr.top/posts/4587/
作者
clxstart
发布于
2026-10-08
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。