1.2 集群概念地图:节点、分片与副本 本节摘要:集群(cluster)是节点的联盟,索引(index)被切成多个分片(shard)分散到节点上,每个主分片还可以拥有副本(replica)。本节把这五个名词放进同一张地图,讲清主分片数为什么建好就不能改、副本如何同时服务高可用与读扩展、节点角色怎样分工。理解这张地图,doc-1001 后续的每一次搬家才有坐标。 概念对齐:一张地图上的五个名词 上一节我们知道了引擎内部是一张倒排表。现在把镜头拉远——这张表物理上住在哪里?答案是:住在一个叫 Lucene 索引的结构里,而一个 Elasticsearch 分片,本质上就是一个完整的 Lucene 索引。
本节摘要:集群(cluster)是节点的联盟,索引(index)被切成多个分片(shard)分散到节点上,每个主分片还可以拥有副本(replica)。本节把这五个名词放进同一张地图,讲清主分片数为什么建好就不能改、副本如何同时服务高可用与读扩展、节点角色怎样分工。理解这张地图,doc-1001 后续的每一次搬家才有坐标。
上一节我们知道了引擎内部是一张倒排表。现在把镜头拉远——这张表物理上住在哪里?答案是:住在一个叫 Lucene 索引的结构里,而一个 Elasticsearch 分片,本质上就是一个完整的 Lucene 索引。于是地图可以这样画:

三个节点组成的集群里,tickets 索引设了 3 个主分片、每个 1 副本,共 6 个分片副本,被尽量打散到不同节点。node-1 同时持有 tickets 的主分片 P0 和 orders 的副本 R1——副本永远不与自己的主分片同节点,否则一台机器掉电就同时失去正本和备份。
一个节点进程可以同时扮演多个角色,分工如下:
| 角色 | 干什么 | 不干什么 |
|---|---|---|
| master 候选 | 参与选举、维护集群元数据(有哪些索引、分片在哪) | 不处理文档读写 |
| data 节点 | 存储分片、执行写入与查询 | 不参与集群决策 |
| ingest 节点 | 写入前对文档做预处理(补字段、改格式) | 不存储数据 |
| 协调节点 | 接收任意请求、分发到相关分片、汇总返回 | 任何节点都能兼任 |
生产集群常见两种形态:小集群人人兼职(默认每个节点都是 master 候选加 data);大集群则分离出专职 master 候选(3 或 5 个)只管元数据,data 节点专心搬数据。协调是最容易被忽视的角色——一次搜索要扇出到所有涉及分片,协调节点负责收集、归并、排序,大结果集时它的 CPU 与内存先扛不住。
这是新手最常踩的坑,值得单独说透。写入一条文档时,引擎按公式决定它去哪个分片(第 4 章会推导),公式的输入是分片总数:
{ "路由公式(概念说明)": { "输入": ["文档id", "索引名", "主分片数"], "计算": "hash(文档id) 对 主分片数 取余", "例子": "hash(doc-1001)=37, 主分片数=3, 37 mod 3 = 1, 落入P1" } }
假如建成后把 3 个主分片改成 5,老文档仍按 3 计算出的位置存放,新查询按 5 去找——大量文档将永远查不到。所以主分片数是一次性决定;数据涨了怎么办?常规做法是建新索引、迁数据、用别名切换,第 3 章的别名机制就是为这种平滑扩容准备的。副本数则随时可调,因为路由只看主分片数。
想增减容量时,用设置请求调整副本数即可:
PUT tickets/_settings { "number_of_replicas": 2 }
读流量涨了加副本(更多分片参与查询),磁盘吃紧减副本——代价与收益都是即时的。
⚠️ 常见坑:单节点集群把副本数设为 1,集群永远显示黄色。因为副本无处安放(不能与主分片同节点),这不是故障,是分配策略在起作用。本地实验时把副本设为 0 即可转绿。
| 考核点 | 达标标准 |
|---|---|
| 五名词分层 | 集群、节点、索引、主分片、副本的包含关系一条不乱 |
| 分片即索引 | 说出"一个分片就是一个 Lucene 索引"对理解存储与恢复的意义 |
| 副本隔离 | 解释副本为什么不与自己的主分片同节点,以及它带来的高可用 |
| 主分片不可改 | 用路由公式的取余推导改数后老文档"失踪" |
| 副本随时调 | 写出调整副本数的设置请求,说明读扩展的收益方向 |
| 角色分工 | 四种角色各自干什么、不干什么,大集群如何专责化 |
第 2 章环境就绪后,两条目录接口把这张地图变成可见的事实:
GET _cat/indices/tickets?v # 每行一个索引 pri 列是主分片数 rep 列是副本数 docs.count 是文档量 GET _cat/shards/tickets?v # 每行一个分片 prirep 区分主副本 state 给出状态 node 给出宿主节点
把副本数从零调到一再查分片目录:单节点上副本行停在未分配,"副本无处安放"从结论变成亲测。再起一个节点组成双节点集群,副本行转正的同时宿主列换成另一个节点名——隔离规则被引擎原样执行了一遍,地图的每个箭头都落到了实处。
地图画好了,住进容器里的是 JSON 文档模型——它和关系表之间有一段恩怨要交代。