测试使用vitess的时候发现vitess元数据的实现有多种方案,etcd, etcd2, zk,zk2, 由于刚开始测试的时候使用的是基于k8s集群+etcd的,以下就分步说明灾备实现方案:
1. 前置条件
元数据实现方式必须选择etcd2, 即在启动的时候需要增加参数
-topo_implementation etcd2 #元数据实现方案, 此处一定需要选择etcd2, 如果选择etcd的话无法使用etcd API3提供的 etcdctl make-mirror进行数据同步 -topo_global_server_address http://etcd-global:4001 -topo_global_root "/vt" #此处也需要指定,默认元数据存储路径使用/vt, 此处不设置也行(但是如果不设置程序是可以正常使用但是使用工具无法获取元数据信息,至于为什么获取不到没有搞明白);这里呢可以保留默认配置使用/vt即可
使用etcd2实现的原因是etcd2使用API_V3进行开发, etcd使用的是API_V2进行开发的, API_V3中官方提供了etcdctl make-mirror 工具可以用来做两个集群元数据的同步操作, 这样在跨机房灾备的时候就可以实现两套etcd集群数据的同步操作,保证一个机房挂了另一个机房依然可以正常提供服务。
上面所说的配置需要分别更新vtctld, vtgate, vttablet三个程序对应的配置,保证配置一致系统才可以正常使用。
2. 灾备部署
1. etcd集群
etcd集群分别在廊坊机房和马驹桥机房分别部署一套,通过工具etcdctl make-mirror实现两个集群数据的同步
#此部分很重要, 使用make-mirror工具必须基于API3
$export ETCDCTL_API=3
#参数说明
#endpoints集群入口(需要备份的源集群)
#dest-prefix目标集群目录前缀
#prefix需要备份的目录
#127.0.0.1:2379目标集群地址,备份数据会被写入目标集群指定的dest-prefix目录下
$etcdctl make-mirror --endpoints=192.168.80.221:4001 --dest-prefix="/vt" --prefix="/vt" 127.0.0.1:2379
#运行后如果有数据同步了会每隔30s输出一次当前更新的key的数量
#18
#19
#19
#29
同步进程最好开启守护进程, 确保程序始终在运行, 这里我们设计的同步进程需要在每个机房启动一个,确保一个程序宕机之后依然还有一个在使用,避免元数据的丢失;两个进程同时写入的时候不会有影响,写入的时候默认etcd都返回OK,两个进程写入的数据是相同的,,所以不会有影响。
对于删除的时候我们可以留意下, etcd删除数据的时候只返回影响的行数,所以我们无需担心同事启动两个进程对元数据产生影响,可以确保元数据始终和源是一样的。
# 先删除tt,由于tt不存在所以返回影响行数是0,这个是不会报错的
$ etcdctl --endpoints=192.168.80.221:4001 del tt $ 0
# 写入key tt1 value,返回OK $ etcdctl --endpoints=192.168.80.221:4001 put tt1 value $ OK
# 查询刚才写入的key tt1 $ etcdctl --endpoints=192.168.80.221:4001 get tt1 $ tt1 $ value
# 删除刚才写入的key tt1,返回影响行数1 $ etcdctl --endpoints=192.168.80.221:4001 del tt1 $ 1
# 继续删除,返回影响行数0 $ etcdctl --endpoints=192.168.80.221:4001 del tt1 $ 0
两个机房的etcd集群都分别使用自己的vip,把vip挂在到LVS下, 通过LVS的探活即可保证元数据的正常切换;
2. tablet部署
tablet由于是依赖于etcd集群,上面我们已经解决了元数据集群的高可用,tablet的部署可以在一个机房部署两个实例,组成一个集群, 如果一个机房挂了, 可以很容易切换到另外一个机房。 只需把灾备机房的从提升为主即可正常提供服务; 这个中间数据是不会丢失的,如果服务中压力大可以随时再增加1-2个从。
3. vtgate
vtgate的部署也是使用两个机房分别部署, 灾备机房可以不提供服务,两个机房的机器也可以通过挂在在LVS下,LVS进行探活,如果机房或者机器出现故障可以自动切换到灾备机房。