x-pipe/README.md at master · ctripcorp/x-pipe https://github.com/ctripcorp/x-pipe/blob/master/README.md

XPipe 解决什么问题

Redis 在携程内部得到了广泛的使用,根据客户端数据统计,整个携程全部 Redis 的读写请求在每秒 200W,其中写请求约 10W,很多业务甚至会将 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 协议,实现了增量同步。下面是 Redis 作者对协议的介绍:psync2.0

携程内部 Redis 地址链接

测试数据

延时测试

测试方案

测试方式如下图所示。从 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。

深入了解

XPipe 解决什么问题的更多相关文章

  1. IE6、7下html标签间存在空白符,导致渲染后占用多余空白位置的原因及解决方法

    直接上图:原因:该div包含的内容是靠后台进行print操作,输出的.如果没有输出任何内容,浏览器会默认给该空白区域添加空白符.在IE6.7下,浏览器解析渲染时,会认为空白符也是占位置的,默认其具有字 ...

  2. 关于解决python线上问题的几种有效技术

    工作后好久没上博客园了,虽然不是很忙,但也没学生时代闲了.今天上博客园,发现好多的文章都是年终总结,想想是不是自己也应该总结下,不过现在还没想好,等想好了再写吧.今天写写自己在工作后用到的技术干货,争 ...

  3. DBImport V3.7版本发布及软件稳定性(自动退出问题)解决过程分享

    DBImport V3.7介绍: 1:先上图,再介绍亮点功能: 主要的升级功能为: 1:增加(Truncate Table)清表再插入功能: 清掉再插,可以保证两个库的数据一致,自己很喜欢这个功能. ...

  4. MVVM框架从WPF移植到UWP遇到的问题和解决方法

    MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...

  5. java中文乱码解决之道(一)-----认识字符集

    沉寂了许久(大概有三个多月了吧),LZ"按捺不住"开始写博了! java编码中的中文问题是一个老生常谈的问题了,每次遇到中文乱码LZ要么是按照以前的经验修改,要么则是baidu.c ...

  6. XStream将java对象转换为xml时,对象字段中的下划线“_”,转换后变成了两个的解决办法

            在前几天的一个项目中,由于数据库字段的命名原因 其中有两项:一项叫做"市场价格"一项叫做"商店价格" 为了便于区分,遂分别将其命名为market ...

  7. 懒加载session 无法打开 no session or session was closed 解决办法(完美解决)

           首先说明一下,hibernate的延迟加载特性(lazy).所谓的延迟加载就是当真正需要查询数据时才执行数据加载操作.因为hibernate当中支持实体对象,外键会与实体对象关联起来.如 ...

  8. 使用JSONObject.fromObject的时候出现“There is a cycle in the hierarchy”异常 的解决办法

    在使用JSONObject.fromObject的时候,出现“There is a cycle in the hierarchy”异常.   意思是出现了死循环,也就是Model之间有循环包含关系: ...

  9. iPhone Anywehre虚拟定位提示“后台服务未启动,请重新安装应用后使用”的解决方法

    问题描述: iPhone越狱了,之后在Cydia中安装Anywhere虚拟定位,但是打开app提示:后台服务未启动,请重新安装应用后使用. 程序无法正常使用... 解决方法: 打开Cydia-已安装, ...

随机推荐

  1. unity3D绘画手册-----地形及术语解释

    Unity3D教程:设置地形(Terrain) Posted on 2013年04月18日 by U3d / Unity3D 基础教程 /被围观 1,901 次 新建地形: 在菜单中新建一个地形. U ...

  2. Java 的JSON、XML转换方法——目录索引(转)

    JSON及XML的Java序列化.反序列化(转换)在WebService.Ajax数据传递中,用得比较多.如:在用ExtJS.jQuery.mootools以及一些WebService时,你可以需要用 ...

  3. erlang的简单模拟半包的产生

     gen_tcp:linsten()/2使用的是{packet,2/4/8},则gen_tcp模块在接受或者发送时自动除去包头或者自动加上包头. 本例中使用的是{packet,0}. -module( ...

  4. [转]Git学习笔记与IntelliJ IDEA整合

    Git学习笔记与IntelliJ IDEA整合 一.Git学习笔记(基于Github) 1.安装和配置Git 下载地址:http://git-scm.com/downloads Git简要使用说明:h ...

  5. AssetBundle中Unload()方法的作用

    AssetBundle.Unload(false)的作用: 官网的解释是这样的: When unloadAllLoadedObjects is false, compressed file data ...

  6. CSS定位背景图片 background-position

    网站的样式的时候经常会发现一种情况,就是在很多background属性里都调用同一张图片,来满足网页各个部分的使用.打开这种图片看一下,会发现这张图片上包含了很多小图片; 又如: 这些小图片就是整图分 ...

  7. linux环境判断字符串是否为非空

    需求描述: 今天帮同事调整脚本,涉及到判断一个字符串为非空的,在此记录下. 操作过程: 通过-n来判断字符串是否为非空,如果为非空那么就是真 #!/bin/bash Str1='MyTest' if ...

  8. [java] java synchronized 关键字详解

    Java语言的关键字,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这段代码.当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一 ...

  9. 工作流JBPM_day01:6-执行流程实例

    工作流JBPM_day01:6-执行流程实例 执行流程 启动流程实例 查询任务列表 办理任务 向后执行一步 先部署流程定义在启动流程实例 Jbpm4_execution表表示正在执行的流程实例的的信息 ...

  10. Linux lspci 命令

    PCI(Peripheral Component Interconnect,外设部件互连标准),即定义连接外部设备的一个标准: 主板上有很多 PCI 接口,用来连接显卡.网卡.声卡等外部设备,而 ls ...