后端数据库【免费下载链接】orchestratorMySQL replication topology management and HA项目地址https://gitcode.com/gh_mirrors/or/orchestrator点击查看免费下载orchestrator/raft是 orchestrator 的一种部署形态多个orchestrator服务节点通过 Raft 共识协议组成一个集群由获得法定人数quorum的节点选举出唯一 leader 来执行变更。本指南围绕 docs/raft.md 展开先讲清 Raft 集群的工作原理与节点、后端数据库、代理、orchestrator-client四大组件的部署细节再结合源码解释健康检查、反向代理、命令分发、快照回放等底层机制并给出跨数据中心网络隔离fencing的实战场景帮助你为 MySQL 复制拓扑管理搭建一套自身高可用 防脑裂的架构。orchestrator/raft 是什么为 orchestrator 自身解决高可用与脑裂问题常规的 orchestrator 部署依赖一个共享后端数据库shared backend来保证多实例的一致性而orchestrator/raft则完全不同若干个orchestrator节点之间通过raft共识协议互相通信共同维护一份有序的命令日志raft log只有获得 quorum 的节点才能成为 leader 并执行变更。这种形态同时解决两类问题orchestrator 自身的高可用单节点故障不影响整体可用性leader 故障后会自动重选网络隔离 / 跨数据中心分区fencing借助 quorum 机制被网络分区隔离出去的节点不可能成为 leader因此永远不会出现两个 orchestrator 同时操作同一个 MySQL 拓扑的脑裂局面。关于orchestrator/raft与另一条高可用路线同步复制后端如 Galera/XtraDB Cluster/InnoDB Cluster的详细对比可参阅 docs/raft-vs-sync-repl.md。Raft 共识的本质quorum 保证leader 不在隔离区Raft 的核心特性是节点通过投票选出一个具有quorum法定人数的 leaderquorum 意味着该节点没有被网络隔离。在3 节点集群中quorum 大小为2在5 节点集群中quorum 大小为3。举例来说假设n1、n2、n3三个节点组成集群正常情况下会稳定选出一个 leader。若网络分区把n1与n2、n3隔开则 leader 必然出自n2或n3——n1因凑不齐 quorum3 节点需 2 票而无法当选。源码中 quorum 的计算逻辑见 go/raft/raft.go#L238-L244func QuorumSize() (int, error) { peers, err : GetPeers() if err ! nil { return 0, err } return len(peers)/2 1, nil }这一特性在跨数据中心DC场景下极其有用假设你在三个 DC 各部署一个orchestrator节点一旦某个 DC 被网络隔离活跃的 leader 必然位于隔离区之外、拥有共识的节点上——被隔离 DC 里的 orchestrator 即便还活着也无法执行任何拓扑变更。部署架构与关键技术细节节点规模3 或 5推荐官方推荐部署3 或 5 个orchestrator节点其他数量也合法但至少需要 3 个。容错能力与节点数直接挂钩3 节点集群最多允许 1 个节点故障5 节点集群最多允许 2 个节点故障。节点不会动态加入集群Raft 集群的成员列表是预先配置在RaftNodes中的替换节点需要手工重新配置并滚动重启见下文运维场景。启动时 orchestrator 依据这份列表建立初始 peer 关系详见 go/raft/raft.go#L120-L167 中的Setup()。每个节点拥有独立的专属后端数据库与 shared-backend 模式不同raft 模式下每个 orchestrator 节点各自连接一个专属的后端数据库二者是一一对应的1:1映射且无需任何复制关系MySQL 后端不需要配置复制但后端 MySQL 本身有 replica 也无妨。部署建议是将 MySQL 与 orchestrator 放在同一台主机上SQLite 后端配置BackendDB: sqlite即可orchestrator 已内置 SQLite无需安装外部依赖。BackendDB: sqlite, SQLite3DataFile: /var/lib/orchestrator/orchestrator.db,选择哪种后端可参考 docs/configuration-backend.md 与 docs/high-availability.md。实际 CI 环境里orchestrator/raft就以 SQLite 后端运行见 conf/orchestrator-raft-env.conf.json。节点间通信非常稀疏Raft 模式下 orchestrator 节点之间不共享拓扑探测数据——每个节点都独立地发现probe全部 MySQL 服务器。节点间只传输 raft 协议本身所需的共识消息以及 leader 向 follower 分发的用户指令与故障恢复事件详见下文行为特征。这种低通信量设计使orchestrator/raft特别适合高延迟的跨 DC 网络。配置指南RaftEnabled 等核心参数详解在 3 节点部署中需要在每个节点上配置以下内容RaftEnabled: true, RaftDataDir: path.to.orchestrator.data.directory, RaftBind: ip.or.fqdn.of.this.orchestrator.node, DefaultRaftPort: 10008, RaftNodes: [ ip.or.fqdn.of.orchestrator.node1, ip.or.fqdn.of.orchestrator.node2, ip.or.fqdn.of.orchestrator.node3 ],各参数含义字段定义见 go/config/config.go#L111-L116参数作用与注意事项RaftEnabled必须为true否则 orchestrator 运行在 shared-backend 模式所有Raft*配置被忽略RaftDataDirorchestrator 的数据目录必须可写目录不存在时 orchestrator 会尝试自动创建RaftBind本节点用于 raft 通信的 IP 或完整主机名该地址也必须出现在RaftNodes中DefaultRaftPortraft 通信端口可改为任意端口但所有节点必须一致默认值10008RaftNodes集群全部节点的 IP 或主机名列表须包含RaftBind所指的本节点一个可直接参考的完整示例对应 docs/configuration-raft.mdRaftEnabled: true, RaftDataDir: /var/lib/orchestrator, RaftBind: 10.0.0.2, DefaultRaftPort: 10008, RaftNodes: [ 10.0.0.1, 10.0.0.2, 10.0.0.3 ],使用完整主机名同样可行RaftEnabled: true, RaftDataDir: /var/lib/orchestrator, RaftBind: node-full-hostname-2.here.com, DefaultRaftPort: 10008, RaftNodes: [ node-full-hostname-1.here.com, node-full-hostname-2.here.com, node-full-hostname-3.here.com ],配置的强制性校验源码佐证配置在启动时会被严格校验不符合要求 orchestrator 会直接拒绝启动。见 go/config/config.go#L569-L577 与对应的单元测试 go/config/config_test.go#L154-L184RaftEnabled true时RaftDataDir必须定义否则报错RaftDataDir must be defined since raft is enabled (RaftEnabled)RaftEnabled true时RaftBind必须定义否则报错RaftBind must be defined since raft is enabled (RaftEnabled)RaftAdvertise未配置时默认取RaftBind的值。另外RaftNodes中的条目若未携带端口会自动补上DefaultRaftPort若条目为 IP 地址则直接使用为主机名则会先做 DNS 解析逻辑见 go/raft/raft.go#L178-L212。NAT、防火墙与路由RaftAdvertise 和 HTTPAdvertise若 raft 节点之间需要经过 NAT 网关通信需额外设置RaftAdvertise: ip.or.fqdn.visible.to.other.nodes即其他节点应该访问的本节点地址。否则其他节点会按RaftBind的地址去连接而失败。此外raft 节点会把 HTTP 请求反向代理给 leader见下文orchestrator 默认按RaftAdvertise启发式推断 leader 的 HTTP 地址。若处于 NAT、端口重映射等环境下无法正确推断可显式指定HTTPAdvertise: scheme://hostname:port例如HTTPAdvertise: http://my.public.hostname:3000表示假设本节点是 leader 时外部应通过哪个 HTTP 地址访问它。HTTPAdvertise的校验非常严格go/config/config.go#L591-L607测试见 go/config/config_test.go#L186-L216必须带http://或https://协议头、必须包含主机名、必须包含端口号、且不允许带路径。leader 的 HTTP URI 计算逻辑见 go/raft/raft.go#L96-L116优先使用HTTPAdvertise否则按RaftAdvertise的主机名 ListenAddress的端口 UseSSL决定的协议拼接。单节点 raft测试环境的特殊形态生产环境应使用 3 或 5 节点测试环境可以运行单节点orchestrator/raft。单节点模式下该节点隐式成为 leader并向自己广播 raft 消息。配置方式有两种配置空的RaftNodesRaftNodes: [],或配置一个与RaftBind或RaftAdvertise完全一致的节点RaftEnabled: true, RaftBind: 127.0.0.1, DefaultRaftPort: 10008, RaftNodes: [ 127.0.0.1 ],源码在 go/raft/raft.go#L140-L144 中检测到peer 列表为空或只有一个且等于本节点时清空 peers 并启用单节点模式对应底层实现在 go/raft/store.go#L81-L85EnableSingleNode true节点自举为 leader。流量接入只有 leader 能执行变更只有 leader 被允许执行变更操作。因此必须保证客户端流量只到达 leader。官方提供两条路线方式一代理到 leader/api/leader-check最简单的做法是在 orchestrator 服务之上架设 HTTP 代理如 HAProxy并使用/api/leader-check作为健康检查任意时刻至多一个orchestrator 节点对该检查返回HTTP 200/OK其余节点返回HTTP 404/Not found。只把流量导向通过该检查的节点。该端点还支持自定义失败状态码访问/api/leader-check/503会得到503响应其他数字同理。实现见 go/http/api.go#L2818-L2829func (this *HttpAPI) LeaderCheck(params martini.Params, r render.Render, req *http.Request) { respondStatus, err : strconv.Atoi(params[errorStatusCode]) if err ! nil || respondStatus 0 { respondStatus http.StatusNotFound } if logic.IsLeader() { r.JSON(http.StatusOK, OK) } else { r.JSON(respondStatus, Not leader) } }一个可直接使用的 HAProxy 配置示例来自 docs/raft.mdlisten orchestrator bind 0.0.0.0:80 process 1 bind 0.0.0.0:80 process 2 bind 0.0.0.0:80 process 3 bind 0.0.0.0:80 process 4 mode tcp option httpchk GET /api/leader-check maxconn 20000 balance first retries 1 timeout connect 1000 timeout check 300 timeout server 30s timeout client 30s default-server port 3000 fall 1 inter 1000 rise 1 downinter 1000 on-marked-down shutdown-sessions weight 10 server orchestrator-node-0 orchestrator-node-0.fqdn.com:3000 check server orchestrator-node-1 orchestrator-node-1.fqdn.com:3000 check server orchestrator-node-2 orchestrator-node-2.fqdn.com:3000 check提示也可使用orchestrator-client替代代理方案见下文。方式二代理到健康 raft 节点/api/raft-health这是上述约束的放宽版本健康的 raft 节点会把请求反向代理给 leader。你可以在 Kubernetes 等场景下尤其推荐向任意健康成员发送请求但绝不能访问不健康即被隔离出 quorum的成员。判断节点是否健康使用/api/raft-healthHTTP 200/OK该节点属于健康 raft 组可以接收流量HTTP 500/Internal Server Error该节点不属于健康组。需要注意两个短暂窗口刚启动、leader 尚未选出时以及leader 重新选举期间所有节点都可能短暂报告为不健康。实现见 go/http/api.go#L2983-L2993其底层依赖 go/raft/raft.go#L254-L261 的IsHealthy()状态为 Leader 或 Follower 即健康。反向代理的完整机制在 go/http/raft_reverse_proxy.go#L14-L47非 leader 节点一旦得知 leader 的 URI就会用httputil.NewSingleHostReverseProxy把请求转发过去leader 的 URI 由 leader 通过 raft 日志广播的leader-uri命令发布go/raft/raft.go#L154-L161、go/logic/command_applier.go#L285-L292。节点间还通过request-health-report心跳机制互相确认存活go/raft/raft.go#L352-L377。orchestrator-client无需代理的替代方案orchestrator-client 是一个包装脚本通过 HTTP API 访问 orchestrator 服务提供与orchestrator命令行几乎一致的接口。关键点可以把全部 orchestrator API 端点一次性交给orchestrator-client它会自动判断哪个端点是 leader并把请求直接发给 leader——这样就完全不需要代理了export ORCHESTRATOR_APIhttps://orchestrator.host1:3000/api https://orchestrator.host2:3000/api https://orchestrator.host3:3000/api如果你已经有代理orchestrator-client也支持只配置代理这一个端点export ORCHESTRATOR_APIhttps://orchestrator.proxy:80/apiORCHESTRATOR_API可以统一配置在/etc/profile.d/orchestrator-client.sh中若该文件存在会被orchestrator-client自动加载。常用命令示例orchestrator-client -c clusters # 列出所有集群 orchestrator-client -c discover -i 127.0.0.1:22987 # 发现实例 orchestrator-client -c topology -i 127.0.0.1:22987 # 打印拓扑 ASCII 树 orchestrator-client -c relocate -i 127.0.0.1:22988 -d 127.0.0.1:22987 # 移动 replica行为特征与运行语义raft 模式下的注意事项基于 docs/raft.md 并结合源码验证raft 模式下 orchestrator 有以下关键行为每个节点独立执行全部拓扑发现3 节点部署中每个 MySQL 拓扑服务器会被 3 个不同的 orchestrator 节点各自访问探测各自独立分析正常情况下各节点看到近乎一致的拓扑视图但每个节点独立运行自己的 analysis故障检测分析各自写各自的专属后端 DBMySQL 或 SQLite数据相互独立节点间通信稀疏且不关联事务性数据库提交leader 只向其他节点分发被拦截的用户指令如begin-downtime、register-candidate等以及进行中的故障恢复事件。命令分发表完整可见于 go/logic/command_applier.go#L38-L92涵盖discover、forget、begin-downtime、end-downtime、register-candidate、ack-recovery、write-recovery、put-key-value、put-instance-tag等 20 余种操作统一经 raft 日志有序回放go/raft/fsm.go#L33-L52所有用户变更必须经过 leader 的 HTTP API绝不能直接操作后端数据库否则该改动不会发布给其他节点会造成各节点数据不一致命令行模式被拒绝raft 模式下运行orchestrator可执行文件的 CLI 会直接拒绝。源码 go/app/cli.go#L141-L144 会输出提示并退出Orchestrator configured to run raft (RaftEnabled: true). All access must go through the web API of the active raft node. You may use the orchestrator-client script ... You may override this with --ignore-raft-setup也就是说日常操作应改用 orchestrator-client--ignore-raft-setup是我清楚我在做什么的风险开关若要使用它更合理的方式是直连 leader 的后端数据库只在服务节点安装 orchestrator 二进制orchestrator-client脚本可安装在任意需要的地方容错能力3 节点集群最多 1 个节点故障5 节点集群最多 2 个节点故障不影响可用性节点不能没有后端 DBSQLite 内嵌于 orchestrator天然无此问题MySQL 后端下若长时间连不上后端 DBorchestrator 服务会主动退出bail out节点可宕机后恢复重新加入 raft 组后会收到离线期间错过的全部事件。无论离线多久只要本地没有相关 raft 日志/快照其他节点会自动把最新快照推给它无法加入 raft 组则退出orchestrator 服务若无法加入集群会直接终止。快照与日志回放源码级机制上述自动补快照的能力依赖 raft 的日志存储与快照存储每个节点的 raft 日志log store和稳定存储stable store落在一个 SQLite 文件raft_store.db中表raft_log、raft_store实现见 go/raft/rel_store.go#L31-L54快照存储为磁盘文件snapshots/目录默认保留 10 份retainSnapshotCount并带 CRC64 校验见 go/raft/file_snapshot.go#L22-L28 与 go/raft/raft.go#L42-L47快照内容由 go/logic/snapshot_data.go#L33-L56 定义包括实例键InstanceKey/MinimalInstance、停机维护downtime记录、候选实例、故障检测、KV 存储、恢复记录、集群别名、访问令牌等经 gzip JSON 序列化后随 raft 分发Restore()会把快照内容整体应用到本地后端 DB并丢弃快照中不存在的旧实例。主要优势高可用leader 故障自动重选节点故障不影响整体共识防脑裂故障恢复由处于 quorum 中的 leader 节点执行不会被隔离节点干扰支持嵌入式 SQLite 后端无需为 orchestrator 准备 MySQL虽然 MySQL 后端同样支持跨节点通信量小非常适合高延迟的跨 DC 网络。实战场景跨数据中心网络隔离DC fencing考虑三个数据中心DC1、DC2、DC3我们在每个 DC 各部署一个orchestrator/raft节点当DC2发生网络隔离时会发生什么DC2内的节点失去与另外两个节点的联系凑不齐 quorum因此 leader 必然留在DC1或DC3拥有共识的那一侧。隔离中的节点既不能当选 leader也不会被客户端选为可用节点整个隔离期间MySQL 拓扑管理包括故障检测与恢复始终由 quorum 侧的 leader 完成。恢复网络后DC2节点重新加入 raft 组通过日志回放或快照补齐离线期间错过的全部变更orchestrator/raft的 KV 写入同样走 raft 协议leader 决定写入后会把请求发布给所有 raft 节点各节点按自身配置独立应用形成最终一致eventual-consistent的跨 DC 主库发现。详细说明见 docs/kv.md#kv-and-orchestratorraft。运维场景节点故障、重新供给与替换以下场景来自 docs/deployment-raft.md节点崩溃重启节点如适用先启动 MySQL 服务再启动 orchestrator 服务它会加入 raft 组、获取最近快照、追平 raft 日志后恢复正常新节点 / 重新供给后端数据库为空SQLite 无需任何准备节点加入后自动获取快照并追平日志MySQL 后端则需要先为新服务器配置好 orchestrator 数据库权限详见 docs/configuration-backend.md此后 orchestrator 可自动加入集群克隆后端数据库同样有效且非必需可用备份/恢复或 dump/load 方式克隆现有后端MySQL 逻辑/物理备份SQLite 用.dump恢复再启动 orchestrator 服务即可追上日志并加入集群替换节点假设RaftNodes: [node1, node2, node3]要把node3换成nodeX——先下线node3node1、node2仍可保持集群运行准备好nodeX的后端数据在node1、node2、nodeX上把RaftNodes改为[node1, node2, nodeX]先启动nodeX此时会因旧成员尚不知晓变更而被拒绝加入然后依次重启node1、node2三者即可形成新的健康集群。另外raft 节点之间的通信端口是DefaultRaftPort默认10008该端口只需对全部 orchestrator 节点开放其他人无需访问权限。Roadmap仍在规划中的能力根据 docs/raft.md以下能力仍在开发中故障检测需要 quorum 共识DeadMaster等故障需经多个 orchestrator 节点共同分析确认才能触发 failover/recovery探测共享与上述互斥由 leader 把待探测服务器列表按数据中心分配给各节点使每个 MySQL 服务器只被单个节点探测降低探测负载同时让所有 orchestrator 节点看到完全一致的拓扑视图而非各自独立的视图。延伸阅读orchestrator/raft 与同步复制后端对比orchestrator-client 使用指南raft 部署文档raft 相关配置详解后端数据库配置Key-Value 存储与 orchestrator/raft高可用方案总览赞分享后端数据库【免费下载链接】orchestratorMySQL replication topology management and HA项目地址https://gitcode.com/gh_mirrors/or/orchestrator点击查看免费下载相关推荐Orchestrator Raft 模式部署指南基于共识协议的高可用 MySQL 拓扑管理集群Orchestrator Raft 模式部署指南基于共识协议的高可用 MySQL 拓扑管理集群 导读 本文聚焦 orchestrator 的 Raft 共识模后端数据库LocalSend AppImage 打包实战Linux 便携版应用完整制作流程LocalSend AppImage 打包实战Linux 便携版应用完整制作流程 想在任何 Linux 机器上免安装分发 LocalSendAppImage即时通讯网络/通信orchestrator 高可用部署全解从单节点、共享后端到 raft 共识集群orchestrator 高可用部署全解从单节点、共享后端到 raft 共识集群 orchestrator 本身以高可用服务的方式运行本文以 docs/hi后端数据库上一篇PHPStan 错误 mixin.nonObject 详解当 mixin 指向了标量类型下一篇Inspector MCP 服务器 UX 处理器与交互模式深度解析Sampling、Elicitation、Roots 与表单生成实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考