Redis高可用之持久化、主从复制、哨兵模式、集群

一、Redis高可用

1.1 简介

在web服务器中,高可用是指服务器可以正常访问的时间,衡量的标准是在多长时间内可以提供正常服务(99.9%、99.99%、99.999%等等)。
但是在Redis语境中,高可用的含义似乎要宽泛一些,除了保证提供正常服务(如主从分离、快速容灾技术),还需要考虑数据容量的扩展、数据安全不会丢失等。

1.2 高可用策略

策略概述
持久化持久化是最简单的高可用方法,主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。
主从复制主从复制是高可用Redis的基础,主要实现了数据的多机备份,以及对于读操作的负载均衡和简单的故障恢复
哨兵在主从复制的基础上,哨兵实现了自动化的故障恢复。缺陷:写操作无法负载均衡,存储能力受到单机的限制。
集群通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案。

二、 Redis持久化

2.1简介

Redis是内存数据库,数据都是存储在内存中,为了避免服务器断电等原因导致Redis进程异常退出后数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;

当下次Redis重启时,利用持久化文件实现数据恢复。

除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。

2.2 Redis 的 两种持久化方式

2.2.1 RDB持久化

定时把redis内存中的数据进行快照并压缩保存到硬盘;

RDB持久化保存的文件占用空间小,网络传输快,恢复速度也比AOF快,性能影响比AOF更小;

实时性不如AOF,兼容性较差,持久化期间在fork子进程时会阻塞reids父进程。

2.2.2 AOF持久化

以追加的方式将Redis写操作的命令记录到文件中;

实时性比RDB好,支持秒级持久化,兼容性较好;

持久化保存的文件占用磁盘空间更大,恢复速度更慢,性能影响更大,AOF文件重写期间在fork子进程时会阻塞reids父进程;

两者区别可通过 *工作方式、实时性、磁盘占用、恢复速度、兼容性、IO性能影响等方面进行阐述。

三、Redis主从复制

3.1 什么是主从复制?

Redis主从复制是一种常见的数据复制机制,用于在不同的Redis服务器之间同步数据。

在主从复制中,一个Redis服务器充当主服务器(master),负责接收和处理写入操作,而其他的Redis服务器充当从服务器(slave),通过复制主服务器的数据来保持与主服务器的数据同步。

Redis主从复制是实现读写分离、Redis高可用等的基础。

3.2 为什么要用主从复制?

1)产生Redis单机故障时,可用通过从服务器上进行恢复数据;

2)Redis要实现高可用、高并发,单个Redis也就只能支持几万的QPS,必须以集群的形式提供服务,而集群中又以多个主从组成。

3)主从是以多个redis集合在一起,以一个master多个slave为模式对外提供服务,master主要以写为主,slave提供读,即是读写分离的情况,以读多写少为准。

3.3 主从复制的特性

1)一个master可以有多个slave;

2)一个slave只能有一个master;

3) 数据流是单向的,master到slave;

4)主从复制底层依赖与RDB方式进行全量复制。

3.4 主从复制工作原理

Redis主从之间的复制分为两部分:全量复制和增量复制。

3.4.1 全量复制

Redis在第一次实现主从关系时会进行全量复制

1)Slave 通过 psync命令同步数据与Master建立socket长连接;

2)Master 收到psync命令,执行bgsave语句生成RDB快照;

3)Master发送RDB数据;

4)Slave清空数据并加载Master发来的RDB数据;

5)Master将生成RDB文件过程中,修改的数据,从repl buffer发送给Slave;

6)Slave执行接收到的修改命令;

7)Master通过socket长连接持续把写命令发送给从接单,保证数据一致性。

3.4.2 增量复制

如果由于网络原因造成原因造成主从断开,期间有数据写入master,再次形成主从时,会形成增量复制

1)Slave连接断开;

2)Master最近数据的修改命令的缓存;

3)Slave重新建立Socket长连接到master;

4)Slave psync命令同步数据: offset偏移量控制;

5)Master判断 Slave的offset。如果在repl backlog buffer中,Master会将缓存中从salve的offset之后数据一次性同步给salve节点,否则会全量同步;

6)Master通过socket长连接持续把写命令发送给从节点,保证主从一致性。

3.5 Redis主从同步策略

主从刚刚连接的时候,进行全量同步;全同步结束后,进行增量同步。

当然,如果有需要,slave 在任何时候都可以发起全量同步。

redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步

四、搭建Redis主从复制

节点服务器IP地址
Master192.168.10.20
Slave192.168.10.30
#开机自动关闭防火墙
systemctl  disable firewalld --now


#永久关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config

所有节点服务器安装Redis

过程详见Redis部署和基础命令

Master节点修改 Redis 配置文件

vim /apps/redis/etc/redis.conf
 
bind 127.0.0.1
bind 0.0.0.0               #69行 ,添加监听的主机地址,0.0.0.0表示监听任意地址
protected-mode no     
#89行,将本机访问保护模式设置no。如果开启了,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的响应
port 6379             #93行,Redis默认的监听6379端口
daemonize yes         #137行,设置为守护进程。后台启动
pidfile /apps/redis/run/redis_6379.pid
#159行,指定PID文件
logfile  /apps/redis/log/redis.log
#172行,指定日志文件
dir /apps/redis/data
#264行,指定持久化文件所在目录
#requirepass abc123	 
#508行,增加一行,设置redis密码,可选
appendonly yes
#699行,开启AOF
systemctl restart redis-server.service
#重启服务

Slave节点修改 Redis 配置文件

vim /apps/redis/etc/redis.conf
 

bind 0.0.0.0               #69行 ,添加监听的主机地址,0.0.0.0表示监听任意地址

protected-mode no     
#89行,将本机访问保护模式设置no。如果开启了,那么在没有设定bind ip且没有设密码的情况下,Redis只允许接受本机的响应

port 6379             #93行,Redis默认的监听6379端口

daemonize yes         #137行,设置为守护进程。后台启动

pidfile /apps/redis/run/redis_6379.pid
#159行,指定PID文件

logfile  /apps/redis/log/redis6379.log
#172行,指定日志文件

dir /apps/redis/data
#264行,指定持久化文件所在目录

replicaof 192.168.10.20 6379
#287行,指定要同步的Master节点IP和端口

masterauth abc123						
#294行,可选,指定Master节点的密码,仅在Master节点设置了requirepass

#requirepass abc123	 
#508行,增加一行,设置redis密码,可选

appendonly yes
#699行,开启AOF
systemctl restart redis-server.service
#重启服务

主从效果验证

#在Master节点上看日志:
tail -f /apps/redis/log/redis.log 

#在Master节点上验证从节点:
redis-cli  info replication 

五、Redis哨兵模式

5.1 简介

主从模式,当主节点宕机之后,从节点是可以作为主节点顶上来,继续提供服务的。

但是有一个问题,主节点的IP已经变动了,此时应用服务还是拿着原主节点的地址去访问,这…

于是,在Redis 2.8版本开始引入,就有了哨兵这个概念。

哨兵模式的核心功能是在主从复制的基础上,引入了主节点的自动故障转移。

端口号:26379

5.2 哨兵模式的作用

1)监控:哨兵会不断地检查主节点和从节点是否运作正常。

2)自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其它从节点改为复制新的主节点。

3)通知(提醒):哨兵可以将故障转移的结果发送给客户端。

5.3 哨兵结构

哨兵结构由两部分组成,哨兵节点和数据节点
哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。
数据节点:主节点和从节点都是数据节点。

5.4 故障转移机制(重要)

由哨兵节点定期监控发现主节点是否出现了故障

每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。

如果主节点在一定时间范围内(如down-after-milliseconds参数设定的阈值,默认为30秒)不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。

当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。

当主节点出现故障,此时哨兵节点会通过Raft算法(选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知

所以整个运行哨兵的集群的数量不得少于3个节点。

由leader哨兵节点执行故障转移

##故障转移过程##
将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
若原主节点恢复也变成从节点,并指向新的主节点;
通知客户端主节点已经更换。

客观下线是主节点才有的概念;

如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。

5.5 主节点选举机制

1)过滤掉不健康的(已下线的),没有回复哨兵 ping 响应的从节点。

2)选择配置文件中从节点优先级配置最高的。(replica-priority,默认值为100)

3)选择复制偏移量最大,也就是复制最完整的从节点。

六、部署Redis哨兵模式

节点服务器IP地址
Master192.168.10.20
Slave1192.168.10.30
Slave2192.168.10.40

修改 Redis 哨兵模式的配置文件(所有节点操作)

cp /data/redis-5.0.7/sentinel.conf  /apps/redis/etc/


chown redis.redis /apps/redis/etc/sentinel.conf 

vim /apps/redis/bin/sentinel.conf

protected-mode no							
#17行,关闭保护模式

port 26379									#21行,Redis哨兵默认的监听端口

daemonize yes								#26行,指定sentinel为后台启动

pidfile /apps/redis/run/redis-sentinel.pid		
#31行,指定 PID 文件

logfile /apps/redis/log/sentinel.log	#36行,指定日志存放路径

dir /apps/redis/data					#65行,指定数据库存放路径

sentinel monitor mymaster 192.168.10.20 6379 2
#84行
#指定该哨兵节点监控192.168.10.20:6379这个主节点
#该主节点的名称是mymaster,
#最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移

sentinel auth-pass mymaster abc123			#87行指定Master节点的密码,仅在Master节点设置了requirepass

sentinel down-after-milliseconds mymaster 3000
#113行,判定服务器down掉的时间周期,默认3000毫秒(3秒)

sentinel failover-timeout mymaster 180000	#214行,同一个sentinel对同一个master两次failover之间的间隔时间(180秒)

准备service 文件 注意先开 主再开从 全部节点都需要

[root@localhost etc]#cat  >> /lib/systemd/system/redis-sentinel.service  <<eof
[Unit]
Description=Redis Sentinel
After=network.target
[Service]
ExecStart=/apps/redis/bin/redis-sentinel /apps/redis/etc/sentinel.conf --supervised systemd
ExecStop=/bin/kill -s QUIT $MAINPID
User=redis
Group=redis
RuntimeDirectory=redis
RuntimeDirectoryMode=0755
[Install]
WantedBy=multi-user.target
eof


[root@localhost etc]# systemctl daemon-reload 
[root@localhost etc]# systemctl start redis-sentinel.service

关掉 主服务器验证  在主上观察日志

 systemctl stop redis


tail -f /apps/redis/log/sentinel.log

在192.168.10.40上查看

[root@localhost etc]# redis-cli info replication

主再恢复后会变成从

[root@localhost ~]# systemctl start redis


[root@localhost etc]# redis-cli info replication

七、部署Redis集群

Redis的集群一般需要6个节点,3主3从。

方便起见,这里在同一台服务器上模拟。

服务器主机名IP主端口从端口
Node1节点node192.168.10.2060016004
Node2节点node192.168.10.2060026005
Node3节点node192.168.10.2060036006

创建集群配置目录及文件

[root@localhost src]#cd  /apps/redis/
[root@localhost redis]#mkdir -p redis-cluster/redis600{1..6}


for i in {1..6}
do
cp /data/redis-5.0.7/redis.conf /apps/redis/redis-cluster/redis600$i
cp /data/redis-5.0.7/src/redis-cli /data/redis-5.0.7/src/redis-server /apps/redis/redis-cluster/redis600$i
done

开启群集功能

其他5个文件夹的配置文件配置类似,6个端口都要不一样

[root@localhost redis6001]#cd /apps/redis/redis-cluster/redis6001/
vim redis.conf
#bind 127.0.0.1							#69行,注释掉bind 项,默认监听所有网卡
protected-mode no						#88行,修改,关闭保护模式
port 6001								#92行,修改,redis监听端口,
daemonize yes							#136行,开启守护进程,以独立进程启动  如果是 systemd 启动不需要修改
cluster-enabled yes						#832行,取消注释,开启群集功能
cluster-config-file nodes-6001.conf		#840行,取消注释,群集名称文件设置
cluster-node-timeout 15000				#846行,取消注释群集超时时间设置
appendonly yes							#700行,修改,开启AOF持久化
[root@localhost redis6001]#sed -i.bak  's/bind 127.0.0.1/bind 0.0.0.0/' redis.conf 
[root@localhost redis6001]#sed -i.bak  's/protected-mode yes/protected-mode no/' redis.conf 
[root@localhost redis6001]#sed -i.bak  's/^port .*/port 6001/' redis.conf
[root@localhost redis6001]#sed -i.bak  's/^daemonize .*/daemonize yes/' redis.conf 
[root@localhost redis6001]#sed -i.bak  's/^# cluster-enabled .*/cluster-enabled yes/' redis.conf 
[root@localhost redis6001]#sed -i.bak  's/^# cluster-config-file .*/cluster-config-file nodes-6001.conf/' redis.conf 
[root@localhost redis6001]#sed -i.bak  's/^# cluster-node-timeout .*/cluster-node-timeout 15000/' redis.conf
[root@localhost redis6001]#sed -i.bak  's/appendonly no/appendonly yes/' redis.conf

将6001的配置文件,分别复制给2-5

[root@localhost redis6001]#cd /apps/redis/redis-cluster/redis6001
#先切换目录
#复制配置文件
for i in {2..6}
do
\cp -f  ./redis.conf   /apps/redis/redis-cluster/redis600${i}
done

修改配置文件中的端口号

sed  -i   's/6001/6002/'   /apps/redis/redis-cluster/redis6002/redis.conf;
sed  -i   's/6001/6003/'   /apps/redis/redis-cluster/redis6003/redis.conf;
sed  -i   's/6001/6004/'   /apps/redis/redis-cluster/redis6004/redis.conf;
sed  -i   's/6001/6005/'   /apps/redis/redis-cluster/redis6005/redis.conf;
sed  -i   's/6001/6006/'   /apps/redis/redis-cluster/redis6006/redis.conf

启动redis节点

分别进入那六个文件夹,执行命令:redis-server redis.conf,来启动redis节点

[root@localhost redis6001]#systemctl stop redis
# 先停止之前的服务
[root@localhost redis6001]#ss -natp |grep 6379

[root@localhost redis6001]#cd /etc/redis/redis-cluster/redis6001
# 切换目录
[root@localhost redis6001]#redis-server redis.conf
# 启动


#脚本去启动
for d in {1..6}
do
cd /apps/redis/redis-cluster/redis600$d
redis-server redis.conf
done

查看是否成功启动

ps -ef | grep redis

启动集群

redis-cli --cluster create 127.0.0.1:6001 127.0.0.1:6002 127.0.0.1:6003 127.0.0.1:6004 127.0.0.1:6005 127.0.0.1:6006 --cluster-replicas 1
#六个实例分为三组,每组一主一从,前面的做主节点,后面的做从节点。下面交互的时候 需要输入 yes 才可以创建。
#--replicas 1 表示每个主节点有1个从节点。


测试群集

#登录6001
redis-cli -p 6001 -c					
#加-c参数,节点之间就可以互相跳转
127.0.0.1:6001> cluster slots			
#查看节点的哈希槽编号范围

127.0.0.1:6001> set name byyb

127.0.0.1:6001> cluster keyslot name
#查看name键的槽编号

redis-cli -p 6004 -c
127.0.0.1:6004> keys *						#对应的slave节点也有这条数据,但是别的节点没有

#连接到6001节点并获取集群中的节点信息
redis-cli -p 6001 -c cluster nodes


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值