先用一张映射表安顿下来
从 MySQL 世界过来的开发者,先拿映射表对号入座,能省一半的懵:
| MySQL | Elasticsearch | 备注 |
|---|---|---|
| 数据库 Database | 集群 Cluster | 对齐粒度不同,大致对应 |
| 表 Table | 索引 Index | 注意:不是 MySQL 的「索引」 |
| 行 Row | 文档 Document | JSON 格式 |
| 列 Column | 字段 Field | 每个字段自带正排+倒排 |
| 表结构 Schema | 映射 Mapping | 定义字段类型与分词器 |
| 分区 Partition | 分片 Shard | 水平切分,分布式的基础 |
最容易混的是 Index:在 MySQL 里它是 B+ 树结构,在 ES 里它是一张「表」。本系列说的 Index 一律指后者。
Document:一份 JSON 的自我修养
文档就是一个 JSON 对象,写进索引时会带上几个系统元数据:_id(文档唯一标识,可自定可生成)、_source(原始 JSON 的完整保存,查询时默认原样返回,update 和 reindex 也靠它)、_routing(路由值,决定文档落在哪个分片,默认取 _id)。老王的商品文档长这样:
POST /product/_doc/10086
{
"name": "燕麦拿铁(大杯)",
"category": "咖啡",
"price": 32.0,
"tags": ["燕麦", "新品"],
"stock": 200
}Shard:把一张表拆到多台机器
单机装不下、扛不住时就要水平切分。ES 的 Index 由多个主分片(Primary Shard)组成,每个主分片本质上是一个独立完整的 Lucene 实例——还记得第 2 篇的 FST 和倒排表吗?它们都活在分片里。三个分片的索引,一次查询会被拆成三个子查询并行打出去,再把结果归并——这就是 ES 天生并行的来源。
关键规则:主分片数量在建索引时确定,之后不能改。为什么改不了?看路由公式:
shard = hash(routing) % number_of_primary_shards文档去哪个分片由这个公式决定,分片数一变,所有已有文档的位置计算全部作废——文档找不到了。想改分片数只有两条路:reindex 到新索引,或用 split API 按倍数拆分。所以分片规划要在建索引前想清楚(第 14 篇专题)。
Replica:备份与读扩展一肩挑
副本分片(Replica Shard)是主分片的拷贝,两个职责:主分片所在节点挂掉时顶上(高可用),以及分担读请求(读扩展)。两条硬规则:
- 主副不可同节点:副本绝不分配到它的主分片所在的节点——否则节点一挂主副全灭,备份失去意义;
- 副本数可随时改:和主分片数不同,副本数不参与路由公式,大促前临时加副本扩读能力,过完再减回来,都是合法操作。
单节点集群可以建副本数,但副本无处安放,集群健康就是黄色——注意这个信号别当成故障瞎折腾。
集群健康的三色灯
| 颜色 | 含义 | 动作 |
|---|---|---|
| green | 主分片、副本分片全部就位 | 安心喝咖啡 |
| yellow | 主分片全在,部分副本没地方放 | 查节点数是否小于副本数 |
| red | 有主分片丢失,数据不可写不可查 | 立即排查,这是真故障 |
小结
概念地图一句话:文档进索引,索引拆分片,分片带副本,主副不同居。主分片数定死路由,副本数弹性伸缩,三色灯红黄绿分清轻重。世界观立好了,下一篇解决中文搜索的生死劫:分词器——标准分词器为什么把「燕麦拿铁」切成单字,IK 分词器怎么用。
评论 (0)