Redis 的主从复制,哨兵模式和cluster模式

一、Redis模式的发展:
单机——》主从——》哨兵——》cluster,后面都是前面的升级。
说到Redis模式,就要知道集群,所谓集群:就是指通过增加服务器的数量,提供相同的服务,从而让服务器达到稳定,高可用的状态。之所以延伸出这么多Redis模式,就是为了是多个服务器能够高效率,高利用率的为集群服务。Redis集群是基于主从复制模式实现的。 节点:Redis集群中,每一个Redis都为一个节点。节点又分为主从节点,这个集群中只有一个主节点,n个从节点。

二、单机模式:
弊端:

  • 单机故障(服务器宕机了,redis服务就不可用)
  • 容量瓶颈(读写能力有限)
  • qps瓶颈

三、主从复制模式:

  1. 概念:有且仅有一个主节点,多个从节点。
  2. 特点:主节点可读可写,从节点只可读
  3. 练习:windows环境下搭建主从复制模式例子:
    重要:一个Redis配置文件就是一个Redis实例。 步骤如下:
    1.在redis/目录下创建一个redis-master-slave目录,命令如下:mkdir -p ./redis-master-slave,然后在新建的redis-master-slave下创建3个子目录,如下图:
  4. hiredis的哨兵 redis 哨兵 cluster_服务器

  5. 2.然后依次往这三个目录下拷贝redis的配置文件(redis.windows.conf),命令为:
    cp d:/redis/redis.windows.conf ./master6380。结果如下图:
  6. hiredis的哨兵 redis 哨兵 cluster_服务器_02

  7. 3.进入上面这三个配置文件,修改配置信息。
    修改主节点的配置文件的端口号;修改从节点的端口号同时开启主从复制
    从节点的配置如下(拿其中一个举例):
  8. hiredis的哨兵 redis 哨兵 cluster_redis_03

  9. 4.自此,主从复制模式配置成功。开始测试:
    打开三个cmd窗口,在每个窗口中,启动一个redis节点(服务端)。
    下面是主节点启动方式,从节点等同。
  10. hiredis的哨兵 redis 哨兵 cluster_服务器_04

  11. 再打开三个cmd窗口,在每个窗口中,登录一个redis节点(客户端),命令如下:
  12. hiredis的哨兵 redis 哨兵 cluster_数据库_05

  13. 可以发现主节点可以进行读写操作,从节点只能操作,如下图所示:
  14. hiredis的哨兵 redis 哨兵 cluster_服务器_06


  15. hiredis的哨兵 redis 哨兵 cluster_nosql_07

  16. 主节点服务器上显示了2个从节点服务器的连接信息,表明是一主二从的关系,如下,:
  17. hiredis的哨兵 redis 哨兵 cluster_redis_08

  18. 5.遇到的问题:
    设置了主从节点密码后,会出现下面这种情况:
  19. hiredis的哨兵 redis 哨兵 cluster_数据库_09

  20. 这表示从节点连接不上主节点,因为密码不对。
    解决问题:在主节点的配置文件上加 requiredpass 123456就可以了。
    原因分析:我以为一主二从都设置masterauth 123456 就可以了,其实不是 是我把masterauth和requiredpass概念弄错了。
    5.1 requiredpass和masterauth的作用? masterauth:主要针对master对应的slave节点设置的,在slave节点数据同步的时候用到
    requiredpass:对登录权限做限制,redis每个节点的requiredpass可以是独立的、不同的
    5.2 启用redis密码认证的涉及的问题,是否只设置requirepass就可以?masterauth是否需要同步设置?
    答案:redis启用密码认证一定要requirepass和masterauth同时设置。 如果主节点设置了requirepass登录验证,在主从切换,slave在和master做数据同步的时候首先需要发送一个ping的消息给主节点判断主节点是否存活,再监听主节点的端口是否联通,发送数据同步等都会用到master的登录密码,否则无法登录,log会出现响应的报错。也就是说slave的masterauth和master的requirepass是对应的,所以建议redis启用密码时将各个节点的masterauth和requirepass设置为相同的密码,降低运维成本。当然设置为不同也是可以的,注意slave节点masterauth和master节点requirepass的对应关系就行。

四、哨兵模式(解决了单机故障,自动选择从机代替主机,替换过程中redis不可用):
缺陷:写操作无法负载均衡,存储能力受到单机的限制
优点:实现了数据的多机备份,读操作的负载均衡和简单的故障恢复
protect-mode生效的两个原则:1.没有使用bind或者2.没有设置访问密码 哨兵模式是在主从复制模式的基础上搭建的。
主从复制模式有个致命的缺陷,当主机宕机后,整个集群就没有可写的节点了。假设当主节点宕机后,其中一个从节点能变成主节点,那么就解决了这个问题,即哨兵模式的诞生。

  1. 哨兵的任务:
    Redis 的Sentinel系统用于管理多个Redis服务器(instance),有三个任务:
  • 监控(Monitoring):Sentinel会不断地检查主从服务器是否正常运行
  • 提醒(Notification):当监控的某个Redis服务器出现问题,Sentinel可以通过API向管理员或者其他应用程序发送通知
  • 自动故障迁移(Automatic failover):当主服务器不能正常工作时,Sentinel会开始一次故障迁移,通过选举的方式,将其中一个从服务器升级为新的主服务器,并让原先主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新的主服务器的地址,使集群可以使用新主服务器代替失效服务器。
  1. Sentinel网络:
    2.1 什么是Sentinel网络?
    监控同一个Master的Sentinel会自动连接,组成一个分布式的Sentinel网络,互相通信并交换彼此关于被监控服务器的信息。如下图:
  2. hiredis的哨兵 redis 哨兵 cluster_redis_10

  3. 2.2. 为什么使用Sentinel网络?
    当只有一个Sentinel时,如果其挂掉,那么就无法实现自动故障迁移。但是Sentinel网络中只要有一个Sentinel活着,就可以故障迁移。
  4. 故障迁移的过程
    3.1 投票(半数原则)
    当任何一个Sentinel发现被监控的主服务器下线时,会通知其他的Sentinel开会,投票决定该主服务器是否下线(半数以上,所以Sentinel通常配奇数个)。
    3.2 选举
    当Sentinel确定主服务器下线,会在所有的从服务器中,选举一个新的节点,升级为主节点,其它的从节点,转为该节点的从节点。如果原主服务器重新上线,自动转为当前主节点的从节点。
  5. 其他相关概念
    主观下线和客观下线:
    主观下线(Subjectively Down,即SDOWN):指的是单个Sentinel实例对服务器作出的下线判断
    客观下线(Objectively Down,即ODOWN):指的是多个Sentinel实例在对同一个服务器做出SDOWN判断,且通过SENTINEL is-master-down-by-addr 命令互相交流后,得出的服务下线判断。只适用于主服务器,因为其他类型的Redis实例,Sentinel在将它们判断为下线前不需要进行协商。每个Sentinel实例都执行定时任务:
    a. 每个Sentinel以每秒一次的频率向它所知的主服务器、服务器以及其他Sentinel实例发送一个PING命令。
    b.如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 那么这个实例会被 Sentinel 标记为主观下线。 一个有效回复可以是: +PONG 、 -LOADING 或者 -MASTERDOWN 。
    c.如果一个主服务器被标记为主观下线, 那么正在监视这个主服务器的所有 Sentinel 要以每秒一次的频率确认主服务器的确进入了主观下线状态
    d.如果一个主服务器被标记为主观下线, 并且有足够数量的 Sentinel (至少要达到配置文件指定的数量)在指定的时间范围内同意这一判断, 那么这个主服务器被标记为客观下线。
    Sentinel API:
    有2种方式可以与Sentinel进行通讯:指令、发布和订阅。
    a. Sentinel命令:
    PING :返回 PONG 。
    SENTINEL masters :列出所有被监视的主服务器,以及这些主服务器的当前状态;
    SENTINEL slaves :列出给定主服务器的所有从服务器,以及这些从服务器
    的当前状态;

    b.发布与订阅信息:
    客户端可以将 Sentinel 看作是一个只提供了订阅功能的 Redis 服务器: 你不可以使用 PUBLISH 命令向这个服务器发送信息, 但你可以用 SUBSCRIBE 命令或者 PSUBSCRIBE 命令, 通过订阅给定的频道来获取相应的事件提醒。
    一个频道能够接收和这个频道的名字相同的事件。 比如说, 名为 +sdown 的频道就可以接收所有实例进入主观下线(SDOWN)状态的事件。
    通过执行 PSUBSCRIBE * 命令可以接收所有事件信息。
    +switch-master <master name> <oldip> <oldport> <newip> <newport> :配置变更,主服务器的 IP 和地址已经改变。
  6. Windows环境下搭建哨兵模式(基于主从复制模式):
    之前犯了一个很大错误,在windows环境下我搭好了主从模式,开始搭建哨兵模式的时候,发现解压文件下没有sentinel.conf配置文件,我以为是版本太低,于是重新安装了一个最新的Linux版本的Redis,以为解压后就能直接用,大错特错,搞混了Linux和Window操作系统。基于一直没认识到这个错误,然后我搭建好了主从模式,但是主从节点服务器都没法启动,报下面的错:
    然后我又犯了第二个错,以为是没有禁用保护模式,在我关掉防火墙,设置bind 0.0.0.0,protected-mode no,设置redis访问密码等操作之后,发现还是报这个错,还固执的以为是保护模式没有禁用成功的原因,在经历了7/8个小时的各种尝试还是无法启动redis服务器,我就开始重新思考了这个问题。发现自己犯了一个很致命的错误,我下载的是linux版本的reidisan安装包,在windows环境下解压后是无法使用的,需要再linux环境下解压后,编译,再安装,最后还需要安装gcc。
    反思:之所以犯了这个错误,还是因为自己不够细心以及一味的图快,看着别人的微博都不认真思考,每一步的意义,以为自己看懂了,其实并没有懂,不要以为自己看了跟着做了就是学习到了,要明白学了25%和75%的区别,因为只要你去看了新东西都是学习了,但是这种学习的意义不大。 例子1:需求:基于主从模式搭建哨兵模式,配置三个Sentinel实例,监控同一个主节点。
    步骤:
sentinel配置信息模板:
# 这个是Redis6379配置内容,其他文件同理新增然后改一下端口即可,26380
#当前Sentinel服务运行的端口
protected-mode no
port 26381
# 哨兵监听的主服务器 后面的1表示主机挂掉以后进行投票,只需要1票就可以从机变主机
sentinel monitor mymaster 127.0.0.1 6379 2
# 3s内mymaster无响应,则认为mymaster宕机了
sentinel down-after-milliseconds mymaster 3000
#如果10秒后,mysater仍没启动过来,则启动failover  
sentinel failover-timeout mymaster 10000  
# 执行故障转移时, 最多有1个从服务器同时对新的主服务器进行同步
sentinel parallel-syncs mymaster 1
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码,没有的话不用设置
sentinel auth-pass mymaster 123456

a.在redis目录下建一个sentinels目录 ,该目录下建三个配置文件:sentinel26380.conf,sentinel26381.conf,sentinel26381.conf
sentinel26380.conf内容为:

port 26380
sentinel monitor mymaster 127.0.0.1 6380 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 15000

sentinel26381.conf内容为:

port 26381
	sentinel monitor mymaster 127.0.0.1 6381 2
	sentinel down-after-milliseconds mymaster 5000
	sentinel parallel-syncs mymaster 1
	sentinel failover-timeout mymaster 15000

sentinel26382.conf内容为:

port 26382
		sentinel monitor mymaster 127.0.0.1 6382 2
		sentinel down-after-milliseconds mymaster 5000
		sentinel parallel-syncs mymaster 1
		sentinel failover-timeout mymaster 15000

b.先在redis解压目录下启动三个redis服务(主从复制模式)

hiredis的哨兵 redis 哨兵 cluster_数据库_11


然后再启动三个sentinel服务:

hiredis的哨兵 redis 哨兵 cluster_数据库_12


hiredis的哨兵 redis 哨兵 cluster_服务器_13


hiredis的哨兵 redis 哨兵 cluster_redis_14


自此,Window下Redis的哨兵模式就启动了。例子2:一主二从,一个sentinel,在这种模式下,当主节点宕机后,会选择一个从节点升级为主节点,如果原先的主节点重新启动,会成为新主节点的从节点,三个redis.windows.conf都会做修改,sentinel.conf也会做修改。

sentinel服务器端发生的变化如下图所示:

hiredis的哨兵 redis 哨兵 cluster_数据库_15


补充:命令info:可以查看服务器的信息

例子3:尝试搭建哨兵也是多个的模式(因为如果只有一个哨兵,当这个哨兵也挂掉,就无法实现自动故障转移)。

需求:一主二从,三个sentinel

一主二从的搭建就不再重复,新增3个sentinel.conf配置文件:

以其中一个配置文件为例:

port 26380
# 哨兵监听的主服务器 后面的1表示主机挂掉以后进行投票,只需要1票就可以从机变主机
sentinel monitor mymaster 127.0.0.1 6380 2
# 3s内mymaster无响应,则认为mymaster宕机了
sentinel down-after-milliseconds mymaster 3000
#如果10秒后,mysater仍没启动过来,则启动failover  
sentinel failover-timeout mymaster 10000  
# 执行故障转移时, 最多有1个从服务器同时对新的主服务器进行同步
sentinel parallel-syncs mymaster 1
# 设置哨兵sentinel 连接主从的密码 注意必须为主从设置一样的验证密码,没有的话不用设置
sentinel auth-pass mymaster 123456  

sentinel monitor s1 127.0.0.1 6381 2
sentinel down-after-milliseconds s1 3000
sentinel failover-timeout s1 10000  
sentinel parallel-syncs s1 1
sentinel auth-pass s1 123456  

sentinel monitor s2 127.0.0.1 6382 2
sentinel down-after-milliseconds s2 3000
sentinel failover-timeout s2 10000  
sentinel parallel-syncs s2 1
sentinel auth-pass s2 123456

新增的三个sentinel 分别都监督主从节点。这里好像有个问题,三个sentinel之间好像没有相互通信?

  1. Linux环境下 哨兵模式的搭建:
    6.1 搭建步骤(基于主从模式):
    需求:配置三个Sentinel实例,监控同一个主节点。
    a. 在redis目录下创建Sentinel目录:

    然后在sentinels目录下创建三个子目录:

    拷贝redis解压目录下的sentinel.conf文件到上面新建的三个目录下:
    6.2 测试:

五、cluster模式:
优点:解决了写操作的负载均衡

  1. Windows下搭建Redis cluster集群
    需要四个部件:Redis、Ruby语言运行环境、Redis的Ruby驱动redis-xxx.gem、创建Redis集群的工具redis-trib.rb
    安装Ruby:
    https://rubyinstaller.org/downloads/ 出现下图表示安装成功:

    下载ruby环境下Redis的驱动:
    https://rubygems.org/gems/redis/versions/4.1.3
    把下载下来的文件移到:D:\Ruby23-x64
    然后安装该驱动:gem install --local path_to_gem/filename.gem,如下图:

    下载Redis官方提供的创建Redis集群的ruby脚本文件redis-trib.rb,路径如下:
    https://github.com/beebol/redis-trib.rb
    将下载下来的redis-trib放到redis目录下。

    修改各节点配置文件(redis.windows.conf),其中一个例子为:

    准备工作完成了,那么开始搭建redis-cluster,安装和启动四个redis实例:


    在任务管理器可以看到:
  2. redis-trib已放到redis目录下,然后切到redis目录下,(使用ruby命令)创建redis集群,命令为:
    redis-trib.rb create --replicas 0 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382

    检查创建成功命令:redis-trib.rb check 127.0.0.1:6380

    redis cluster 模式客户端连接服务器:

    从客户端的查看集群信息命令:cluster info
    看已知节点的信息:cluster nodes
  3. redis cluster 测试:
  4. 重启集群
    pkill -9 redis
    rm -rf dump.rdb
    rm -rf nodes-.
    重启redis节点,逐个启动 创建集群
  5. 碰到的问题,创建redis cluster的时候报下面的错: 查这个问题查了好3/4个小时,一直锁定不了问题所在,后来终于找到一篇靠谱的博客说clint.rb没设置密码。
    分析:因为我搭建的各节点的redis.windows.conf都设置了requirepass 123456(所有的密码保持一致,不然会有问题),单机连接是没有问题,但是创建集群就会报上面的错
    解决方案:redis cluster 设置密码做集群时需要修改gem下client.rb文件
    通过 find / -name client.rb 找到client.rb文件目录。我的在D:\Ruby23-x64\lib\ruby\gems\2.3.0\gems\redis-4.1.3\lib\redis下,给password设置密码

    然后重启个节点服务,再重新创建redis cluster即可。

6.Redis集群数据Hash分片算法是怎么回事?
Redis Cluster将所有数据划分为16384个slots槽位,每个节点负责其中一部分槽位,槽位的信息存储于每个节点中。
当Redis Cluster的客户端来连接集群时,它会得到一份集群的槽位配置信息并缓存在客户端本地。这样当客户端要查找某个key时,可以根据槽位定位算法定位到目标节点。
**槽位定位算法:**HASH_SLOTS = CRC16(key) mod 16384