侧边栏壁纸
  • 累计撰写 57 篇文章
  • 累计创建 23 个标签
  • 累计收到 4 条评论

Redis集群

cluski
2022-03-16 / 0 评论 / 0 点赞 / 301 阅读 / 7,569 字
温馨提示:
本文最后更新于 2022-04-03,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Redis集群

1 主从赋值

1.1 主从复制原理

主从复制可以减轻主服务器的压力,同时备份数据保证数据的可靠性。主从复制(master-salve
replacation)模式是为目标服务器创建拥有一个或多个副本的服务器,其中目标服务器被称为主服务器
(master server) ,副本服务器被称为从服务器 (slave server或称为replica)
一主一从:

image-20210911204913985

一主多从:

image-20210911205036043

说明:

  1. 一台主服务器可以有多台从服务器,但一台从服务器只能有一台主服务器。
  2. 主服务器中的数据和从服务器上的数据保持实时同步,当主服务器接收到写命令时会通过主从复制机制将命令同步给从服务器。
  3. 主从复制不会阻塞master,在同步数据时,master可以继续处理client请求,主服务器可以处理读写请求,而从服务器只能处理读请求。(当然2.6版本以后从服务器可以设置为可写的从服务器,但会造成
    数据不一致所以不建议这么设置)

1.2 主从配置

之前版本的Redis,配置为SLAVEOF,现在改为REPLICAOF。主从模式,可以是树状的,从服务属于多台
主服务,且从服务也可以有从服务。主从模式,可实现读写分离;高可用模式下,主服务出现问题,也可以通过哨兵切换从服务为主服务,可实现主服务不用数据持久化,从服务进行持久化工作,减轻主服务负担等等。

  1. 创建三个Redis实例(赋值),一个master(主服务器)、两个slave(从服务器)

  2. master实例不做任何特殊配置。

  3. 修改从服务器的端口号

    port 6380
    port 6381
    
  4. 修改从节点replicaof参数,指定主服务器的ip和端口号(默认该参数被注释掉了)
    replicaof <masterip> <masterport>

  5. 修改主节点的密码(默认该参数被注释掉了)
    masterauth <master-password>

1.3 测试

# 从节点一
Aliyun2# ./redis-cli -a WYF0331cl -p 6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380> keys *
(empty list or set)
127.0.0.1:6380> role
1) "slave"
2) "127.0.0.1"
3) (integer) 6379
4) "connected"
5) (integer) 126

# 从节点二
Aliyun2# ./redis-cli -a WYF0331cl -p 6381
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6381> role
1) "slave"
2) "127.0.0.1"
3) (integer) 6379
4) "connected"
5) (integer) 140

# master节点
Aliyun2# ./redis-cli -a WYF0331cl -p 6379
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> role
1) "master"
2) (integer) 182
3) 1) 1) "127.0.0.1"
      2) "6380"
      3) "182"
   2) 1) "127.0.0.1"
      2) "6381"
      3) "182"

主节点设置值:

# 主节点设置值
127.0.0.1:6379> set name lisi
OK
127.0.0.1:6379> get name
"lisi"
127.0.0.1:6379>

# 从节点一获取name
Aliyun2# ./redis-cli -a WYF0331cl -p 6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380> get name
"lisi"
127.0.0.1:6380>

# 从节点二获取name
Aliyun2# ./redis-cli -a WYF0331cl -p 6381
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6381> get name
"lisi"

2 哨兵模式

Redis的主从复制模式的弊端:一旦主节点由于故障不能提供服务,需要人工将从节点晋升为主节点,同
时还要通知应用方更新主节点地址,对于很多应用场景这种故障处理的方式是无法接受的。

可喜的是Redis从2.8开始正式提供了Redis Sentinel(哨兵)架构来解决这个问题。

2.1 哨兵模式介绍

Sentinel (哨兵)进程是用于监控Redis集群中Master主服务器工作的状态,在Master主服务器发生故障
下线的时候,将它其中一个从服务器转换为主服务器,并使用新的主服务器继续处理命令请求。

这种正常服务器替换下线服务器以维持系统正常运转的操作,一般被称为故障转移(failover)

自动进行故障转移,保证了系统的高可用 (HA),其已经被集成在Redis2.6+的版本中,Redis的哨兵模式
到了2.8版本之后就稳定了下来。

哨兵(sentinel)会不断地检查你的Master和Slave是否运作正常。当被监控的某个Redis节点出现问题时,哨兵(sentinel)可以通过API向管理员或者其他应用程序发送通知。当一个Master不能正常工作时,哨兵
(sentinel)会开始一次自动故障转移操作。

image-20210911211103928

哨兵是Redis集群架构中非常重要的一个组件,主要功能如下:

  1. 集群监控:负责监控Redis master和slave进程是否正常工作
  2. 消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
  3. 故障转移:如果master服务器挂掉了,会自动转移到slave服务器上
  4. 配置中心:如果故障转移发生了,通知client客户端新的master地址

Sentinel单机部署的弊端:

  • 一旦Sentinel宕机,那么主从服务器的自动故障转移将无法实施。

  • 另外还可能因为Sentinel的网络故障,错误的认为主服务器已下线,继而进行没必要的故障转移操作。因此Sentinel也需要集群部署,并且Sentinel之间相互监控,真正的部署架构图就变成了这样:

image-20210911211534753

2.2 哨兵进程的工作方式

2.2.1 监控过程

  1. 每个Sentinel (哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器、Slave从服务器以及
    其他Sentinel (哨兵)进程发送一个PING命令。
  2. 如果一个Redis实例(instance)距离最后一次有效回复PING命令的时间超过down-after- milliseconds选项所指定的值,则这个实例会被Sentinel (哨兵)进程标记为主观下线
    (SDOWN)
  3. 如果一个Master主服务器被标记为主观下线(SDOWN) ,则正在监视这个Master主服务器的所有
    Sentinel (哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
  4. 当有足够数量的Sentinel (哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master
    主服务器进入了主观下线状态(SDOWN) , 则Master主服务器会被标记为客观下线 (ODOWN) ,然
    后进行故障转移。
  5. 在一般情况下,每个Sentinel (哨兵)进程会以每10秒一次的频率向集群中的所有Master主服务器、
    Slave从服务器发送INFO命令。
  6. 当Master主服务器被Sentinel (哨兵)进程标记为客观下线(ODOWN)时,Sentinel (哨兵)进程向
    下线的Master主服务器的所有Slave从服务器发送INFO命令的频率会从10秒一次改为每秒一次。
  7. 若没有足够数量的Sentinel (哨兵)进程同意Master主服务器下线,Master主服务器的主观下线状态
    就会被移除。若Master主服务器重新向Sentinel (哨兵)进程发送PING命令返回有效回复,Master主
    服务器的主观下线状态就会被移除。

image-20210911213019444

2.2.2 SDOWN (Subjectively Down)和ODOWN (Objectively Downi

  1. SDOWN和ODOWN两种失败状态
  2. SDOWN是主观宕机,就一个哨兵如果自己觉得一个master宕机了,那么就是主观宕机
  3. ODOWN是客观宕机,如果quorum数量的哨兵都觉得一个master宕机了,那么就是客观宕机
  4. SDOWN达成的条件:如果一个哨兵ping一个master,超过了is-master-down-after-
    milliseconds指定的毫秒数之后,就主观认为master宕机
  5. ODOWN达成的条件:如果一个哨兵在指定时间内,收到了quorum指定数量的其他哨兵也认为那个
    master是SDOWN了,那么就认为是ODOWN了,客观认为master宕机

简单来说就是:

SDOWN是我认为你宕机了;

ODOWN是都认为你宕机了。

2.3 Sentinel集群搭建

组建Sentinel集群的方法也非常简单,只需要启动多个Sentinrl并指定Sentinel要监视的主服务器即可
Sentinel会自动发现对方。

为了演示方便我们就复制多个配置文件,模拟多个Sentinel.

  1. 复制sentinel.conf文件并以端口号为后缀,做文件名
  2. 分别修改三个配置文件
# 端口号
port 26379
# 后台守护进程启动
daemonizer yes
#log日志文件名称,名字随便起不重复就行,防止互相覆盖
logfile "26379.log"
# 给主服务器起个名字为: mymaster
# 配置主服务器的地址: 192.168.0.38
# 端口: 6379
# 判断主服务器客观下线的sentinel数量:2
# 假设sentineL数量为n,那么quorum值设置一般为: (n/2) +1,以此来保证,需要超过半数的sentinel才能认定master ODOWN
sentinel monitor mymaster 127.0.0.1 6379 2
# 设置主节点名称和密码
sentinel auth-pass mymaster WYF0331cl

登录其中一个sentinel,使用命令sentinel masters查看:

Aliyun2# ./redis-cli -p 26379
127.0.0.1:26379> sentinel masters
1)  1) "name"
    2) "mymaster"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6379"
    7) "runid"
    8) "a991862c3bdea18bae7c309008a175946b38d946"
    9) "flags"
   10) "master"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "280"
   19) "last-ping-reply"
   20) "280"
   21) "down-after-milliseconds"
   22) "30000"
   23) "info-refresh"
   24) "7650"
   25) "role-reported"
   26) "master"
   27) "role-reported-time"
   28) "57853"
   29) "config-epoch"
   30) "0"
   31) "num-slaves"
   32) "2"
   33) "num-other-sentinels"
   34) "2"
   35) "quorum"
   36) "2"
   37) "failover-timeout"
   38) "180000"
   39) "parallel-syncs"
   40) "1"

kill掉Redis的master节点

Aliyun2# ps -ef | grep redis
root      5444     1  0 21:53 ?        00:00:00 ./redis-sentinel *:26379 [sentinel]
root      5473     1  0 21:53 ?        00:00:00 ./redis-sentinel *:26380 [sentinel]
root      5496     1  0 21:53 ?        00:00:00 ./redis-sentinel *:26381 [sentinel]
root      6388 30079  0 21:55 pts/0    00:00:00 grep redis
root     18913     1  0 21:02 ?        00:00:04 ./redis-server *:6379
root     19028     1  0 21:02 ?        00:00:04 ./redis-server *:6380
root     19086     1  0 21:02 ?        00:00:04 ./redis-server *:6381
Aliyun2# kill 18913

# 随便登录一个Redis,查看role
Aliyun2# ./redis-cli -a WYF0331cl -p 6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380> role
1) "master"
2) (integer) 36759
3) 1) 1) "127.0.0.1"
      2) "6381"
      3) "36612"

3 Redis集群

​ Redis集群是Redis 3.0版本正式开始引入的功能,而Redis 5.0更是在集群原有功能的基础上,进一步添加
了更多新功能,对原有功能做了相当多的优化,使得整个集群系统更简单、易用和高效。

​ Redis集群提供了主从复制功能和类似单机版的Redis Sentinal功能,在集群中每个服务器被称为节点 (node) ,其中主节点(master node)负责处理客户端发送来的读写命令请求,从节点(replica/slave node)则负责对主节点进行复制和监视,集群中的各个节点将相互监视各自的运行状况,并在某个主节点下
线时,通过提升该节点的从节点为新主节点来继续提供服务。

分片:与单机版Redis将整个数据库放在同一台服务器上的做法不同Redis集群通过将数据库分散存储到多个节点上来平衡各个节点的负载压力。具体来说, Redisa会将整个数据库空间划分为16384个槽(slot)来实现数据分片(Sharding) ,而集群中的各个主节点则会分别负责处理其中的一部分槽。

​ 当用户尝试将一个键存储到集群中时,客户端会先计算出该键属于哪个槽,接着在记录集群节点分布的映射
表中找出处理该槽的节点,最后再将键存储到相应的节点中。

image-20211211190645736

3.1 Redis-Cluster架构图

3.2 投票容错

image-20211211191543842

  1. 整个投票过程是集群中所有master参与,如果半数以上master节点与master节点通信超过(cluster-
    node-timeout),认为当前master节点挂掉

  2. 什么时候整个集群不可用(cluster-state:fail)?

    • 如果集群任意master挂掉,且当前master没有slave集群进入fail状态。也可以理解成集群的slot映射
      [0-16383]不完整时进入fail 状态。

    • 如果集群超过半数以上的master挂掉,无论是否有slave集群进入fail状态。

注意:当集群不可用时,所有对集群的操作做都不可用,收到( (error) CLUSTERDOWN The cluster is down )错误

3.3 创建集群

2018年十月Redis发布了稳定版本的5.0版本,推出了各种新特性,其中一点是放弃Ruby的集群方式,改为使用C语言编写的redis-cli的方式,使集群的构建方式复杂度大大降低。

Redis在它的源码中附带了集群自动搭建程序create-cluster,这个程序可以快速构建起一个完整可用的集群以供用户测试。

create-cluster程序位于源码的utils/create-cluster目录下,由于Redis提供的集群创建方式不支持远程连接,而我们一会需要通过客户端来远程连接集群,所以在启动前需要对create-cluster程序做一个修改,主要做两处修改:

3.3.1 修改脚本程序

  1. 添加--protected-mode no参数,关闭保护模式
  2. 修改127.0.0.1为外放访问ip

image-20211211192516040

3.3.2 启动服务

执行命令

./create-cluster start
0

评论区