---
title: "分布式基础"
date: 0001-01-01
description: "集群扩容、分片分配、故障转移——Easysearch 的分布式架构实战。"
summary: "分布式基础 #  Easysearch 的主旨是随时可用和按需扩容。真正的扩容能力来自于水平扩容——为集群添加更多的节点，并且将负载压力和稳定性分散到这些节点中。Easysearch 天生就是分布式的，它知道如何通过管理多节点来提高扩容性和可用性。
本页通过从 1 节点到 3 节点的演进，直观展示分片分配、故障转移和水平扩容的过程。
空集群 #  启动一个单独的节点，里面不包含任何数据和索引——这就是一个空集群。
此时这个节点既是唯一的数据节点，也是主节点。作为用户，我们可以将请求发送到集群中的任何节点（包括主节点），每个节点都知道任意文档所处的位置，并能将请求直接转发到正确的节点。
集群健康 #  Easysearch 的集群监控信息中最重要的一项是集群健康，status 字段展示为 green、yellow 或 red：
GET /_cluster/health    颜色 含义     green 所有的主分片和副本分片都正常运行   yellow 所有的主分片都正常运行，但不是所有的副本分片都正常运行   red 有主分片没能正常运行    添加索引 #  索引是指向一个或者多个物理分片的逻辑命名空间。一个分片是一个底层的工作单元，它本身就是一个完整的搜索引擎（一个 Lucene 实例）。
Easysearch 利用分片将数据分发到集群内各处。当集群规模扩大或缩小时，Easysearch 会自动在各节点间迁移分片，使数据均匀分布。
让我们创建一个名为 blogs 的索引，分配 3 个主分片和 1 份副本：
PUT /blogs { &#34;settings&#34; : { &#34;number_of_shards&#34; : 3, &#34;number_of_replicas&#34; : 1 } } 此时只有一个节点，3 个主分片都分配在该节点上。集群健康状态为 yellow——主分片正常，但 3 个副本分片无处分配（在同一节点上保存原始数据和副本没有意义）。"
---


# 分布式基础

Easysearch 的主旨是随时可用和按需扩容。真正的扩容能力来自于水平扩容——为集群添加更多的节点，并且将负载压力和稳定性分散到这些节点中。Easysearch 天生就是分布式的，它知道如何通过管理多节点来提高扩容性和可用性。

本页通过从 1 节点到 3 节点的演进，直观展示分片分配、故障转移和水平扩容的过程。

## 空集群

启动一个单独的节点，里面不包含任何数据和索引——这就是一个空集群。

此时这个节点既是唯一的数据节点，也是主节点。作为用户，我们可以将请求发送到集群中的任何节点（包括主节点），每个节点都知道任意文档所处的位置，并能将请求直接转发到正确的节点。

## 集群健康

Easysearch 的集群监控信息中最重要的一项是**集群健康**，`status` 字段展示为 `green`、`yellow` 或 `red`：

```json
GET /_cluster/health
```

| 颜色 | 含义 |
|------|------|
| `green` | 所有的主分片和副本分片都正常运行 |
| `yellow` | 所有的主分片都正常运行，但不是所有的副本分片都正常运行 |
| `red` | 有主分片没能正常运行 |

## 添加索引

索引是指向一个或者多个物理分片的逻辑命名空间。一个分片是一个底层的工作单元，它本身就是一个完整的搜索引擎（一个 Lucene 实例）。

Easysearch 利用分片将数据分发到集群内各处。当集群规模扩大或缩小时，Easysearch 会自动在各节点间迁移分片，使数据均匀分布。

让我们创建一个名为 `blogs` 的索引，分配 3 个主分片和 1 份副本：

```json
PUT /blogs
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}
```

此时只有一个节点，3 个主分片都分配在该节点上。集群健康状态为 `yellow`——主分片正常，但 3 个副本分片无处分配（在同一节点上保存原始数据和副本没有意义）。

## 添加故障转移

启动第二个节点后，3 个副本分片将被分配到新节点上——每个主分片对应一个副本分片。这意味着任何一个节点出现问题时数据都完好无损。

集群健康变为 `green`：所有 6 个分片都正常运行。

所有新索引的文档都会先保存在主分片上，然后被并行复制到对应的副本分片。

## 水平扩容

启动第三个节点后，分片会被重新分配。`Node 1` 和 `Node 2` 上各有一个分片被迁移到 `Node 3`，现在每个节点上只有 2 个分片（而不是之前的 3 个），每个分片能获得更多的硬件资源，性能得到提升。

拥有 6 个分片（3 个主 + 3 个副本）的索引可以最大扩容到 6 个节点，每个节点只承载一个分片。

### 更多的扩容

主分片的数目在索引创建时就已确定。但读操作可以同时被主分片和副本分片处理，所以副本越多、硬件越多，可并行处理的搜索请求也越多。

在运行中的集群上可以动态调整副本分片数目：

```json
PUT /blogs/_settings
{
   "number_of_replicas" : 2
}
```

此时 `blogs` 索引将拥有 9 个分片：3 个主分片和 6 个副本分片。

> ⚠️ 只在相同节点数目的集群上增加副本并不能提高性能（每个分片分到的资源更少了）。需要增加硬件资源来提升吞吐量。但更多的副本确实提高了数据冗余量。

## 应对故障

当某个节点出现故障时：

1. 主节点立即将该节点上的主分片对应的副本提升为主分片（瞬间完成）
2. 集群状态变为 `yellow`（主分片齐全，但副本不足）
3. 如果有其他节点可用，新的副本会被分配出去

如果只剩一个节点且有主分片丢失，集群状态变为 `red`。

## 分布式特性

Easysearch 在分布式方面几乎是透明的。以下操作都在后台自动完成：

- 分配文档到不同的分片中，文档可以储存在一个或多个节点中
- 按集群节点来均衡分配分片，对索引和搜索过程进行负载均衡
- 复制每个分片以支持数据冗余，防止硬件故障导致的数据丢失
- 将集群中任一节点的请求路由到存有相关数据的节点
- 集群扩容时无缝整合新节点，重新分配分片以便从离群节点恢复

## 小结

| 概念 | 要点 |
|------|------|
| 主分片 | 负责写入，数量在索引创建时确定 |
| 副本分片 | 提供冗余和读扩展，数量可动态调整 |
| 集群健康 | green/yellow/red 三色表示集群状态 |
| 水平扩容 | 增加节点 → 分片自动重新分配 |
| 故障转移 | 副本自动提升为主分片，瞬间完成 |

下一步可以继续阅读：

- [分布式写入过程]({{< relref "./distributed-write.md" >}})：文档路由、主副本交互、mget/bulk 执行路径
- [分布式搜索执行过程]({{< relref "./distributed-search.md" >}})：query/fetch 两阶段
- [写入与存储机制]({{< relref "./write-and-storage.md" >}})：refresh、flush、merge 详解

