文章目录

  • 1. 在linux下安装redis
  • 2. redis主从架构
    • 2.1 redis主从架构搭建步骤
    • 2.2 redis主从架构数据同步原理
    • 2.3 如果在主从传输过程中,从节点挂了怎么办?
    • 2.4 什么是主从复制风暴?
  • 3. redis哨兵高可用架构
    • 3.1 redis哨兵架构搭建步骤
    • 3.2 哨兵的主要作用
    • 3.3 哨兵leader选举流程
  • 4. redis集群高可用架构
    • 4.1 redis高可用集群搭建
    • 4.2 redis集群的槽位存储原理
    • 4.2 redis集群节点之间的通信机制
    • 4.3 redis集群选举原理
    • 4.4 redis的脑裂问题

1. 在linux下安装redis

下载地址:http://redis.io/download
安装步骤:
# 安装gcc
yum install gcc# 把下载好的redis-5.0.3.tar.gz放在/usr/local文件夹下(可以使用Xftp传输)
wget http://download.redis.io/releases/redis-5.0.3.tar.gz# 解压
tar xzf redis-5.0.3.tar.gz
cd redis-5.0.3# 进入到解压好的redis-5.0.3目录下,进行编译与安装
make# 修改配置
daemonize yes  #后台启动
protected-mode no  #关闭保护模式,开启的话,只有本机才可以访问redis
# 需要注释掉bind,如果开启只能通过自己服务器连接redis,多个redis之间无法连接,无法通信
#bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)# 启动服务
src/redis-server redis.conf# 验证启动是否成功
ps -ef | grep redis # 进入redis客户端
src/redis-cli # 退出客户端
quit# 退出redis服务:
(1)pkill redis-server
(2)kill 进程号
(3)src/redis-cli shutdown

如果使用make命令编译redis失败,出现
“没有名为‘xxx’的成员”
“警告:在有返回值的函数中,控制流程到达函数尾”等情况时,可能是gcc版本过低,具体请看此链接
解决make编译redis失败的方式

2. redis主从架构

redis主从架构可以配置一主一从、一主多从等结构,主要是从主节点读写数据,从节点多用于备份数据!

2.1 redis主从架构搭建步骤

1、复制一份redis.conf文件2、将相关配置修改为如下值:
port 6380
pidfile /var/run/redis_6380.pid  # 把pid进程号写入pidfile配置的文件
logfile "6380.log"
dir /usr/local/redis-5.0.3/data/6380  # 指定数据存放目录
# 需要注释掉bind
# bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)3、配置主从复制
replicaof 192.168.0.60 6379   # 从本机6379的redis实例复制数据,Redis 5.0之前使用slaveof
replica-read-only yes  # 配置从节点只读4、启动从节点
redis-server redis.conf5、连接从节点
redis-cli -p 63806、测试在6379实例上写数据,6380实例是否能及时同步新修改数据

2.2 redis主从架构数据同步原理

如果为reids配置了主从架构,那么从服务器启动时是怎么从主服务器中同步数据的呢?具体的流程图如下:

  • ①:从服务器slave先于主服务器master建立socket长连接
  • ②:从服务器slave向主服务器master发送一个PSYNC命令,请求复制数据。
  • ③:主服务器master接收到PSYNC命令后,会通过bgsave命令利用子线程生成最新的rdb快照文件,并发送给从服务器slave。持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存repl buffer中
  • ④:slave清掉无用数据,并接受master传来的数据加载到内存中
  • ⑤:master再将之前持久化时缓存在内存中的命令发送给slave。
  • ⑥:slave接受master发过来的新命令并执行
  • ⑦:此时数据已同步完毕,当master再有新的写操作,会通过socket长连接持续的发给slave,保证主从数据一致性!

注意: 如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。

2.3 如果在主从传输过程中,从节点挂了怎么办?

当salve因为网络等原因接收到一半数据时挂掉了,经过一段时间后,人为的重启了salve从节点,那么此时的数据传输是怎么处理呢?

答:从redis2.8版本开始,redis改用可以支持部分数据复制的命令PSYNC去master同步数据,slave与master能够在网络连接断开重连后只进行部分数据复制(断点续传)。流程图如下:

  • ①:首先redis在运行时会默认开启一个缓存池,用于缓存最近的redis命令,可以在redis.config中配置

    # repl-backlog-size 1mb        redis命令缓存池,默认大小为1Mb
    
  • ②:当slave与master断开并重新建立连接时,slave会向master发送PSYNC命令,并通过offset偏移量定位到断开连接时传输数据的位置,从这个位置开始进行断点续传
  • ③:如果slave节点断开时间太久,导致偏移量太旧,已经在master中的命令缓存池中找不到对应的位置,那么就会进行一次全量数据的复制。无法使用断点续传了!

2.4 什么是主从复制风暴?

主从复制风暴:多个从节点同时复制主节点导致主节点压力过大
为了解决主从复制风暴问题,可以让部分从节点与从节点同步数据,架构如下设计:

3. redis哨兵高可用架构

sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点的状态!

哨兵架构下client端第一次请求redis服务时,会通过哨兵找出redis的主节点,后续就直接访问redis的主节点不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)

3.1 redis哨兵架构搭建步骤

1、复制一份sentinel.conf文件
cp sentinel.conf sentinel-26379.conf2、将相关配置修改为如下值:
port 26379
daemonize yes
pidfile "/var/run/redis-sentinel-26379.pid"
logfile "26379.log"
dir /usr/local/redis-5.0.3/data# sentinel monitor <master-redis-name> <master-redis-ip> <master-redis-port> <quorum>
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
# 推荐哨兵设为最少3个
# mymaster这个名字随便取,客户端访问时会用到
sentinel monitor mymaster 192.168.0.60 6379 2   3、启动sentinel哨兵实例
src/redis-sentinel sentinel-26379.conf4、查看sentinel的info信息
src/redis-cli -p 26379
127.0.0.1:26379>info
可以看到Sentinel的info里已经识别出了redis的主从5、可以自己再配置两个sentinel,端口26380和26381

注意:每个哨兵sentinel中的唯一标志myid一定不能一样,如果一样则只代表一个哨兵。删掉启动时会自动生成

创建完成后可以进入监听的master客户端,使用info命令查看哨兵、从服务器配置情况

Info:查看redis服务运行信息,分为 9 大块,每个块都有非常多的参数,这 9 块分别是:

Server 服务器运行的环境参数
Clients 客户端相关信息
Memory 服务器运行内存统计数据
Persistence 持久化信息
Stats 通用统计数据
Replication 主从复制相关信息
CPU CPU 使用情况
Cluster 集群信息
KeySpace 键值对统计数量信息

当哨兵启动完成,会往sentinel-xxx.conf配置文件的底部增添一些master的从节点信息,如下所示,如果有这些说明哨兵搭建成功!

3.2 哨兵的主要作用

现象: 当master节点挂掉后,服务端控制台会打印 连接超时错误,当过一段时间后,又恢复正常,可以继续向redis中写入数据!

原因: 原因就是哨兵会时刻监视着master节点,当master节点挂掉,此时服务端控制台会打印连接超时错误。但同时哨兵经过半数机制确认master挂掉,会选举出一个slave作为新的master(默认3分钟),选举的这顿时间内,控制台还是会打印错误,一旦选举成功,就会通知client并恢复正常连接,这也是出现以上现象的原因!!当原来挂掉的master节点重新恢复时,将自动称为新的master的丛节点,完成哨兵高可用架构!

注意: 当master节点挂掉,哨兵选举新节点的这个时间内,整个redis架构会挂掉,无法对外提供服务!

3.3 哨兵leader选举流程

当一个master服务器被某sentinel视为下线状态后,哨兵会选举出一个新的master,大概流程如下:

  • ①:哨兵先与其他哨兵协商,选出一个哨兵leader。如果所有超过一半的sentinel选举某哨兵A作为leader,那这个哨兵A就是leader。如果只有一个哨兵,自己就是leader
  • ②:之后该哨兵leader从存活的slave中选举出新的master

为了高可用一般都推荐至少部署三个哨兵节点,且节点数为基数,这样做的原理和redis集群类似

4. redis集群高可用架构

在redis3.0以前的版本要实现集群一般是借助哨兵sentinel来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master。这种方式足以应对一般的QPS,但在面对很高并发的场景时,也会存在以下几个缺点:

  • ①:主从切换瞬间会存在访问访问瞬断的情况,此时redis无法对外提供服务
  • ②:哨兵模式只有一个主节点对外提供服务,没法支持很高的并发(单台redis最高大概10w左右)
  • ③:单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率,引发主从复制风暴!

总之,在高并发场景下哨兵架构的配置略微复杂,并且性能和高可用性等各方面表现一般。为了应对这个问题,redis3.0以后引入了redis集群架构,redis集群架构如下:

redis集群是一个由多个主从节点群 组成的分布式服务器群,它具有复制、高可用和数据分片存储特性。redis集群包含哨兵的功能,所以不需要配置哨兵也可以完成半数选举新节点的功能!

redis集群在处理数据时是分片存储 且 没有中心节点,故可水平扩展,可根据实际场景(双11和平时)进行服务器动态扩容缩容,官方推荐不超过1000个节点。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单!

4.1 redis高可用集群搭建

集群搭建步骤如下,可以单机搭建,也可多台服务器搭建

第一步:在第一台机器的/usr/local下创建文件夹redis-cluster,然后在其下面分别创建2个文件夾如下
(1)mkdir -p /usr/local/redis-cluster
(2)mkdir 8001 8004第一步:把之前的redis.conf配置文件copy到8001下,修改如下内容:
(1)daemonize yes
(2)port 8001(分别对每个机器的端口号进行设置)
(3)pidfile /var/run/redis_8001.pid  # 把pid进程号写入pidfile配置的文件
(4)dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)//5、6、7步是针对集群的操作
(5)cluster-enabled yes(启动集群模式)
(6)cluster-config-file nodes-8001.conf(集群节点信息文件,相当于cluster nodes命令查看节点信息,这里800x最好和port对应上)
(7)cluster-node-timeout 10000(8)# bind 127.0.0.1(bind绑定的是自己机器网卡的ip,如果有多块网卡可以配多个ip,代表允许客户端通过机器的哪些网卡ip去访问,内网一般可以不配置bind,注释掉即可)(9)protected-mode  no   (关闭保护模式)(10)appendonly yes         (开启Aof持久化)
如果要设置密码需要增加如下配置:(11)requirepass zhuge     (设置redis访问密码)(12)masterauth zhuge      (设置集群节点间访问密码,跟上面一致)第三步:把修改后的配置文件,copy到8004,修改第2、3、4、6项里的端口号,可以用批量替换:
:%s/源字符串/目的字符串/g 第四步:另外两台机器也需要做上面几步操作,第二台机器用8002和8005,第三台机器用8003和8006第五步:分别启动6个redis实例,然后检查是否启动成功
(1)/usr/local/redis-5.0.3/src/redis-server /usr/local/redis-cluster/800*/redis.conf
(2)ps -ef | grep redis 查看是否启动成功第六步:用redis-cli创建整个redis集群(redis5以前的版本集群是依靠ruby脚本redis-trib.rb实现)
# 下面命令里的1代表为每个创建的主服务器节点创建一个从服务器节点
# 执行这条命令需要确认三台机器之间的redis实例要能相互访问,
# 可以先简单把所有机器防火墙关掉,如果不关闭防火墙则需要打开redis服务端口和集群节点gossip通信端口16379(默认是在redis端口号上加1W)
# 关闭防火墙
# systemctl stop firewalld # 临时关闭防火墙
# systemctl disable firewalld # 禁止开机启动
(1)/usr/local/redis-5.0.3/src/redis-cli -a zhuge--cluster create --cluster-replicas 1 192.168.0.61:8001 192.168.0.62:8002 192.168.0.63:8003 192.168.0.61:8004 192.168.0.62:8005 192.168.0.63:8006 第七步:验证集群:
(1)连接任意一个客户端即可:./redis-cli -c -h -p (-a访问服务端密码,-c表示集群模式,指定ip地址和端口号)如:/usr/local/redis-5.0.3/src/redis-cli -a zhuge -c -h 192.168.0.61 -p 800*
(2)进行验证: cluster info(查看集群信息)、cluster nodes(查看节点列表)
(3)进行数据操作验证
(4)关闭集群则需要逐个进行关闭,使用命令:
/usr/local/redis-5.0.3/src/redis-cli -a zhuge -c -h 192.168.0.60 -p 800* shutdown

问题一: 如何创建集群?

在这里采用一台机器部署redis集群的方式,分别启动8001、8002、8003、8004、8005、8006端口的redis后,结果如下:


此时要组成集群的6个redis节点已启动成功,但他们之间还没有任何关系,通过客户端命令可以为他们组建集群关系,下面的组建集群关系命令只在redis5.0以后有用,redis5.0之前的是依靠ruby脚本redis-trib.rb实现的!!

# --cluster create       创建集群关系
# --cluster-replicas 1      每一个集群主节点配置一个从节点
redis-6.0.9/src/redis-cli  --cluster create  --cluster-replicas 1 192.168.100.100:8001 192.168.100.100:8002 192.168.100.100:8003 192.168.100.100:8004 192.168.100.100:8005 192.168.100.100:8006

输入命令后,会为每个集群节点分配槽位!那为什么会有槽位分配呢?

因为redis集群的数据是分片(分槽位slot)来存储的,所以每个集群节点在建立集群关系时,会分到不同区间的槽位,一共16384个槽位供数据存储!

在集群模式下,当操作redis客户端存储数据时,数据的key会与16384进行%运算,运算结果决定存储在哪个槽位上,这个槽位又被分配在redis集群中的某个master节点上,所以要存储的数据也就存储在这个master节点上!

分配槽位详情如下:

然后确定槽位分配,集群关系组建成功的标志如下:

连接任意一个客户端进行验证:

# -c 代表集群模式src/redis-cli -c -h 192.168.100.100 -p 8001

进入8001的客户端,在客户端中使用cluster info命令查看集群信息

在客户端中使用cluster nodes命令查看集群信息如下:
三主三从,每一台服务器对应一个唯一id,通过观察从服务器依赖的id,可以知道从服务器依赖于哪一台master!

问题二:集群关闭后,如何重新启动?

如果要重启集群,千万不要使用上边的创建集群命令!!只需要把之前已经搭建好的6个集群节点使用 redis-server config 的方式逐一启动即可! 启动完成后,他们会自动建立集群关系!

因为我们之前在节点的配置文件中配置了节点信息存储目录,节点启动时会自动去该目录下找到并根据该配置建立集群关系

cluster-config-file nodes-8001.conf(集群节点信息文件,相当于cluster nodes命令查看节点信息,这里800x最好和port对应上)

8001的节点信息nodes-8001.conf配置如下,可以看到和上边的cluster nodes命令结果一样!

 
问题三:如果集群中的某个master节点挂掉,整个集群还可用吗?

redis集群默认一个master节点挂掉,整个集群不可用,但是可以修改配置文件使集群可用

注意:

# 为no表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用
# 为yes则不可用
cluster-require-full-coverage = no

问题四: redis集群为什么至少需要三个master节点,并且推荐节点数为奇数?
        因为新master的选举需要大于半数的集群master节点同意才能选举成功,如果只有两个master节点,当其中一个挂了,是达不到选举新master的条件的。

奇数个master节点可以在满足选举该条件的基础上节省一个节点,比如三个master节点和四个master节点的集群相比,大家如果都挂了一个master节点都能选举新master节点,如果都挂了两个master节点都没法选举新master节点了(因为选举需要大于2票,就剩余两个master,最大=2),所以奇数的master节点更多的是从节省机器资源角度出发说的。

问题五:redis集群支持批量操作命令吗?
        如果直接使用mset,mget这样的多个key的原生批量操作命令,会执行失败,因为redis集群只支持所有key落在同一槽位slot的情况,多个key可能落在不同的槽位slot中!

如果有多个key一定要用mset命令在redis集群上操作,则可以在key的前面加上{XX},这样参数数据分片hash计算的只会是大括号里的值,这样能确保不同的key能落到同一slot里去,示例如下:

mset {user1}:1:name zhuge {user1}:1:age 18

假设name和age计算的hash slot值不一样,但是这条命令在集群下执行,redis只会用大括号里的 user1 做hash slot计算,所以算出来的slot值肯定相同,最后都能落在同一槽位slot中!

4.2 redis集群的槽位存储原理

Redis Cluster 将所有数据划分为 16384 个 slots(槽位),每个节点负责其中一部分槽位。槽位的信息存储于每个节点中。在Springboot项目中,当 Redis Cluster 的客户端(jedis、redistemplate等) 来连接集群时,它也会得到一份集群的槽位配置信息并将其缓存在本地。这样当客户端要查找某个 key 时,通过槽位定位算法可以直接定位到目标节点。同时因为槽位的信息可能会存在客户端与服务器不一致的情况(比如集群数据迁移、集群扩容缩容等),还需要纠正机制来实现槽位信息的校验调整。

槽位定位算法

redis集群默认会对 key 值使用 crc16 算法进行 hash 得到一个整数值,然后用这个整数值对 16384 进行取模来得到具体槽位。核心算法如下:HASH_SLOT = CRC16(key) mod 16384

跳转重定位

当时用redis客户端命令set向redis存储k-v值时

  • ①:如果当前key根据槽位定位算法算得槽位在当前master节点的槽位区间内,则把数据存储在当前master节点中
  • ②:如果发生集群数据迁移、集群扩容等操作,本地缓存还未来得及修改槽位信息!那么当前key经过槽位定位算法算得槽位可能不在当前master节点的槽位区间内,这时它会向客户端发送一个特殊的跳转指令,这个指令携带了能匹配当前key的槽位值的节点地址,告诉客户端去这个节点操作数据。客户端收到指令后除了跳转到正确的节点上去操作,还会同步更新纠正本地的槽位映射表缓存,后续所有 key 将使用新的槽位映射表。

4.2 redis集群节点之间的通信机制

redis集群中一个节点挂掉后,别的节点可以及时感知到,并选举出新的节点,这其中就依赖于节点之间的通信机制!维护集群的元数据通信方式大概有两种:集中式和gossip 。redis cluster节点间采取gossip协议进行通信! 两种通信方式介绍如下:

集中式:

  1. 优点:元数据的更新和读取,时效性非常好,一旦元数据出现变更立即就会更新到集中式的存储中,其他节点读取的时候立即就可以立即感知到
  2. 缺点:所有的元数据的更新压力全部集中在一个地方,可能导致元数据的存储压力

zookeeper就是借助集中式来哦存储数据信息!

gossip:

  1. 优点:元数据的更新比较分散,不是集中在一个地方,节点更新请求会陆陆续续,打到所有节点上去更新,有一定的延时,具有最终一致性!但不会有元数据的集中存储,降低了存储压力!
  2. 缺点:元数据更新有延时可能导致集群的一些操作会有一些滞后。所以不推荐集群节点个数太多!

每个节点都有一个专门用于节点间gossip通信的端口,就是自己提供服务的端口号+10000,比如7001,那么用于节点间通信的就是17001端口。

gossip协议包含多种消息,包括ping,pong,meet,fail等等。

  • meet:某个节点发送meet给新加入的节点,让新节点加入集群中,然后新节点就会开始与其他节点进行通 信;
  • ping:每个节点都会频繁给其他节点发送ping,其中包含自己的状态还有自己维护的集群元数据,互相通过 ping交换元数据(类似自己感知到的集群节点增加和移除,hash slot信息等);
  • pong: 对ping和meet消息的返回,包含自己的状态和其他信息,也可以用于信息广播和更新;
  • fail: 某个节点判断另一个节点fail之后,就发送fail给其他节点,通知其他节点,指定的节点宕机了。

通信超时时间设置

机房网络往往并不是风平浪静的,比如网络波动就是非常常见的一种现象,突然之间部分连接变得不可访问,然后很快又恢复正常。如果集群节点的通信因为网络波动而认为有节点挂掉,进而触发选举机制,那么网络波动结束后,旧的master节点恢复了连接,然而又选举出了一个新的master节点!两个master节点同时对外提供服务,就会出现脑裂问题。

为了防止因网络波动产生脑裂,Redis Cluster 提供了一种选项cluster-node-timeout 设置连接超时时间,表示当某个节点持续 timeout 的时间失联时,才可以认定该节点出现故障,需要进行主从切换。如果没有这个选项,网络抖动会导致主从频繁切换 (数据的重新复制)。

4.3 redis集群选举原理

当slave发现自己的master变为FAIL状态时,并不是马上尝试发起选举,而是有一定延迟,一定的延迟确保我们等待FAIL状态在集群中传播完毕,slave如果立即尝试选举,其它masters或许尚未意识到FAIL状态,可能会拒绝投票。延迟之后slave便尝试成为新的master。

延迟计算公式:
DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

说明:SLAVE_RANK表示此slave已经从master复制数据的总量的rank。Rank越小代表已复制的数据越新。这种方式下,持有最新数据的slave将会首先发起选举(理论上)。

由于挂掉的master可能会有多个slave,从而存在多个slave竞争成为master节点的过程, 其过程如下:

  • ①:slave发现自己的master变为FAIL
  • ②:将记录集群选举次数currentEpoch加1,并向其他节点广播,发送信息为自己拉票
  • ③:其他节点收到该信息,只有master响应,判断请求者的合法性,并返回FAILOVER_AUTH_ACK,对每一个slave的请求只发送一次ack
  • ④:尝试成为新的master的slave收集到其他master返回的FAILOVER_AUTH_ACK
  • ⑤:slave收到超过半数master的ack后变成新Master (这里解释了集群为什么至少需要三个主节点,如果只有两个,当其中一个挂了,只剩一个主节点是不能选举成功的)
  • ⑥:slave广播Pong消息通知其他集群节点自己已成为新的master!
  • ⑦:当旧的master复活后,会变成新的master的从节点

如果多个slave第一次竞选票数一样,则会把集群选举次数currentEpoch加1,再次执行上面的步骤进行选举!

4.4 redis的脑裂问题

redis的脑裂问题在哨兵模式和集群模式都可能存在:

哨兵模式的脑裂:

如上图,1个master与3个slave组成的哨兵模式(哨兵独立部署于其它机器),刚开始时,2个应用服务器server1、server2都连接在master上,视为正常情况。

如果masterslave及哨兵sentinel之间的网络发生故障,但是哨兵与slave之间通讯正常,这时3个slave其中1个经过哨兵投票后,提升为新master,如果恰好此时server1仍然连接的是旧的master,而server2连接到了新的master上。数据就不一致了,基于setNX指令的分布式锁,可能会拿到相同的锁;基于incr生成的全局唯一id,也可能出现重复。

集群模式的脑裂:

上文说到为防止网络波动产生脑裂问题,可以配置cluster-node-timeout 设置连接超时时间来预防。但是当连接时间超出cluster-node-timeout设置的值,还是会选举出新的master节点,此时旧的master节点如果恢复连接,还是会因为存在多个master节点对外提供服务而产生脑裂!!

生产环境下,由于redis master节点和redis salve节点处于不同的网络分区,当网络分区恢复(ping通)之前,有两个master节点对外提供服务,在提供服务期间:可能会存在数据不一致问题:

  • 基于setNX指令的分布式锁,可能会拿到相同的锁
  • 基于incr指令生成的全局唯一id,也可能出现重复

当网络分区恢复之后,redis会把旧的master节点变为新的master节点的slave节点,并同步新的master节点的数据。但同时会带来一个新的问题,旧节点上的数据会被删除,如果它在作为master对外提供服务的时间内,处理了很多命令,那么被删除的话就会丢失一部分数据!具体过程如下图所示:

正常状态:

网络发生中断:如果此时master服务器所在区域网络通信出现异常,导致和两台slave机器无法正常通信,但是和客户端的连接是正常的。那么sentinel就会从两台slave机器中选举其中一个作为新的master来处理客户端请求。如图


网络恢复后: 旧master节点变为新master节点的从节点,旧master上的数据会被删除。在网络发生中断期间,旧master从客户端接收到的数据全部丢失!

脑裂问题的解决方案

可以在redis配置里加上参数(这种方法不可能百分百避免数据丢失):

# 写数据成功最少同步的slave数量
# 这个数量可以模仿大于半数机制配置,比如集群总共三个节点可以配置1,加上leader就是2,超过了半数
min-slaves-to-write 1  # 主从数据同步超时时间,10秒。
min-slaves-max-lag 10

根据以上配置可以将master通信异常期间的数据丢失控制在10秒以内,但同时在一定程度上会影响集群的可用性,比如slave要是少于1个,这个集群就算leader正常也不能提供服务了,需要具体场景权衡选择。

redis专题:redis的主从、哨兵、集群架构的配置和部署详情、以及问题分析相关推荐

  1. redis 主从 哨兵 集群 及原理

    1.主从哨兵 1.主从哨兵架构图: 此图为最常见的一主两从结构,一个master主机,两个slave主机.每台主机上都运行着两个进程: redis-server 服务,处理redis正常的数据操作与响 ...

  2. Redis分片主从哨兵集群,原理详解,集群的配置安装,8大数据类型,springboot整合使用

    文章目录 Redis介绍 Redis分片 Redis主从 Redis哨兵 Redis集群 Redis持久化策略 RDB AOF 持久化方案选择 Redis内存策略 LRU算法 LFU算法 Random ...

  3. Redis进阶-主从,哨兵,集群

    主从复制 master-slave主从 同时运行多个redis服务端,其中一个作为主(master),其他的一个或多个作为从(slave),主从之间通过网络进行通讯,slave通过复制master的数 ...

  4. redis 主从 哨兵 集群部署

    介绍 Redis是当前比较热门的NOSQL系统之一,它是一个key-value存储系统.和Memcache类似,但很大程度补偿了Memcache的不足,它支持存储的value类型相对更多,包括stri ...

  5. redis学习-主从-哨兵集群-redis-cluster简单日记

    1.linux下redis安装及部署 redis安装包与ruby安装包下载 (转)Linux下Redis的安装与部署 2.常用命令及简单配置注解 redis-server redis.conf: 启动 ...

  6. mysql进阶:canal搭建主从|集群架构

    0.引言 之前我们讲解过canal的各种应用,但是对于生产环境来讲,服务高可用是必须保证的.因此canal单节点是不能满足我们的需求的.就需要搭建canal集群. 1. canal集群模式 从架构方式 ...

  7. Redis主从哨兵集群模式概念以及搭建

    目录 前言 一.Redis使用准备工作 1.1.下载redis 1.2.安装redis 二.Redis部署 2.1.单节点模式部署 2.2.主从模式部署 2.2.1 主从模式的感念: 2.2.2 主从 ...

  8. 如何保证 Redis 高可用和高并发(主从+哨兵+集群)

    1. 概述 Redis 作为一种高性能的内存数据库,普遍用于目前主流的分布式架构系统中.为了提高系统的容错率,使用多实例的 Redis 也是必不可免的,但同样复杂度也相比单实例高出很多. 那么如何保证 ...

  9. Redis主从哨兵集群

    更多精彩内容请关注 微信公众号:LifeSmile 个人网站:www.lifesmile.cn Redis:Redis主从复制哨兵机制及集群搭建 Redis主从复制 什么是主从复制 持久化保证了即使R ...

最新文章

  1. MySQL慢查询日志分析(一)
  2. 百练4103:踩方格
  3. CodeForces - 287C Lucky Permutation(构造)
  4. 杰瑞服务器虚拟化,大家在Mac中开发PHP,是用虚拟机的方式还是直接在Mac下搭建环境...
  5. synchronized 解决死锁的问题 轉貼
  6. 护理在计算机的应用研究,计算机虚拟和模拟技术在护理实践教学中应用的研究...
  7. 仿任务面板 跨多个RecyclerView的Item拖动 支持缩小后拖动
  8. VC6.0+XT库+OPENCV1.0调试笔记
  9. 在.cpp文件中调用.c文件中的函数
  10. Open mv识别图形形状及颜色
  11. CDA-分角色用户查询
  12. 解决训练时显存不断增大问题
  13. 神棍节献礼之——URAL1111 Squares(几何)
  14. 计算机体系架构(1)计算机组成原理
  15. linux使用命令将po与mo文件进行转换
  16. 【面向对象程序设计】侩子手游戏(Java、JavaFX)
  17. MySQL数据备份批处理
  18. 杰理之关于608n省晶振模式使用PWM_LED的注意事项【篇】
  19. 优酷鸿蒙开发实践|多屏互动开发实践
  20. input 金额格式校验

热门文章

  1. win7分区c盘调整容量_C盘空间不足变红咋办?清理垃圾瘦身不如扩容,硬盘容量调整教程...
  2. Java中的抽象类和接口(interface),abstract关键字的用法
  3. boot sprint 项目结构_Spring Boot 项目结构
  4. mysql not default_MySQL的not null default
  5. python判断某年是否为闰年的程序_Python 学习--从0到1(4. 题3)
  6. python openstack vpc互通_深入浅出新一代云网络——VPC中的那些功能与基于OpenStack Neutron的实现(一)-简述与端口转发...
  7. 基于prometheus + grafana + mysql + Telegram 监控告警
  8. 艾媒:ofo活跃用户规模为摩拜近2倍 每10辆共享单车7辆小黄车
  9. [LeetCode] NO. 8 String to Integer (atoi)
  10. 五大常用算法:分治、动态规划、贪心、回溯、分支限界