部署高可用模式
此文档主要介绍了高可用模式的原理、准备工作、以及服务器的操作说明
1.原理
TuGraph 通过多机热备份来提供高可用(HA)模式。在高可用模式下,对数据库的写操作会被同步到所有服务器(非witness)上,这样即使有部分服务器宕机也不会影响服务的可用性。
高可用模式启动时,多个 TuGraph 服务器组成一个备份组,即高可用集群。每个备份组由三个或更多 TuGraph 服务器组成,其中某台服务器会作为leader
,而其他复制组服务器则作为follower
。写入请求由leader
提供服务,该leader
将每个请求复制同步到follower
,并在请求同步到服务器后才能响应客户端。这样,如果任何服务器发生故障,其他服务器仍将具有到目前为止已写入的所有数据。如果leader
服务器发生故障,其他服务器将自动选择出新的leader
。
TuGraph的高可用模式提供两种类型的节点:replica
节点和witness
节点。其中,replica
节点是普通节点,有日志有数据,可对外提供服务。
而witness
节点是一种只接收心跳和日志但不保存数据的节点。根据部署需求,leader
节点和follower
节点可以灵活的部署为replica
节点或witness
节点。
基于此,TuGraph高可用模式的部署方式有两种:一是普通部署模式,二是带witness的简约部署模式。
对于普通部署模式,leader
和所有follower
均为replica
类型的节点。写入请求由leader
提供服务,该leader
将每个请求复制同步到follower
,
并在请求同步到超过半数的服务器后才能响应客户端。这样,如果少于半数的服务器发生故障,其他服务器仍将具有到目前为止已写入的所有数据。如果leader
服务器发生故障,其他服务器将自动选举出新的leader
,通过这种方式保证数据的一致性和服务的可用性。
然而,在用户服务器资源不够或者发生网络分区时,不能建立正常的HA集群。此时,由于witness
节点没有数据,对资源占用小,可以将witness
节点和replica
节点部署在一台机器上。
例如,当只有2台机器的情况下,可以在一台机器上部署replica
节点,在另一台机器上部署replica
节点和witness
节点,不仅节省资源,而且不需要把日志应用到状态机上,
也不需要生成和安装快照,因此响应请求的速度很快,可以在集群崩溃或网络分区时协助快速选举出新的leader
,这就是TuGraph HA集群的简约部署模式。
尽管witness
节点有诸多好处,但是由于没有数据,集群实际上增加了一个不能成为leader
的节点,因此可用性会略有降低。为提高集群的可用性,
可通过指定ha_enable_witness_to_leader
参数为true
,允许witness
节点临时当主。witness
节点在把新日志同步到其他节点之后,
会将leader角色主动切换到有最新日志的节点。
v3.6及以上版本支持此功能。
2.准备工作
要启用高可用模式,用户需要:
-
三台及以上的 TuGraph 服务器实例。
-
在启动 lgraph_server 时打开高可用模式,可以使用配置文件或者命令行将
enable_ha
选项设置为true
。 -
设置正确的
rpc_port
,可通过配置文件或者命令行设置。
3.启动初始备份组
安装好TuGraph之后,可以使用lgraph_server
命令在不同的机器上启动高可用集群。本节主要讲解高可用集群的启动方式,启动之后的集群状态管理参见lgraph_peer工具
3.1.初始数据一致
当启动时所有服务器中的数据相同或没有数据时,用户可以通过指定--ha_conf host1:port1,host2:port2
启动服务器。
这种方式可以将准备好的所有TuGraph实例一次性加入初始备份组,由备份组中的所有服务器根据raft协议选举出leader
,并将其他服务器以follower
的角色加入备份组。
启动初始备份组的命令示例如下所示:
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090
3.2.初始数据不一致
如果第一台服务器中已有数据(以lgraph_import
工具导入或从非高可用模式的服务器传输得到),
并且之前并未在高可用模式下使用,则用户应使用boostrap方式启动。
以ha_bootstrap_role
参数为1在bootstrap模式下启动有数据的服务器,并通过ha_conf
参数指定本机为leader
。
在bootstrap模式下,服务器在将新加入的服务器添加到备份组之前会将自己的
数据复制到新服务器中,以使每个服务器中的数据保持一致。
启动有数据服务器的命令示例如下所示:
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090 --ha_bootstrap_role 1
其他无数据的服务器需要指定ha_bootstrap_role
参数为2,并通过ha_conf
参数指定leader
即可,命令示例如下所示
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090 --ha_bootstrap_role 2
使用bootstrap启动HA集群时需要注意两点:
- 需要等待
leader
节点生成snapshot并且成功启动之后再加入follower
节点,否则follower
节点可能加入失败。在启动follower
节点时可以将ha_node_join_group_s
参数配置的稍大,以在加入HA集群时多次等待和超时重试。 - HA集群只有在第一次启动时可以使用bootstrap模式,后续再启动时只能使用普通模式(见3.1节)启动,尤其不能让同一个集群的多个节点以bootstrap模式启动,否则可能产生数据不一致的情况
4.启动witness节点
4.1.不允许witness节点成为leader
witness
节点的启动方式和普通 节点的启动方式一致,只需要设置ha_is_witness
参数为true
即可。需注意,witness节点的数量应少于集群节点总数量的一半。
启动witness
节点服务器的命令示例如下所示:
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090 --ha_is_witness 1
注:默认不允许witness
节点成为leader
节点,这可以提高集群的性能,但是在leader
节点崩溃时会降低集群的可用性。
4.2.允许witness节点成为leader
可以通过指定ha_enable_witness_to_leader
参数为true
,使 得witness
节点可以临时成为leader
节点,在将新日志同步完成之后再主动切主
启动允许成为leader
节点的witness
节点服务器的命令示例如下所示:
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090 --ha_is_witness 1 --ha_enable_witness_to_leader 1
注:尽管允许witness
节点成为leader
节点可以提高集群的可用性,但是在极端情况下可能会影响数据的一致性。因此一般应保证witness
节点数量+1少于集群节点总数量的一半。
5.横向扩展其他服务器
启动初始备份组后,如 果想对备份组进行横向扩展,要将新服务器添加到备份组,
应使用--ha_conf HOST:PORT
选项,其中HOST
可以是该备份组中已有的任何服务器的 IP 地址,
而PORT
是其 RPC 端口。例如:
./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090
此命令将启动一台高可用模式的 TuGraph 服务器,并尝试将其添加到包含服务器172.22.224.15:9090
的备份组中。
请注意,加入备份组需要服务器将其数据与备份组的leader
服务器同步,此过程可能需要相当长的时间,具体取决于数据的大小。
6.停止服务器
当服务器通过CTRL-C
下线时,它将通知当前的leader
服务器,告知其从备份组中删除该下线的服务器。如果leader
服务器下线,
它将在下线前将leader
身份权限传给另一台服务器。
如果服务器被终止或者与备份组中的其他服务器失去连接,则该服务器将被视为失败节点,leader
服务器将在特定时限后将其从备份组中删除。
如果任何服务器离开备份组并希望重新加入,则必须从--ha_conf HOST:PORT
选项开始,其中HOST
是当前备份组中的某台服务器的 IP 地址。
7.重启服务器
不建议重新启动整个备份组,因为它会中断服务。如果需要,可以关闭所有服务器。但在重新启动时,
必须保证关闭时的备份组中至少有N/2+1的服务器能正常启动,否则启动失败。 并且,
无论初始启动复制组时是否指定enable_bootstrap
为true,重启服务器时都只需通过
指定--ha_conf host1:port1,host2:port2
参数一次性重启所有服务器即可,命令示例如下所示:
$ ./lgraph_server -c lgraph.json --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090
8.docker部署高可用集群
在真实业务场景中,很可能遇到在多种操作系统或架构上部署高可用集群的需求。 差异化的环境可能导致编译TuGraph时缺少某些依赖。因此, 在docker中编译软件并部署高可用集群是非常有应用价值的。以centos7版本的docker为例, 部署高可用集群的步骤如下所示。
8.1.安装镜像
使用如下命令下载TuGraph的编译docker镜像环境
docker pull tugraph/tugraph-compile-centos7
然后拉取TuGraph源码并编译安装
8.2.创建容器
使用如下命令创建容器,使用--net=host
使得容器运行在host模式,此模式下
docker和宿主机和共享网络namespace,即共用同一个IP。
docker run --net=host -itd -p -v {src_dir}:{dst_dir} --name tugraph_ha tugraph/tugraph-compile-centos7 /bin/bash
8.3.启动服务
在每台服务器上使用如下命令启动服务,因为docker和宿主机共享IP,所以可以直接指定在宿主机IP上启动服务
$ lgraph_server -c lgraph.json --host 172.22.224.15 --rpc_port 9090 --enable_ha true --ha_conf 172.22.224.15:9090,172.22.224.16:9090,172.22.224.17:9090
9.查看服务器状态
备份组的当前状态可以在 TuGraph 可视化工具、REST API 以及 Cypher 查询中获取。
在 TuGraph 可视化工具中,可以在 DBInfo 部分中找到备份组中的服务器及其角色列表。
使用 REST API 时,可以使用GET /info/peers
请求获取信息。
在 Cypher 中,使用CALL dbms.listServers()
语句来查询当前备份组的状态信息。
10.高可用模式下数据同步问题
在高可用模式下,同一备份组中的不同服务器可能并不总是处于相同的状态。出于性能原因,如果请求已同步到超过一半的服务器,则leader
服务器将认为该请求属于committed
状态。尽管其余服务器最终将收到新请求,但服务器的状态不一致将持续一段时间。客户端也可能向刚刚重新启动的服务器发送请求,从而具有较旧的状态。
为了确保客户端看到一致连续的数据,特别是为了摆脱反向时间旅行
问题(其中客户端读取比以前看到的状态更旧的状态),每个 TuGraph 服务器都会保持一个单调增加的数据版本号。备份组中数据版本号到数据库状态的映射全局一致,这意味着如果两台服务器具有相同的数据版本号,则它们必须具有相同的数据。响应请求时,服务器在响应中包含了其数据版本号。因此,客户端可以知道它看到了哪个版本。客户端收到旧版本的数据之后可以重新向Leader发送请求,从而获取到最新的数据。