龙空技术网

携程开源Redis多数据中心复制管理系统

GitHub精选 1856

前言:

现时你们对“tcpaa”大体比较珍视,大家都想要知道一些“tcpaa”的相关文章。那么小编同时在网上收集了一些有关“tcpaa””的相关内容,希望看官们能喜欢,各位老铁们一起来了解一下吧!

《开源精选》是我们分享Github、Gitee等开源社区中优质项目的栏目,包括技术、学习、实用与各种有趣的内容。本期推荐的是一个由携程框架部门研发的Redis多数据中心复制管理系统——X-Pipe。

Redis 在携程内部得到了广泛的使用,根据客户端数据统计,整个携程全部 Redis 的读写请求在每秒 2000W,其中写请求约 100W,很多业务甚至会将 Redis 当成持久化的内存数据库使用。这样,就对 Redis 多数据中心提出了很大的需求,一是为了提升可用性,解决数据中心 DR(Disaster Recovery) 问题,二是提升访问性能,每个数据中心可以读取当前数据中心的数据,无需跨机房读数据,在这样的需求下,XPipe 应运而生 。

为了方便描述,后面用 DC 代表数据中心 (Data Center)。

整体架构Console 用来管理多机房的元信息数据,同时提供用户界面,供用户进行配置和 DR 切换等操作。Keeper 负责缓存 Redis 操作日志,并对跨机房传输进行压缩、加密等处理。Meta Server 管理单机房内的所有 keeper 状态,并对异常状态进行纠正。Redis 数据复制问题

多数据中心首先要解决的是数据复制问题,即数据如何从一个 DC 传输到另外一个 DC。我们决定采用伪 slave 的方案,即实现 Redis 协议,伪装成为 Redis slave,让 Redis master 推送数据至伪 slave。这个伪 slave,我们把它称为 keeper,如下图所示:

使用 keeper 带来的优势:

减少 master 全量同步

如果异地机房 slave 直接连向 master,多个 slave 会导致 master 多次全量同步,而 keeper 可以缓存 rdb 和 replication log,异地机房的 slave 直接从 keeper 获取数据,增强 master 的稳定性。

减少多数据中心网络流量

在两个数据中心之间,数据只需要通过 keeper 传输一次,且 keeper 之间传输协议可以自定义,方便支持压缩 (目前暂未支持)。

网络异常时减少全量同步

keeper 将 Redis 日志数据缓存到磁盘,这样,可以缓存大量的日志数据 (Redis 将数据缓存到内存 ring buffer,容量有限),当数据中心之间的网络出现较长时间异常时仍然可以续传日志数据。

安全性提升

多个机房之间的数据传输往往需要通过公网进行,这样数据的安全性变得极为重要,keeper 之间的数据传输也可以加密 (暂未实现),提升安全性。

机房切换流程检查是否可以进行 DR 切换

类似于 2PC 协议,首先进行 prepare,保证流程能顺利进行。

原主机房 master 禁止写入

此步骤,保证在迁移的过程中,只有一个 master,解决在迁移过程中可能存在的数据丢失情况。

提升新主机房 master其它机房向新主机房同步

同时提供回滚和重试功能。回滚功能可以回滚到初始的状态,重试功能可以在 DBA 人工介入的前提下,修复异常条件,继续进行切换。

高可用

XPipe 系统高可用

如果 keeper 挂掉,多数据中心之间的数据传输可能会中断,为了解决这个问题,keeper 有主备两个节点,备节点实时从主节点复制数据,当主节点挂掉后,备节点会被提升为主节点,代替主节点进行服务。

提升的操作需要通过第三方节点进行,我们把它称之为 MetaServer,主要负责 keeper 状态的转化以及机房内部元信息的存储。同时 MetaServer 也要做到高可用:每个 MetaServer 负责特定的 Redis 集群,当有 MetaServer 节点挂掉时,其负责的 Redis 集群将由其它节点接替;如果整个集群中有新的节点接入,则会自动进行一次负载均衡,将部分集群移交到此新节点。

Redis 自身高可用

Redis 也可能会挂,Redis 本身提供哨兵 (Sentinel) 机制保证集群的高可用。但是在 Redis4.0 版本之前,提升新的 master 后,其它节点连到此节点后都会进行全量同步,全量同步时,slave 会处于不可用状态;master 将会导出 rdb,降低 master 的可用性;同时由于集群中有大量数据 (RDB) 传输,将会导致整体系统的不稳定。

截止当前文章书写之时,4.0 仍然没有发布 release 版本,而且携程内部使用的 Redis 版本为 2.8.19,如果升到 4.0,版本跨度太大,基于此,我们在 Redis3.0.7 的版本基础上进行优化,实现了 psync2.0 协议,实现了增量同步。

测试数据

测试方案

测试方式如下图所示。从 client 发送数据至 master,并且 slave 通过 keyspace notification 的方式通知到 client,整个测试延时时间为 t1+t2+t3。

测试数据

首先我们测试 Redis master 直接复制到 slave 的延时,为 0.2ms。然后在 master 和 slave 之间增加一层 keeper,整体延时增加 0.1ms,到 0.3ms。

在携程生产环境进行了测试,生产环境两个机房之间的 ping RTT 约为 0.61ms,经过跨数据中心的两层 keeper 后,测试得到的平均延时约为 0.8ms,延时 99.9 线为 2ms。

docker快速启动

1 启动准备

需要提前启动docker进程,且支持docker-compose新建一个路径,在该路径下启动(建议)

2 启动docker

方式一:启动dockerhub上的镜像

/bin/bash -c "$(curl -sSL )"

启动后的容器分布

执行命令:docker ps -aCONTAINER ID   IMAGE                              COMMAND                  CREATED      STATUS      PORTS                                                                                                                          NAMES1e77491414a9   ctripcorpxpipe/xpipe-console:1.0   "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:8079->8080/tcp, :::8079->8080/tcp                                                                                       consolejq6694f9eff0ad   ctripcorpxpipe/xpipe-console:1.0   "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:8081->8080/tcp, :::8081->8080/tcp                                                                                       consoleoyaa0d109c7aae   ctripcorpxpipe/xpipe-meta:1.0      "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:9747->8080/tcp, :::9747->8080/tcp                                                                                       metajq0c6cb6dfe51f   ctripcorpxpipe/xpipe-meta:1.0      "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:9748->8080/tcp, :::9748->8080/tcp                                                                                       metaoy0e0f78ae096d   ctripcorpxpipe/xpipe-keeper:1.0    "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:7080->8080/tcp, :::7080->8080/tcp                                                                                       keeperjq116c5fdd14a5e   ctripcorpxpipe/xpipe-keeper:1.0    "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:7081->8080/tcp, :::7081->8080/tcp                                                                                       keeperjq21915292f3a7f   ctripcorpxpipe/xpipe-keeper:1.0    "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:7180->8080/tcp, :::7180->8080/tcp                                                                                       keeperoy10c885945d8f3   ctripcorpxpipe/xpipe-keeper:1.0    "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:7181->8080/tcp, :::7181->8080/tcp                                                                                       keeperoy215062ab45feb   ctripcorpxpipe/xpipe-proxy:1.0     "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:19079->80/tcp, :::19079->80/tcp, 0.0.0.0:19442->443/tcp, :::19442->443/tcp, 0.0.0.0:8092->8080/tcp, :::8092->8080/tcp   proxyjqed38daf8e71e   ctripcorpxpipe/xpipe-proxy:1.0     "docker-entrypoint.sh"   3 days ago   Up 3 days   0.0.0.0:19081->80/tcp, :::19081->80/tcp, 0.0.0.0:19444->443/tcp, :::19444->443/tcp, 0.0.0.0:8091->8080/tcp, :::8091->8080/tcp   proxyoyd0e811ea5d3d   zookeeper                          "/docker-entrypoint.…"   3 days ago   Up 3 days   2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, :::2181->2181/tcp, 8080/tcp                                                         zoo141381b5bd3a9   zookeeper                          "/docker-entrypoint.…"   3 days ago   Up 3 days   2888/tcp, 3888/tcp, 8080/tcp, 0.0.0.0:2182->2181/tcp, :::2182->2181/tcp                                                         zoo2d5f85ee0360e   ctripcorpxpipe/xpipe-mysql:2.0     "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp                                                                            mysqlba2b64f10700   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp                                                                                       redis-63794687df7ac486   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:6479->6379/tcp, :::6479->6379/tcp                                                                                       redis-647958cfdf41284a   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:6579->6379/tcp, :::6579->6379/tcp                                                                                       redis-6579d180471bb010   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:6679->6379/tcp, :::6679->6379/tcp                                                                                       redis-66794539be899dd3   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:7379->6379/tcp, :::7379->6379/tcp                                                                                       redis-7379dcf1b8079c1e   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:7479->6379/tcp, :::7479->6379/tcp                                                                                       redis-7479	180a2255d038   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:7579->6379/tcp, :::7579->6379/tcp                                                                                       redis-7579a877a83287b4   redis:4.0                          "docker-entrypoint.s…"   3 days ago   Up 3 days   0.0.0.0:7679->6379/tcp, :::7679->6379/tcp                                                                                       redis-7679
方式二:根据最新代码编译本地镜像再启动

3 验证

数据复制

测试master中数据是否能同步到备机房redis:

1、如果本地未安装reids, 则随机进入一台redis容器

docker exec -ti redis-6379 bash

2、连接主机房master redis 并添加数据后退出

`redis-cli -h 172.19.0.10set test1 12345`

3、连接备机房slave redis 获取数据成功后退出

`redis-cli -h 172.19.0.13get test1`

4、例子

song@ubuntu:~/yusong/code/test$ docker exec -ti redis-6379 bash root@c568933bae57:/data# redis-cli -h 172.19.0.10172.19.0.10:6379> set test1 12345OK172.19.0.10:6379> exitroot@c568933bae57:/data# redis-cli -h 172.19.0.13172.19.0.13:6379> get test1"12345"172.19.0.13:6379> exit
延迟监测

启动浏览器,进入localhost:8079/#/cluster_dc_shards/cluster1 查看各个redis的状态指示均为绿色

迁移功能

1、在cluster_list页面找到该cluster,点击迁移

2、选择待迁移cluster和目标机房

3、执行迁移

4、查看迁移是否成功

4 停止

docker-compose down

—END—

开源协议:Apache 2.0

开源地址:

标签: #tcpaa