- 后端
- 数据库
【免费下载链接】orchestrator
MySQL replication topology management and HA
本文围绕 GitHub 开源项目 orchestrator(MySQL 复制拓扑管理与高可用工具)的共享后端部署模式展开:多个orchestrator服务节点共用同一个后端数据库(典型为 Galera / XtraDB Cluster / InnoDB Cluster 等同步复制集群或主从复制架构),由数据库层面保证状态一致、由orchestrator自身通过后端选主机制保证单领导者。读完本文,你将掌握共享后端模式下服务端与客户端的完整部署方法、/api/leader-check等关键 API 的用法、领导者角色的源码级原理,以及它与 raft 模式、半高可用方案的取舍。
一、什么是共享后端部署
orchestrator支持多种后端数据库(backend DB)形态,高可用文档 对各类形态做了系统梳理。所谓shared backend(共享后端),指的是:所有orchestrator服务节点都连接到同一个后端数据库,该数据库承载了全部拓扑的“状态”(state)。
关键设计前提是:
- 后端数据库保存着你的所有 MySQL 拓扑状态;
orchestrator自身几乎无状态(almost stateless),它信任后端数据库中的数据。 - 在共享后端部署下,多个
orchestrator服务同时读写同一份后端数据,因此它们看到的是同一个“世界”,彼此之间不需要(也没有)直接的节点间通信协议。
这与 raft 模式 有本质区别:raft 模式下每个orchestrator节点拥有私有的后端数据库(MySQL 或 SQLite),靠 raft 共识协议在节点间同步数据;而共享后端模式把同步问题整体下沉到数据库层解决。两种方案的详细对比可参见 raft vs 同步复制后端对比文档。
二、后端数据库选型与高可用
设置共享后端数据库的工作由你(运维方)负责。官方文档明确提醒:orchestrator不会“自产自销”(doesn't eat its own dog food),它无法自动恢复自己后端数据库的故障。换句话说,后端 MySQL 集群的维护——比如往 Galera 集群里加节点、管理代理的健康检查——都需要你自己处理。
后端数据库可以是:
- 同步复制集群(面向高可用):Galera / XtraDB Cluster / InnoDB Cluster / NDB Cluster 等,MySQL 节点间以同步复制方式保持数据一致;
- 主从复制架构(半高可用):普通 master-replicas 布局,此时后端本身不具备自动故障切换能力。
针对两种后端,官方给出的配置建议如下:
同步复制后端(多写模式):
- 配置多写模式(multi-writer),即集群中每个 MySQL 节点都可写;
- 采用
orchestrator服务与 MySQL 节点1:1 映射:每个orchestrator服务只连接自己的那个 MySQL 节点。由于复制是同步的,不存在脑裂,全集群最多只有一个orchestrator领导者,且该领导者只会与达成共识的数据库节点通信。这种“1:1 耦合、节点同机部署”的组合是生产环境常用的形态(下文架构图即此形态)。
主从复制后端(异步/半同步):
- 配置所有
orchestrator节点访问同一个后端 DB(即 master 本身); - 可选地,在
orchestrator与后端之间架设你自己的负载均衡器,让所有orchestrator节点通过代理访问 master。
注意:如果后端采用“单写者 + 代理”的同步复制形态,一旦写者节点故障,需要由你的代理识别并切换流量到被提升的新写者——这部分不属于
orchestrator的能力范围。
从配置层面看,后端连接参数在 conf/orchestrator-sample.conf.json 中形如:
{ "MySQLOrchestratorHost": "127.0.0.1", "MySQLOrchestratorPort": 3306, "MySQLOrchestratorDatabase": "orchestrator", "MySQLOrchestratorUser": "orc_server_user", "MySQLOrchestratorPassword": "orc_server_password" }对应的类型定义与默认行为可参见 go/config/config.go 中的MySQLOrchestratorHost、MySQLOrchestratorPort、MySQLOrchestratorDatabase等字段。连接打开、连接池初始化等底层实现在 go/db/db.go(OpenOrchestrator及getMySQLURI等)。
三、部署orchestrator服务节点
服务数量与放置位置
- 将
orchestrator服务部署到“服务机”(service boxes)上。具体部署多少台,取决于你的可用性需求。 - 在“同步复制共享后端”形态下,服务机很可能就是 MySQL 节点本身,按
1:1映射同机部署(这也是架构图所示的典型布局)。 - 共享后端模式下,你可以按需部署任意数量的
orchestrator节点(官方建议参考 高可用文档,3 节点或 5 节点形态常见于生产)。
在服务机前架设代理(Proxy)
建议在服务节点之上加一层代理:
- 代理理想情况下应把所有流量导向领导者节点;
- 全集群有且只有一个领导者,其状态检查端点为
/api/leader-check; - 把流量导向任意健康节点也是可以的:因为所有
orchestrator节点共享同一个后端 DB,在一个服务节点上执行某些操作、在另一个服务节点上执行另一些操作是安全的——orchestrator内部通过锁(internal locks)避免互相矛盾或互相干扰的命令并发执行。
/api/leader-check在源码中的实现位于 go/http/api.go:
func (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") } }即:请求到达领导者节点时返回200 OK,到达非领导者节点时返回你指定的错误状态码(默认404,可通过/api/leader-check/:errorStatusCode自定义)。它的注册方式见 go/http/api.go 中registerAPIRequestNoProxy(m, "leader-check", ...)与leader-check/:errorStatusCode两行——注意它注册为NoProxy端点,意味着该请求不会被反向代理转发,而是由本节点直接应答,这正是负载均衡器做健康检查所需要的语义。另一个相关端点/api/status(对应配置项StatusEndpoint)可用于常规健康检查。
此外,orchestrator还暴露了/api/lb-check(LBCheck)端点,恒定返回"OK",可用于负载均衡器的存活探测(见 go/http/api.go)。
以 systemd 方式运行服务
仓库提供了 etc/systemd/orchestrator.service 作为服务运行参考,其中:
[Service] Type=simple WorkingDirectory=/usr/local/orchestrator ExecStart=/usr/local/orchestrator/orchestrator http EnvironmentFile=-/etc/sysconfig/orchestrator ExecReload=/bin/kill -HUP $MAINPID LimitNOFILE=16384orchestrator http即启动 HTTP 服务;SIGHUP信号会触发配置热加载(见 go/logic/orchestrator.go 的acceptSignals),SIGTERM则优雅退出。
四、部署客户端(三种交互方式)
要从 shell / 自动化脚本与orchestrator交互,可以选择以下三种方式之一(可混合使用):
方式一:直接调用 HTTP API
直接向orchestrator服务的 HTTP API 发起请求即可,例如:
curl -s "http://my.orchestrator.service:80/api/clusters"API 的完整说明见 Web API 使用文档。
方式二:使用orchestrator-client脚本(推荐用于自动化)
orchestrator-client 是对 HTTP API 的封装脚本,提供了与orchestrator命令行几乎一致的体验,并且可以自动识别领导者节点并把请求转发过去。部署要求极低:
- 在任意你想发起交互的机器上部署
orchestrator-client脚本即可; - 无需安装
orchestrator二进制、无需部署配置文件、无需访问后端 DB,只需要能够访问 HTTP API。
在这些机器上创建并编辑/etc/profile.d/orchestrator-client.sh,内容为:
ORCHESTRATOR_API="http://your.orchestrator.service.proxy:80/api"或者提供全部orchestrator节点列表(不用代理,脚本会自动找出领导者):
ORCHESTRATOR_API="http://your.orchestrator.service.host1:3000/api http://your.orchestrator.service.host2:3000/api http://your.orchestrator.service.host3:3000/api"第二种写法下,你的自动化不再需要代理(当然 Web 界面的用户仍然可以走代理)。orchestrator-client会逐个探测各节点,自动判定谁是领导者,并把请求发送给领导者。
官方同时建议:用 chef / puppet 等配置管理工具来维护ORCHESTRATOR_API的值,使其能随环境变化自动适配。
方式三:使用orchestrator命令行
命令行执行文档 详细介绍了这种方式。要点如下:
- 在任意你想发起交互的机器上部署
orchestrator二进制(可以使用orchestrator-cli发行包); - 在这些机器上创建
/etc/orchestrator.conf.json并填入凭据。该文件通常应与服务节点的配置文件保持一致;如果不确定,直接使用完全相同的内容即可; orchestrator二进制会直接访问共享后端 DB,所以务必为其开通后端数据库访问权限——通常就是 MySQL 的3306端口。
一个可直接复制的配置骨架(节选自 conf/orchestrator-sample.conf.json):
{ "ListenAddress": ":3000", "MySQLTopologyUser": "orc_client_user", "MySQLTopologyPassword": "orc_client_password", "MySQLOrchestratorHost": "127.0.0.1", "MySQLOrchestratorPort": 3306, "MySQLOrchestratorDatabase": "orchestrator", "MySQLOrchestratorUser": "orc_server_user", "MySQLOrchestratorPassword": "orc_server_password" }需要特别说明的是:即使
orchestrator服务正在运行,你也可以同时运行orchestratorCLI。它们都会在后端 DB 上协调工作,不会互相冲突。这是共享后端模式相对 raft 模式的一个显著便利——raft 模式下 CLI 直连会被禁止,必须走 HTTP API(参见 go/app/cli.go 中RaftEnabled时的报错逻辑)。
命令行常用示例(详细命令清单见 命令行执行文档):
# 列出当前已知集群(拓扑) orchestrator -c clusters # 发现一个实例(会沿 master/replica 链递归爬取整个拓扑) orchestrator -c discover -i 127.0.0.1:22987 # 打印拓扑 ASCII 树 orchestrator -c topology -i 127.0.0.1:22987 # 移动一个副本到其他位置 orchestrator -c relocate -i 127.0.0.1:22988 -d 127.0.0.1:22987 # 查看当前活跃的 orchestrator 节点(对应源码命令 active-nodes) orchestrator -c active-nodes其中active-nodes在源码中调用process.ReadAvailableNodes(false)列出所有健康节点(见 go/app/cli.go 与 go/process/health_dao.go)。
五、服务节点的角色分工:领导者与非领导者
共享后端模式下,多个orchestrator节点中会有一个被选举为领导者(leader)。选主机制基于后端数据库中的active_node表实现,完整实现在 go/process/election_dao.go:
AttemptElection():先insert ignore into active_node尝试写入;若写入成功即成为领导者;若已有领导者,则检查其last_seen_active是否超过ActiveNodeExpireSeconds(默认 5 秒,见 go/config/config.go),超时则通过update抢占;否则仅续写自己的last_seen_active心跳;ElectedNode():读取active_node表中记录,判断“本进程是否为当选者”;Reelect():删除active_node记录,强制让当前领导者让位、触发重新选举;GrabElection():强制抢占领导权(官方注释:Use with care!!)。
每轮健康心跳中,各节点都会调用AttemptElection刷新/争夺领导权,并把结果写入内存标志isElectedNode(见 go/logic/orchestrator.go 的onHealthTick)。logic.IsLeader()则统一返回当前节点是否为领导者。
只有领导者(leader)会执行以下动作:
- 发现(probe)你的 MySQL 拓扑:领导者驱动整个发现队列(
discoveryQueue),见 go/logic/orchestrator.go 的ContinuousDiscovery与handleDiscoveryRequests——非领导者节点的发现请求会被跳过(日志为 "Node apparently demoted. Skipping discovery..."); - 运行故障检测(failure detection):只有领导者参与
CheckAndRecover及其内部的故障分析流程; - 运行恢复(recoveries):故障自动恢复仅在领导者上执行。
所有节点都会执行:
- 提供 HTTP 服务:任何健康节点都能应答 API 请求;
- 注册自己的健康检查:每个节点持续向
node_health表写入心跳(ContinuousRegistration,默认每HealthPollSeconds = 1秒一次,见 go/process/health.go)。写入实现WriteRegisterNode在 go/process/health_dao.go,其中还会记录db_backend(即该节点实际连接的后端库地址)。
所有节点都可能执行:
- 任意人工命令(如
relocate、begin-downtime等)——因为这些操作通过共享后端协调,天然一致; - 按人工请求执行恢复操作。
六、CLI 的执行模型
orchestratorCLI(以及服务进程收到命令请求时)执行的是一个具体的操作,其行为取决于操作类型:
- 某些操作(如
relocate)需要探测少量服务器以获得实时信息; - 另一些操作则完全不探测服务器,只是从后端 DB 读取/写入数据。
由于所有读写都落到共享后端,CLI 与服务进程之间不存在数据不一致的问题,这也是“服务运行期间可以放心使用 CLI”的底层原因。命令的注册与分发集中在 go/app/cli.go(registerCliCommand维护命令清单,CliWrapper负责分发,并支持stop-slave→stop-replica等新旧命令同义词映射)。
七、架构总览:一个直观的部署示例
上图展示了共享后端模式的典型形态(即原部署文档的视觉示例):
- 三个
orchestrator节点运行在一个3 节点同步复制集群之上; - 每个
orchestrator节点连接不同的MySQL 后端节点,但这些后端通过同步复制共享同一份数据视图(理论上存在极小的复制延迟); - 其中一个
orchestrator节点被选举为领导者,只有它探测 MySQL 拓扑(图中为清晰起见只画出了部分探测连线); - 代理层可把用户/客户端流量导向领导者(基于
/api/leader-check),或导向任意健康节点。
八、共享后端 vs raft:如何选择
关于“共享后端”与“raft”的完整取舍,仓库专门提供了对比文档 raft vs 同步复制后端,核心差异可概括为:
| 维度 | 共享后端(同步复制) | orchestrator/raft |
|---|---|---|
| 节点间通信 | 无直接通信,依赖后端数据库同步 | 通过 raft 协议直接通信 |
| 后端 DB | MySQL(需自己维护集群) | 每节点私有 MySQL 或 SQLite |
| 探测拓扑 | 仅领导者探测,每台拓扑服务器被探测 1 次 | 所有节点独立探测,每台拓扑服务器被探测 N 次 |
| HTTP 访问 | 可访问任意健康节点(建议走代理只访领导者) | 必须只访问领导者 |
| 命令行 | HTTP/API、orchestrator-client、orchestratorCLI 均可 | 仅 HTTP/API 或orchestrator-client |
| 适用场景 | 单数据中心、已有同步复制集群运维经验 | 跨数据中心、高延迟网络、不想为后端分配 MySQL |
选型建议(来自对比文档的 Considerations):
- 只有单数据中心:选共享后端,甚至更简单的非 HA 形态;
- 熟悉 Galera / XtraDB Cluster / InnoDB Cluster 且有成熟自动化:选共享后端;
- 跨数据中心网络延迟高:选 raft;
- 不想为后端分配 MySQL 服务器:选 raft + SQLite;
- 拓扑规模达数千台 MySQL:两者皆可,但优先 MySQL 后端(写性能优于 SQLite)。
九、部署完成后的下一步
完成共享后端部署后,可参考生产部署文档 做进一步落地,例如:
- 拓扑自动发现:在每台生产 MySQL 上配置 cron,让每个主机每天自我上报一次(
orchestrator-client -c discover -i this.hostname.com,配合随机 sleep 避免请求风暴); - 候选实例声明:通过
orchestrator -c register-candidate -i ... --promotion-rule prefer|neutral|prefer_not|must_not定期声明各服务器的提升偏好(规则约一小时后过期,建议每 2 分钟 cron 刷新); - 主动停机(downtime):对例行故障的主机使用
orchestrator-client -c begin-downtime -duration 30m -reason ... -owner ...或直接调用/api/begin-downtime/...,使其不出现在问题列表、不参与恢复决策。
结语
共享后端模式把“一致性”问题交给后端数据库解决,让orchestrator服务本身保持近乎无状态、可水平扩展,是单数据中心生产环境的经典高可用方案。部署时抓住三个要点即可:一是后端同步复制集群的运维(含多写配置与 1:1 节点映射)必须自理;二是用/api/leader-check驱动代理把流量导向唯一领导者;三是客户端侧善用orchestrator-client的自动选主能力,让自动化脚本无需依赖代理。相关细节可继续阅读 高可用文档、raft 部署文档 与 Web API 使用文档。
- 后端
- 数据库
【免费下载链接】orchestrator
MySQL replication topology management and HA
相关推荐
Zenodo——“Research. Shared.”:基于 Invenio 的科研数据仓库架构与本地部署实战指南
Zenodo——“Research. Shared.”:基于 Invenio 的科研数据仓库架构与本地部署实战指南 本文围绕开源仓库 README.rst ht
后端企业应用FTLinearActivityIndicator:让刘海屏iPhone重获网络活动指示器的终极解决方案
FTLinearActivityIndicator:让刘海屏iPhone重获网络活动指示器的终极解决方案 FTLinearActivityIndicator是一
Ultimate SD Upscale快速入门:5分钟学会使用终极超分辨率工具
Ultimate SD Upscale快速入门:5分钟学会使用终极超分辨率工具 Ultimate SD Upscale是AUTOMATIC1111 Stable
人工智能AI 应用计算机视觉
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考