如果多个etcd集群的键值不重复,能否将数据合并?能否像数据库一样,将数据从旧库导出,然后在新库插入就万事大吉呢?答案是不能,etcd并没有提供类似功能,倒是有个备份功能,但是多个集群的备份数据却无法直接合并到一起。难道只能写个循环,将老集群的数据遍历出来,然后再插入新集群吗?这样也太土了吧,于是开始在网上找各种资料,可总是无功而返,看来只能老老实实看etcd官方资料了。功夫不负有心人,终于找到一条类似命令make-mirror,这条命令可以实时将一个集群的数据备份到其他集群,感觉跟我上面的想法一致,那么它可以用来做数据合并吗?请看接下来的实验吧!
make-mirror简介
命令语法如下,详情见命令手册。
ETCDCTL_API=3 etcdctl make-mirror [options] <destination> [flags]
其中[options]
主要是配置源集群和目的集群证书信息,以及源集群的客户端地址等。<destination>
是目的集群的客户端地址。该命令是单向的,目的集群的变化不会影响源集群。
准备测试环境
在windows本地搭建3套etcd集群,名字分别是cluster1、cluster2、cluster3,这里假设将cluster1和cluster2的数据合并到cluster3,为了实验方便,只开放http访问。
启动集群1,并写入测试键/cluster1。为了避免混淆,在官方推荐的2379/2380端口前面加上数字代表不同的集群,例如对于集群1来说,客户端访问端口是12379,集群通信端口是12380。
$ nohup etcd -name cluster1 \
--data-dir /tmp/cluster1/data/ \
--listen-client-urls http://localhost:12379 \
--advertise-client-urls http://localhost:12379 \
--listen-peer-urls http://localhost:12380 \
--initial-cluster-state new &
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:12379 put /cluster1 "this is cluster1"
OK
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:12379 get --prefix /
/cluster1
this is cluster1
启动集群2,并写入测试键/cluster2。
$ nohup etcd -name cluster2 \
--data-dir /tmp/cluster2/data/ \
--listen-client-urls http://localhost:22379 \
--advertise-client-urls http://localhost:22379 \
--listen-peer-urls http://localhost:22380 \
--initial-cluster-state new &
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:22379 put /cluster2 "this is cluster2"
OK
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:22379 get --prefix /
/cluster2
this is cluster2
启动集群3,并写入测试键/cluster3。
$ nohup etcd -name cluster3 \
--data-dir /tmp/cluster3/data/ \
--listen-client-urls http://localhost:32379 \
--advertise-client-urls http://localhost:32379 \
--listen-peer-urls http://localhost:32380 \
--initial-cluster-state new &
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:32379 put /cluster3 "this is cluster3"
OK
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:32379 get --prefix /
/cluster3
this is cluster3
启动数据同步
将集群1的数据同步到集群3。
$ ETCDCTL_API=3 nohup etcdctl make-mirror --endpoints=http://localhost:12379 http://localhost:32379 &
将集群2的数据同步到集群3。
$ ETCDCTL_API=3 nohup etcdctl make-mirror --endpoints=http://localhost:22379 http://localhost:32379 &
查看集群3的数据,可以看到集群1、集群2的键值已经同步到集群3了。
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:32379 get --prefix /
/cluster1
this is cluster1
/cluster2
this is cluster2
/cluster3
this is cluster3
修改集群2的键值,然后查看集群3的键值信息,发现数据已实时同步。
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:22379 put /cluster2 "renew cluster2" # 修改集群2的值
OK
$ ETCDCTL_API=3 etcdctl --endpoints=http://localhost:32379 get --prefix /
/cluster1
this is cluster1
/cluster2
renew cluster2 # 已同步最新修改
/cluster3
this is cluster3
总结
- make-mirror命令不仅能用来实时备份数据、异地容灾,还能将多个数据合并到一个集群。
- 遇到问题,最好的解决方案是阅读官方资料。