作者简介
孟文超,携程技术中心框架研发部高级经理。2016年加入携程,目前负责框架数据(数据库,缓存)及相关项目。此前曾在大众点评工作,任基础架构部门通信团队负责人。
一、背景
随着携程国际化业务的发展,为了给海外用户提供更好的服务,公司开始在欧洲部署业务(使用Amazon云),欧洲的用户访问欧洲的本地服务。携程机票业务重依赖于Redis,同时目前的数据产生大部分都在上海,这样就对Redis数据同步至欧洲产生了极大的需求,部署在欧洲的业务只需读取Redis数据即可。
数据传输如果走专线,将会产生高昂的专线费用(1MB的带宽,每月约1万RMB),如果能够通过公网,基本可以将数据传输费用降低到忽略不计。这样产生了第二个需求:数据传输走公网。
XPipe(https://github.com/ctripcorp/x-pipe)是携程内部开源的一套Redis多机房系统,现有的功能在以往的基础上继续扩展,可以参考公众号的另外一篇文章《携程Redis多数据中心解决方案-XPipe》。
Redis数据复制本身的工作原理可以参考一下官方手册:
https://redis.io/topics/replication。
本质上是说在Redis Master内存里面会以RingBuffer的数据结构缓存一段增量数据;如果网络瞬断的话,slave将会继续从自上一次中断的位置同步数据,如果续不上,就会进行一次全量同步。
因为数据在内存中缓存,而内存有限且昂贵,一个思路就是将数据缓存在磁盘里面。
在我们的具体方案中,设计了一个Keeper节点,作为Redis Slave向Master同步数据,同时将同步后的数据存入本地磁盘,海外数据同步通过Keeper进行数据传输,这样就产生了下面的结构:
关于Keeper的高可用及其相关的设计,可以参考前文所述的公众号文章。
首先我们调整了TCP的发送接收窗口:
net.core.wmem_max=50485760net.core.rmem_max=50485760net.ipv4.tcp_rmem=4096 87380 50485760net.ipv4.tcp_wmem=4096 87380 50485760 |
---|
上海到欧洲的网络延时在200ms左右,调整完成之后发现在24小时的稳定性测试中,会有多个时间点带宽无法打上去,导致数据同步延时过高。仔细观察了一下当时TCP连接的状态(通过ss命令),发现发送数据时,TCP发送窗口(cwnd)因为时不时的丢包,导致一直很小,问题主要出在数据发送方。
据此,我们在测试环境比较了多种发送端的拥塞控制(CongestionControl)算法:Cubic, Reno, Htcp. BBR,下面是在1%丢包率下不同算法带宽比较:
算法 | 平均带宽 |
---|---|
Cubic | 0.15 MBytes/sec |
Htcp | 0.11 MBytes/sec |
Reno | 0.09 MBytes/sec· |
BBR | 13.6 MBytes/sec· |
在测试Case下,BBR算法的带宽比其他算法提升了几乎100倍,其他丢包率的情况下,也有更好的表现。关于BBR算法的更多资料可以参考:
https://netdevconf.org/1.2/papers/bbr-netdev-1.2.new.new.pdf
因为我们的场景中数据发送方是在上海,所以在上海端的服务器部署了BBR算法,下面是在10MB数据传输速率下,公网24小时延时测试数据(单位为纳秒),数据最大延迟为88S。
公网和专线比较:
公网 | 专线 | |
---|---|---|
丢包 | 高(约1%) | 低(约0.05%) |
带宽 | 高 | 低 |
延时 | 中 | 中 |
价格 | 非常低 | 高,1W RMB/MByte/月 |
整个系统中最重要的指标是数据从上海到欧洲的延时是多少。根据此数据可以判定系统是否健康。系统延时监控架构如下图所示:
测试Client Publish一个时间戳数据给Master,然后将这个数据从Slave这边订阅收回,整个延时测试时间为:T1+T2+T3+T4。将数据收回计算延时时间主要是为了避免不同服务器时钟不一致产生的影响。
为什么数据订阅走专线?
为什么数据订阅通过Proxy转发?
这个主要是公司安全策略问题,欧洲的服务器只暴漏出了有限的端口供上海访问,而Redis服务器可能部署在很多的端口上面,这样可以通过Proxy进行转发代理。
整体系统架构如上图所示。Console用来管理多机房的元信息数据,同时提供用户界面,供用户进行配置和DR切换等操作。Keeper负责缓存Redis操作日志。Proxy主要解决公网传输问题。Meta Server管理单机房内的所有Keeper状态,并对异常状态进行纠正。Zookeer用来供Meta Server和Keeper进行Leader选举。