Redis: 2、Redis高可用原理,搭建与验证

本文详细介绍了Redis高可用性方案Sentinel的工作原理,包括主备切换流程、哨兵间和从服务器的自动发现机制、Slave选举策略以及获取Master地址的步骤。此外,还详细阐述了如何在环境中搭建Redis-HA,包括下载镜像、配置Sentinel、安装和验证过程。文章最后讨论了Redis-HA验证方法和客户端使用,包括主备切换后的应用验证和不同类型的Redis客户端使用方式。
摘要由CSDN通过智能技术生成

Redis高可用原理,搭建与验证

 

一、redis-ha原理


1 原理


redis高可用采用的是哨兵(sentinel),多个redis-slave配备了多个哨兵进程,哨兵监控redis-master,一旦出现故障,将一台slave提升为master。客户端通过连接哨兵来获取Redis的master地址,发生故障,哨兵会报告新的服务器地址。


2 主备切换流程


2.1 一个哨兵认为master不可用,此时被仍为主观不可用,当有指定个数的哨兵都认为master不可用,此时状态进入客观不可用,进入主备切换流程。
2.2 进入主备切换流程后,需要一定个数的哨兵都同意进行进行主备切换授权,此时才真正开始进行主备切换。
2.3 开始进行主备切换的时候,一个sentinel被授权, 获得挂掉的master的最新配置版本号,主备切换后,该版本号用于最新配置。
2.4 一个sentinel成功对master进行主备切换,会把最新配置通过广播形式高速其他sentinel,其他sentinel则更新对应master配置。
2.5 当将一个slave选举为master并发送命令后,即使其他slave还没有针对新master重新配置自己,主备切换也被认为是成功的,所有sentinels将会发布新的配置信息。
一个相互通信的sentinel集群最终会采用版本号最高且相同的配置。

3 Sentine之间和Slaves之间自动发现机制


sentinel利用master的发布/订阅机制自动发现其他的sentinel节点
每个sentinel向每个master和slave发布/订阅频道 __sentinel__:hello 每秒发送一次消息来宣布存在,每个sentinel订阅每个master和slave的频道__sentinel__:hello的内容来发现未知sentinel,检测新的sentinel,则加入自身维护的master列表。
每个sentinel发送的消息中包含其当前维护的最新master配置,如果某个sentinel发现自己配置版本低于接收到的配置版本,则用新配置更新自己的master配置。

4 Slave选举与优先级


slave选举考虑以下几方面:
1) 与master断开连接的次数
2) Slave的优先级
3)数据复制下标(评估slave当前拥有多少master数据)
4)进程id

候选人规则:
1) slaves优先级越小排名越靠前
2)优先级相同,看复制下标,哪个从master接收的复制数据多,就越靠前。
3)优先级和下标相同,选择进程ID较小的哪个。

5 获取redis master地址的原理


步骤1:连接到第一个Sentinel
客户端需要遍历Sentinel列表的地址。对于每个地址,它需要使用一个较短的超时时间来尝试连接到Sentinel。如果发生错误或者超时,下一个Sentinel地址将会被尝试。
如果所有的Sentinel地址都尝试了都不能成功的话,一个错误会被返回给客户端。
第一个应答client的sentinel应该被放在列表的头部,这样在下一次重连的时候,我们将首先尝试这个sentinel是否可达来最小化延迟。

步骤2: 请求master地址
一旦与Sentinel的连接建立后,客户端应该在sentinel中尝试去执行下面的命令:
SENTINEL get-master-addr-by-name master-name
注意: 请将上述master-name替换为真实的master名称。

返回的结果是包含两部分:
一个ip:port的二元组。
如果接收到一个 ip:port,该地址就是被用于连接到redis  master的地址。否则,如果接收到的是一个空的应答,客户端需要尝试列表中的下一个sentinel。

样例结果如下:
bash-4.4$ redis-cli -p 26379
127.0.0.1:26379> sentinel get-master-addr-by-name mymaster
1) "10.233.65.74"
2) "6379"

步骤3: 在目标实例上调用ROLE命令
一旦客户端发现了master的地址,它应该尝试与master建立一次连接,并且调用ROLE命令来验证该连接的实例是否真的是一个master。
如果该连接的实例不是master,客户端应该等待一个较短的时间,然后继续从步骤1开始执行。


处理重连
一旦服务名称被解析为master的地址,一个与redis master的连接建立后,每次当需要重新连接时,客户端应该使用sentinels从步骤1再次解析地址.
总结:
redis-ha解析获取master 地址的原理:
步骤1: 获取sentinel的ip:port组成的列表,遍历该列表,
            1.1 如果当前sentinel的ip:port可以连接到该sentinel,
然后就发送命令:sentinel get-master-addr-by-name <master-name>
来获取master的ip地址,并执行步骤2
        1.2 否则,继续遍历下一个sentinel的ip:port
步骤2: 建立与master的连接,并执行一个ROLE命令来判定连接的是否真的是master,
             2.1 如果是master,保持与master的连接。
              2.2 否则,转步骤1
 如果现主备切换等需要重新连接的情况,会再次从步骤1开始执行,直到解析出master的地址。

二、redis-ha环境搭建


1 下载镜像


下面是社区镜像地址
https://quay.io/repository/smile/redis?tag=latest&tab=tags 
注意: 社区使用的镜像是:
quay.io/smile/redis:4.0.11-r1


2  下载redis-ha的charts


具体地址:
https://github.com/helm/charts/tree/master/stable/redis-ha 
注意: 该代码必须是基于statefulset的redis-ha而不是原来基于deployment的redis-ha


3 修改redis-ha的charts


3.1 在redis-ha的values.yaml中redis.config下添加一行
protected-mode: "no"
具体修改后的样例如下所示:
redis:
  port: 6379
  masterGroupName: mymaster
  config:
    ## Additional redis conf options can be added below
    ## For all available options see http://download.redis.io/redis-stable/redis.conf
    min-slaves-to-write: 1
    min-slaves-max-lag: 5   # Value in seconds
    maxmemory: "0"       # Max memory to use for each redis instance. Default is unlimited.
    maxmemory-policy: "volatile-lru"  # Max memory policy to use for each redis instance. Default is volatile-lru.
    # Determines if scheduled RDB backups are created. Default is false.
    # Please note that local (on-disk) RDBs will still be created when re-syncing with a new slave. The only way to prevent this is to enable diskless replication.
    save: "900 1"
    # When enabled, directly sends the RDB over the wire to slaves, without using the disk as intermediate storage. Default is false.
    repl-diskless-sync: "yes"
    rdbcompression: "yes"
    rdbchecksum: "yes"
    protected-mode: "no"

解释:
redis没有bind和密码的情况下,保护模式开启,拒绝其他sentinel连接,会导致主备切换不成功。所以要解除保护模式。即进行上述操作。
参考:
https://blog.csdn.net/csdn_ds/article/details/72550898

3.2 在redis-ha的redis-ha-configmap.yaml中
sentinel.conf的
dir "/data"
下添加如下内容:
{ {- $protectedMode :=  index .Values.redis.config "protected-mode" }}
protected-mode { { $protectedMode }}
具体修改后的样例如下所示:
  sentinel.conf: |
{ {- if .Values.sentinel.customConfig }}
{ { .Values.sentinel.customConfig | indent 4 }}
{ {- else }}
    dir "/data"
    { {- $protectedMode :=  index .Values.redis.config "protected-mode" }}
    protected-mode { { $protectedMode }}
    { {- $root := . -}}


3.3 根据需要是否修改persistentVolume的storageClass
默认是:

persistentVolume:
  enabled: true
  ## redis-ha data Persistent Volume Storage Class
  ## If defined, storageClassName: <stor

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值