前言

Redis 集群方案

  • 1、Redis Sentinel
  • 2、Redis Cluster
  • 3、Twemproxy
  • 4、Codis
  • 5、客户端分片

解析

Redis 主从同步

  • Redis 主从同步,是很多 Redis 集群方案的基础,例如 Redis SentinelRedis Cluster 等等,所以我们先来了解Redis的主从同步功能

  • Redis的主从同步机制允许slavemaster那里通过网络传输拷贝到完整的数据备份,从而达到主从机制。为了实现主从复制,我们准备三个redis服务,依次命名为master,slave1,slave2

  • 配置主服务器

    • 为了测试效果,我们先修改master主服务器的配置文件redis.conf的端口信息
      1
      port 6300
  • 配置从服务器

    • 先修改slave1从服务器的配置文件redis.conf的端口信息和从服务器配置

      1
      2
      port 6301
      slaveof 127.0.0.1 6300
    • 再修改slave2从服务器的配置文件redis.conf的端口信息和从服务器配置

      1
      2
      port 6302
      slaveof 127.0.0.1 6300
    • 值得注意的是,从redis2.6版本开始,slave支持只读模式,而且是默认的。可以通过配置项slave-read-only来进行配置。

    • 此外,如果master通过requirepass配置项设置了密码,slave每次同步操作都需要验证密码,可以通过在slave的配置文件中添加以下配置项masterauth <password>
  • 数据怎么同步的?

    • 你启动一台slave 的时候,他会发送一个psync命令给master,如果是这个slave第一次连接到master,他会触发一个全量复制
    • master就会启动一个线程,生成RDB快照,还会把新的写请求都缓存在内存中
    • RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,然后master会把内存里面缓存的那些新命名都发给slave

Redis Sentinel 哨兵

  • 官方中文文档

  • 上面的主从机制方案中主服务器可能存在单点故障,万一主服务器宕机,这是个麻烦事情,所以Redis提供了Redis-Sentinel,以此来实现主从切换的功能,类似与zookeeper

  • Redis-SentinelRedis官方推荐的高可用性(HA)解决方案,当用Redismaster-slave的高可用方案时,假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换。

  • Redis-Sentinel本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

  • 它的主要功能有以下几点

    • 监控(Monitoring):不断地检查redis的主服务器和从服务器是否运作正常。
    • 提醒(Notification):如果发现某个redis服务器运行出现状况,可以通过 API 向管理员或者其他应用程序发送通知。
    • 自动故障迁移(Automatic failover):能够进行自动切换。当一个主服务器不能正常工作时,会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器; 当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器。
配置Sentinel
  • Redis Sentinel 兼容 Redis 2.4.16 或以上版本, 推荐使用 Redis 2.8.0 或以上的版本。

  • 必须指定一个sentinel的配置文件sentinel.conf,如果不指定将无法启动Sentinel。首先,我们先创建一个配置文件sentinel.conf

1
2
port 26379
sentinel monitor master 127.0.0.1 6300 2
  • 官方典型的配置如下
1
2
3
4
5
6
7
8
9
sentinel monitor mymaster 127.0.0.1 6379 2 # 这行配置指示 Sentinel 去监视一个名为 mymaster 的主服务器, 这个主服务器的 IP 地址为 127.0.0.1 , 端口号为 6300, 而将这个主服务器判断为失效至少需要 2 个 Sentinel 同意,只要同意 Sentinel 的数量不达标,自动故障迁移就不会执行。
sentinel down-after-milliseconds mymaster 60000 # 指定了 Sentinel 认为服务器已经断线所需的毫秒数。
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1 # 指定了在执行故障转移时, 最多可以有多少个从服务器同时对新的主服务器进行同步, 这个数字越小, 完成故障转移所需的时间就越长。

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5
  • 配置文件介绍
    • 配置文件只需要配置master的信息就好啦,不用配置slave的信息,因为slave能够被自动检测到(master节点会有关于slave的消息)。
    • 需要注意的是,配置文件在sentinel运行期间是会被动态修改的,例如当发生主备切换时候,配置文件中的master会被修改为另外一个slave。这样,之后sentinel如果重启时,就可以根据这个配置来恢复其之前所监控的redis集群的状态。
启动Sentinel
  • 下面两种方式都必须指定一个sentinel的配置文件sentinel.conf, 如果不指定将无法启动sentinelsentinel默认监听26379端口,所以运行前必须确定该端口没有被别的进程占用。
    • 对于 redis-sentinel 程序, 你可以用redis-sentinel sentinel.conf命令来启动 Sentinel 系统
    • 对于 redis-server 程序, 你可以用redis-server sentinel.conf --sentinel命令来启动一个运行在 Sentinel 模式下的 Redis 服务器

Redis Cluster

设计原则和初衷
  • 官方文档Cluster Spec中,作者详细介绍了Redis集群为什么要设计成现在的样子

  • 最核心的目标有三个:

    • 性能:这是Redis赖以生存的看家本领,增加集群功能后当然不能对性能产生太大影响,所以Redis采取了P2P模式完全去中心化而非Proxy方式、异步复制、客户端重定向等设计,而牺牲了部分的一致性、使用性。
    • 水平扩展:集群的最重要能力当然是扩展,文档中称可以线性扩展到1000结点。
    • 可用性:在Cluster推出之前,可用性要靠Sentinel保证。有了集群之后也自动具有了Sentinel的监控和自动Failover能力。
  • 它采用了P2P的模式,完全去中心化。支持多节点数据集自动分片,提供一定程度的分区可用性,部分节点挂掉或者无法连接其他节点后,服务可以正常运行。Redis 3.0集群采用Hash Slot方案,而不是一致性哈希。Redis把所有的Key分成了16384slot,每个Redis实例负责其中一部分slot。集群中的所有信息(节点、端口、slot等),都通过节点之间定期的数据交换而更新。

  • Redis客户端在任意一个Redis实例发出请求,如果所需数据不在该实例中,通过重定向命令引导客户端访问所需的实例。

  • Redis 3.0集群,目前支持的cluster特性

    • 节点自动发现
    • slave->master 选举,集群容错
    • Hot resharding:在线分片
    • 集群管理:cluster xxx
    • 基于配置(nodes-port.conf)的集群管理
    • ASK 转向/MOVED 转向机制
  • 如上图所示,所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。节点的fail是通过集群中超过半数的节点检测失效时才生效。客户端与redis节点直连,不需要中间proxy层。客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。redis-cluster把所有的物理节点映射到[0-16383]slot上cluster负责维护node<->slot<->value
  • 选举过程是集群中所有master参与,如果半数以上master节点与master节点通信超时,认为当前master节点挂掉。

  • 当集群不可用时,所有对集群的操作做都不可用,收到((error) CLUSTERDOWN The cluster is down)错误。如果集群任意master挂掉,且当前master没有slave,集群进入fail状态,也可以理解成进群的slot映射[0-16383]不完成时进入fail状态。如果进群超过半数以上master挂掉,无论是否有slave集群进入fail状态。

Twemproxy

  • Twemproxy是由Twitter开源的Redis代理, Redis客户端把请求发送到TwemproxyTwemproxy根据路由规则发送到正确的Redis实例,最后Twemproxy把结果汇集返回给客户端。

  • Twemproxy通过引入一个代理层,将多个Redis实例进行统一管理,使Redis客户端只需要在Twemproxy上进行操作,而不需要关心后面有多少个Redis实例,从而实现了Redis集群。

  • Twemproxy本身也是单点,需要用Keepalived做高可用方案。

  • 这么些年来,Twenproxy作为应用范围最广、稳定性最高、最久经考验的分布式中间件,在业界广泛使用。

  • 但是Twemproxy存在诸多不方便之处,最主要的是,Twemproxy无法平滑地增加Redis实例,业务量突增,需增加Redis服务器;业务量萎缩,需要减少Redis服务器。但对Twemproxy而言,基本上都很难操作。其次,没有友好的监控管理后台界面,不利于运维监控。

Codis

  • Codis解决了Twemproxy的这两大痛点,由豌豆荚于2014年11月开源,基于GoC开发、现已广泛用于豌豆荚的各种Redis业务场景。
  • Codis引入了Group的概念,每个Group包括1个Redis Master及一个或多个Redis Slave,这是和Twemproxy的区别之一,实现了Redis集群的高可用。当1个Redis Master挂掉时,Codis不会自动把一个Slave提升为Master,这涉及数据的一致性问题,Redis本身的数据同步是采用主从异步复制,当数据在Maste写入成功时,Slave是否已读入这个数据是没法保证的,需要管理员在管理界面上手动把Slave提升为Master

  • Codis使用,可以参考官方文档https://github.com/CodisLabs/codis/blob/release3.0/doc/tutorial_zh.md

参考