# 高可用性

您可以通过运行 Typesense 节点集群来实现高可用性。 Typesense 使用 Raft 共识算法来管理集群并从节点故障中恢复。

在集群模式下,Typesense 会自动且持续地将整个数据集复制到集群中的所有节点。 读写 API 请求可以发送到集群中的任意节点 - 读请求将由接收到的节点直接处理,写请求会在内部自动转发到集群的 leader 节点。

由于 Raft 算法需要达成法定人数(quorum)才能形成共识,您需要运行至少 3 个节点才能容忍 1 个节点故障。运行 5 节点集群可以容忍最多 2 个节点故障,但会略微增加写入延迟。

# Typesense Cloud 中的高可用性

Typesense Cloud (opens new window) 中,我们为您管理高可用性。

当您在启动集群时开启高可用性设置后,除了单个主机名外,您还将在集群仪表板中看到一个特殊的负载均衡端点*:

Typesense Cloud HA 主机名

发送到负载均衡端点的请求会在集群中的所有 3 个节点之间分配。 如果某个节点出现基础设施问题或因任何原因无法访问,它将自动被隔离,流量将重新路由到其他健康的节点。

注意

您只能在 2022 年 6 月 16 日之后 配置的 HA 集群中看到负载均衡端点。

对于 2022 年 6 月 16 日之前 配置的 HA 集群,您只能看到单个主机名。健康检查和流量重路由是在我们官方客户端库中通过客户端完成的。 请参阅下面的 客户端配置

要在现有集群上启用服务器端负载均衡,请打开集群仪表板,进入集群配置,选择修改,切换开启负载均衡,并安排更改。 之后,按照下面 客户端配置 中的说明,配置您的客户端库使用 nearestNode 参数。

# 自托管 Typesense 时的高可用性

# 配置 Typesense 集群

要将 Typesense 节点作为集群的一部分启动,需在每个集群节点上创建一个新文件,文件格式如下,并使用 --nodes 服务器配置 指向该文件。

文件中的每个节点定义应采用以下格式,用逗号分隔:

<peering_address>:<peering_port>:<api_port>

peering_addresspeering_portapi_port 应与每个节点启动 Typesense 进程时使用的 服务器配置参数 相匹配。

出于安全考虑,集群中的所有节点应使用相同的引导 --api-key

# 节点文件示例

以下是一个 3 节点集群的 --nodes 文件示例:

在上例中:

  • peering_address(用于集群操作的 IP 地址)为 192.168.12.x
  • peering_port(用于集群操作的端口)为 8107
  • api_port(客户端实际连接的端口)为 8108

以下是每个节点启动 Typesense 进程的对应命令:

重要提示

  • --peering-address 应该是一个私有 IP 地址,因为它仅用于内部集群操作,并且包含节点之间交换的未加密 Raft 数据。

  • --api-address 可以是公共或私有 IP 地址。这是最终用户/客户端连接以与 Typesense API 交互的 IP 地址。

  • 在生产环境中,我们强烈建议将 --api-port 设置为 443 (HTTPS),并使用 --ssl-certificate--ssl-certificate-key 服务器参数配置 SSL 证书。

提示

如果您使用 Docker,请确保已配置 Docker 网络,使 Docker 容器内的 Typesense 进程能够使用 IP 地址与其他 Typesense 进程通信。 了解更多关于 Docker 网络 (opens new window)的信息。

# 验证集群形成

当您设置完集群中的所有节点后,可以通过向每个节点的 /debug 端点发送 GET 请求来验证它们是否成功形成了集群:

curl "http://${TYPESENSE_HOST}/debug/" \
        -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"

在其中一个节点上,您应该会看到以下响应:

{
  "state": 1,
  "version": "x.x.x"
}

其中 state: 1 表示该节点被选举为领导者。

所有其他节点应返回以下响应:

{
  "state": 4,
  "version": "x.x.x"
}

其中 state: 4 表示该节点被选为跟随者。

如果在多个节点上看到 state: 1,则表明集群未正确形成。检查 Typesense 日志(通常在 /var/log/typesense/typesense.log 中)以获取更多诊断信息。确保节点可以在您配置的 HTTP 端口和对等端口上相互通信。

如果您看到的值不是 state: 4state: 1,则表示出现了错误。检查 Typesense 日志(通常在 /var/log/typesense/typesense.log 中)以获取更多诊断信息。

# 恢复单个故障节点

当运行高可用的 Typesense 集群时,如果其中一个节点出现故障,恢复过程非常简单:

  1. 如果 Typesense 进程仍在运行,请停止它
  2. 清除故障节点上的数据目录
  3. 在该节点上重新启动 Typesense 服务

该节点将自动从集群中其他健康的节点同步所有必要数据。 Typesense 内置的复制机制将确保您恢复的节点与数据的当前状态保持一致。

TIP

对于这种情况,无需执行任何手动快照操作或恢复备份。让 Typesense 处理同步既更快又更可靠。

# 恢复失去法定人数的集群

一个包含 N 个节点的 Typesense 集群最多可以容忍 (N-1)/2 个节点故障,而不会影响读写操作。

例如:

  • 3 节点集群可以承受 1 个节点故障
  • 5 节点集群可以承受 2 个节点故障

如果 Typesense 集群同时失去超过 (N-1)/2 个节点,集群将变得不稳定,因为它失去了法定人数,剩余的节点无法安全地就哪个节点是领导者达成共识。为了避免潜在的脑裂问题,Typesense 会停止接受写入和读取操作,直到进行一些手动验证和干预。

要恢复失去法定人数的集群:

  1. 通过编辑其中一个节点的 nodes 文件(仅保留其自身的 IP 地址),强制将其变为单节点集群。

    你不需要重启 Typesense 进程,因为对 nodes 文件的更改会在 30 秒内自动生效。

  2. 等待该节点在调用 /health 端点时返回 ok。

  3. 现在编辑这个单节点的 nodes 文件,包含它自己的 IP 地址和第二个节点的 IP 地址。

  4. 编辑第二个节点的 nodes 文件,包含第一个节点和第二个节点的 IP 地址,然后启动第二个节点的 Typesense 进程。

    这将使第二个节点从第一个节点同步数据。如果第二个节点落后第一个节点太多,你可能需要在重新启动第二个节点之前清除其数据目录,这样第二个节点将从第一个节点同步数据的新快照。

  5. 等待第二个节点在调用 /health 端点时返回 ok。

    此时,第一个和第二个节点都应该处于健康状态。

  6. 对于每个额外的节点,重复步骤 3-5:将所有节点(现有节点和即将添加的新节点)的 IP 地址添加到每个节点的 nodes 文件中,然后启动新节点。

# 何时使用快照恢复

快照恢复主要在重大灾难恢复场景中具有重要价值。

例如,如果由于某些意外事件导致集群中的所有三个节点同时故障,整个集群的数据全部丢失,此时就需要依赖备份进行恢复。

在这种灾难恢复场景中,请按照以下步骤操作:

  1. 获取最近的快照备份
  2. 使用该快照启动单个 Typesense 节点
  3. 当第一个节点启动并稳定运行后,添加第二个节点(其数据目录为空),将其 IP 地址添加到第一个节点和该新节点的 nodes 文件中,让其从第一个节点完全同步数据
  4. 最后启动第三个节点(将其 IP 地址添加到所有三个节点的 nodes 文件中),让其从现有节点同步数据,从而重建完整的集群

这种分阶段的方法可以确保在从备份重建集群时保持数据一致性。

# 客户端配置

# 在没有负载均衡器的情况下部署

Typesense 客户端允许您在初始化时指定一个或多个节点。 因此,您可以在实例化客户端库时指定集群中的各个主机名, 客户端库会自动在所有节点之间负载均衡读写操作,并通过内置重试机制自动从瞬时故障中恢复。

以下是一个 3 节点客户端配置示例:

# 使用 Typesense Cloud 或负载均衡器时

如果您使用 Typesense Cloud(集群启用了负载均衡功能,2022年6月16日后创建的所有集群默认启用此功能),或者为了方便选择设置服务器端负载均衡器,您需要指定客户端默认路由所有请求的负载均衡端点。

在 Typesense Cloud 中,您还需要额外指定各个主机名 - 这些将作为客户端的备用节点,以防负载均衡端点恰好命中一个处于"连接耗尽"状态的陈旧节点(例如在配置变更或基础设施更新期间,每次节点轮换会持续30秒)。

这里的 xxx.a1.typesense.net 是一个负载均衡端点。