高可用 FAQ

本文档介绍 YMatrix 6.X 高可用的常见问题。

1 etcd 是部署在每台主机上吗?


etcd 的存储可以理解为全复制表,因此节点数量不必太多。在实践层面,推荐的配置为 1、3、5、7 节点,安装部署过程会自动根据主机数量选定部署几个 etcd 实例。
因此如果集群里的主机个数是偶数,或者超过 7 台主机,那么有些机器上是没有 etcd 节点的。可以通过 ps 命令查看当前主机上有没有 etcd 进程。
通常 Master 和 Standby 的主机上会优先安放 etcd 节点。

2 为什么 etcd 集群的成员数量需要为奇数?


在 etcd 中,将节点数设置为奇数个是为了确保选举过程的稳定性和一致性,在 Raft 协议中,leader 的选举是基于大多数原则。当节点数为奇数时,选举过程更容易达成共识。在这种情况下,半数以上的节点需要同意并投票支持一个 candidate 成为 leader。假设有 5 个节点,需要至少 3 个节点同意选举同一个 leader;如果有 7 个节点,则需要至少 4 个节点同意。

这种配置除了确保 leader 的选举结果是唯一的,还能尽量保证选举时间的精短。另外奇数个节点还能提供更好的容错能力。在发生故障或网络异常的情况下,多数个节点仍然可以保持选举过程的正常运行,确保系统的可用性和一致性。当节点数为偶数时,可能会出现平局的情况,导致选举无法完成或结果不确定。

3 日常我们需要针对 etcd 做哪些运维操作?


首先,需要部署针对 etcd 的监控。目前支持 Prometheus 5.0 部署 etcd 的监控(Prometheus + Grafana)。

4 etcd 的数据量有多大?是否需要特别的运维工作?


5.X 的 etcd 会定期自动进行清理操作,因此数据目录和内存大小都能维持在一个相对固定的范围。
但是如果有节点故障和后续 recover 操作,会使 etcd 的数据在短时间内发生稍许膨胀。只要 etcd 的数据目录不持续膨胀超过 1.5GB,都是正常的,建议通过监控进行监视和定期检查。

5 引入 etcd 后,图形化界面部署数据库集群操作有哪些变化?


从使用体验上并没有变化,安装部署的页面和操作方法跟以前完全一致。

6 5.X 号称实现了 Master Auto-failover,为什么 Master 关机并切换后,再开机 Master 不会自动恢复?


这里存在一个概念误区,一个 Segment 有两个维度的概念:

  • 一个维度是角色:Primary 或 Mirror
  • 一个维度是状态:Up 或 Down

当前版本下,Master Auto-failover 功能指的是节点角色的自动切换,即 Master 离线之后,Standby 能自动切换为 Master,这个动作称为 提升(Promote)或者故障自动转移(Failover)。
而一旦一个 Segment 的状态从 Up 变成 Down,是必须通过手动节点恢复操作(mxrecover)才能变回 Up

7 Master 发生自动切换的延迟是多久?


  1. 当 Master 的 postmaster 进程发生崩溃,但主机和网络都正常,Master 可以快速切换到 Standby。
  2. 当 Master 主机发生断电、网络隔离等现象,其自动切换会根据参数的配置延迟重试一段时间。

8 当半数以上的 etcd 进程异常(被杀死或无法启动)后,集群出现宕机,是正常现象吗?


是的。

postgres 进程的存活需要依赖 etcd 集群的租约存续。当 etcd 服务本身出现异常(半数以上的 etcd 节点宕机或失联),postgres 进程就无法维持存活,宕机是必然的结果。因此,请严格部署 etcd 监控,密切关注其健康状态。监控事项包括但不限于:磁盘剩余空间、磁盘 I/O、网络联通性、宿主进程 supervisor 的存活等。

9 听说 5.X 下不能随便重启 Supervisor 了,为什么,如果重启了会发生什么?


在 4.X 时代,支持用 sudo systemctl restart matrixdb.supervisor.service 来重启图形化界面(MXUI)等组件。
但在 5.X 架构下,Supervisor 管理了更多子进程,包括 etcd、高可用服务、包括 Postmaster 进程。
因此现在如果随意关停或重启 Supervisor,会带来 etcd、Postmaster 等关键进程重启,轻则集群崩溃,重则丢失数据。

因此除了删除数据库集群、卸载数据库软件等操作之外,切勿再使用重启 Supervisor 的命令。

10 为什么每个服务器上都有 Shard / Cluster 服务进程,但只有一个是活跃(active)状态?


新架构在设计上考虑了最严苛的网络分区下的高可用性。

Cluster / Shard 服务负责数据库集群状态的管理。如果网络分区导致它们不能与集群其他应正常工作的部分联通,它们就不在能正确的对数据库集群状态进行决策。
为了在任何故障情况下都尽可能保持数据库集群可用,需要做出集群状态决策的服务本身也是高可用的。能够在各种网络异常下做出跟人类一样的客观判断,这也就是引入 etcd 集群的核心意义。
通常情况下,每个机器上都会运行一组 Cluster / Shard 服务。但整个集群里,每一种服务最多只有一个活跃的实例。其他不活跃的实例会在原活跃的实例失效后自动选出一个成为新的活跃实例。

11 5.X 现版本如何在线扩容?


可以使用图形化界面进行扩容操作

12 YMatrix 5 单个组件启动


不使用 matrixdb.supervisor.service 的原因

在 YMatrix 5 的架构下,supervisor 管理了更多子进程,包括 etcd 集群、高可用服务、postmaster 进程等。随意关停或重启 supervisor,会带来 etcdpostmaster 等关键进程重启,从而引发数据库问题。
因此需要重启某个组件的时候我们推荐采用 supervisorctl 工具。

单个组件管理

  1. 查看 supervisor 的状态及信息
    [mxadmin@mdw3 ~]$ systemctl status matrixdb5.supervisor.service
    ● matrixdb5.supervisor.service - MatrixDB 5 Supervisord Daemon
    Loaded: loaded (/usr/lib/systemd/system/matrixdb5.supervisor.service; enabled; vendor preset: enabled)
    Active: active (running) since Wed 2023-05-24 21:04:35 PDT; 1h 28min ago
    Process: 4426 ExecStop=/bin/bash -c exec "$MXHOME"/bin/supervisorctl shutdown (code=exited, status=1/FAILURE)
    Main PID: 4439 (supervisord)
    Memory: 605.4M
    CGroup: /system.slice/matrixdb5.supervisor.service
            ├─  954 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
            ├─  955 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
            ├─ 3357 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
            ├─ 4439 /opt/ymatrix/matrixdb5/bin/supervisord -c /etc/matrixdb5/supervisor.conf
            ├─ 4451 mxctl telegraf exec --gpname mdw3 --mxui-collector --socket-addr mdw3:51574 --cluster-id AuWFhsrjyywC4xfMahgyor --master-role --dbhost mdw3 --dbport ...
            ├─ 4461 mxctl telegraf exec --gpname mdw3 --mxui-collector --socket-addr mdw3:56639 --cluster-id GFpQhTxkwGqb7qM6iYVA8y --master-role --dbhost mdw3 --dbport ...
            ├─ 4470 /opt/ymatrix/matrixdb5/bin/cylinder -nofile -port 4637 -db-cluster-id AuWFhsrjyywC4xfMahgyor
            ├─ 4479 /opt/ymatrix/matrixdb5/bin/telegraf --config /tmp/mxui_collector_AuWFhsrjyywC4xfMahgyor.conf
            ├─ 4515 /opt/ymatrix/matrixdb5/bin/telegraf --config /tmp/mxui_collector_GFpQhTxkwGqb7qM6iYVA8y.conf
            ├─ 4528 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
            ├─ 4539 /bin/dbus-daemon --fork --print-pid 4 --print-address 6 --session
            ├─ 4997 /opt/ymatrix/matrixdb5/bin/mxui
            ├─12093 /usr/lib64/sa/sadc -S DISK 4 2 /tmp/sysstat-3640257011
            └─12094 /usr/lib64/sa/sadc -S DISK 4 2 /tmp/sysstat-3256168522
  2. 查看各组件运行状态
    [mxadmin@mdw3 ~]$ supervisorctl status
    Status:
         1. pc_id:{group:"mxui_collector_AuWFhsrjyywC4xfMahgyor" name:"mxui_collector_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4451, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/mxui_collector_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/mxui_collector_AuWFhsrjyywC4xfMahgyor.log" pid:4451
         2. pc_id:{group:"cylinder_AuWFhsrjyywC4xfMahgyor" name:"cylinder_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4470, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/cylinder_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/cylinder_AuWFhsrjyywC4xfMahgyor.log" pid:4470
         3. pc_id:{group:"shard_AuWFhsrjyywC4xfMahgyor" name:"shard_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4477, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/shard_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/shard_AuWFhsrjyywC4xfMahgyor.log" pid:4477
         4. pc_id:{group:"mxui" name:"mxui"} describe:"pid 4997, uptime 1:24:43" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/mxui.log" stdout_log_file:"/var/log/matrixdb5/mxui.log" pid:4997
         5. pc_id:{group:"replication-1_AuWFhsrjyywC4xfMahgyor" name:"replication-1_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4484, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/replication-1_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/replication-1_AuWFhsrjyywC4xfMahgyor.log" pid:4484
         6. pc_id:{group:"replication-3_AuWFhsrjyywC4xfMahgyor" name:"replication-3_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4466, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/replication-3_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/replication-3_AuWFhsrjyywC4xfMahgyor.log" pid:4466
         7. pc_id:{group:"etcd" name:"etcd"} describe:"pid 4450, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/mxdata_20230514185455/etcd/log/etcd.log" stdout_log_file:"/mxdata_20230514185455/etcd/log/etcd.log" pid:4450
         8. pc_id:{group:"replication-2_AuWFhsrjyywC4xfMahgyor" name:"replication-2_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4453, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/replication-2_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/replication-2_AuWFhsrjyywC4xfMahgyor.log" pid:4453
         9. pc_id:{group:"cluster_AuWFhsrjyywC4xfMahgyor" name:"cluster_AuWFhsrjyywC4xfMahgyor"} describe:"pid 4454, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/cluster_AuWFhsrjyywC4xfMahgyor.log" stdout_log_file:"/var/log/matrixdb5/cluster_AuWFhsrjyywC4xfMahgyor.log" pid:4454
         10. pc_id:{group:"deployer" name:"deployer"} describe:"pid 4457, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/deployer.log" stdout_log_file:"/var/log/matrixdb5/deployer.log" pid:4457
         11. pc_id:{group:"mxui_collector_GFpQhTxkwGqb7qM6iYVA8y" name:"mxui_collector_GFpQhTxkwGqb7qM6iYVA8y"} describe:"pid 4461, uptime 1:29:17" now:1684992833 state:"Running" log_file:"/var/log/matrixdb5/mxui_collector_GFpQhTxkwGqb7qM6iYVA8y.log" stdout_log_file:"/var/log/matrixdb5/mxui_collector_GFpQhTxkwGqb7qM6iYVA8y.log" pid:4461
  3. 重启某个组件,例:图形化界面(Mxui)
    [mxadmin@mdw3 ~]$ supervisorctl restart mxui
    Restarted:
         1. name:"mxui"

13 Segment 是否可以被 supervisor 自动恢复?


不可以。

supervisor 服务没有自动启动一个 Segment(或称为一个 postgresql 进程组)的功能,只有在 supervisor 被注册的服务才能被 supervisor 启动。postgresql 进程组作为副本(Replication)服务进程的子孙进程,由 replication 服务进程而不是 supervisor 服务进程管理。该进程组的启动只由集群管理工具(mxstartmxstopmxrecover 等)通过调用 replication 服务 API 启动或停止。