Redis 主从复制、哨兵模式、群集模式
1. Redis 的 2种 持久化方式
-
RDB 持久化
- 定时把 redis 内存中的数据进行快照并压缩保存到硬盘
- RDB 持久化保存的文件占用空间小,网络传输快,恢复速度也比 AOF 快
- 缺点:实时性较差不如 AOF,兼容性较差,持久化期间在 fork 子进程时会阻塞 redis 父进程
-
AOF 持久化
- 以追加的方式将redis写操作的命令记录到文件中
- 实时性比 RDB 好,支持秒级持久化,兼容性更好
- 缺点:持久化保存的文件占用磁盘空间更大,恢复速度更慢,性能影响更大,AOF 文件重写期间在 fork 子进程时会阻塞 redis 父进程
问题:
两者区别?
可以通过 "工作方式" 、实时性、磁盘占用、恢复速度、兼容性、IO 性能影响等方面进行阐述。
2. Redis 优化
1)设置 config set activedefrag yes 开启内存碎片自动清理,或者定时执行 memory purge 清理内存碎片
2)设置 maxmemory 指定redis可占用的最大内存大小
设置 maxmemory-policy 指定内存数据淘汰策略,实现保存内存使用率不超过最大内存
设置 maxmemory-samples 指定内存数据淘汰策略的样本数量,值越大越精确(默认为5)
设置 maxclients 指定最大客户端连接数
设置 tcp-backlog 指定最大连接排队数
设置 timeout 指定连接超时时间
3)尽可能使用 hash 数据类型存储数据。因为 hash 类型的一个 key 可包含多个字段,该类型的数据占用空间较小
4)建议设置 key 的过期时间,精简 键名和键值,控制键占用空间的大小
5)设置 AOF持久化 和 主从复制 来备份数据,采用 哨兵 或 集群 模式实现集群的高可用
6)建议通过命令 config set requirepass 或 修改配置文件 requirepass 参数来设置redis密码
3. Redis 主从复制的原理
-
首次同步:当从节点要进行主从复制时,它会发送一个SYNC命令给主节点。主节点收到SYNC命令后,会执行BGSAVE命令来生成RDB快照文件,并在生成期间使用缓冲区记录所有写操作。
-
快照传输:当主节点完成BGSAVE命令并且快照文件准备好后,将快照文件传输给从节点。主节点将快照文件发送给从节点,并且在发送过程中,主节点会继续将新的写操作缓冲到内存中。
-
追赶复制:当从节点收到快照文件后,会加载快照文件并应用到自己的数据集中。一旦快照文件被加载,从节点会向主节点发送一个PSYNC命令,以便获取缓冲区中未发送的写操作。
-
增量复制:主节点收到PSYNC命令后,会将缓冲区中未发送的写操作发送给从节点,从节点会执行这些写操作,保证与主节点的数据一致性。此时,从节点已经追赶上了主节点的状态。
-
同步:从节点会继续监听主节点的命令,并及时执行主节点的写操作,以保持与主节点的数据同步。主节点会定期将自己的操作发送给从节点,以便从节点保持最新的数据状态.
注意:当slave首次同步或者宕机后恢复时,会全盘加载,以追赶上大部队,即全量复制
3.1 配置文件
Master 192.168.175.101
Slave1 192.168.175.102
Slave2 192.168.175.103
-----修改 Redis 配置文件(Master节点操作)-----
vim /usr/local/redis/conf/redis.conf
bind 0.0.0.0 #87行,修改监听地址为0.0.0.0
appendonly yes #1380行,开启AOF
systemctl restart redis-server.service
-----修改 Redis 配置文件(Slave节点操作)-----
vim /usr/local/redis/conf/redis.conf
bind 0.0.0.0 #87行,修改监听地址为0.0.0.0
appendonly yes #1380行,开启AOF
replicaof 192.168.175.101 6379 #528行,指定要同步的Master节点IP和端口
#masterauth abc123 #535行,可选,指定Master节点的密码,仅在Master节点设置了requirepass
systemctl restart redis-server.service
redis-cli -h 192.168.175.101 -p 6379 -a abc123
redis-cli -h 192.168.175.102 -p 6379 -a abc123
redis-cli -h 192.168.175.103 -p 6379 -a abc123
info replication
3.2 Redis 主从复制
Master
cd /usr/local/redis/conf
ls
cd ..
ls
cd log/
ls
vim redis_6379.log
redis-cli -h 192.168.175.101 -p 6379 -a abc123
keys *
set name ssu
#新建姓名 ssu
set group G1
#新建组 G1
keys *
#全部信息
Slave1
redis-cli -h 192.168.175.102 -p 6379 -a abc123
keys *
#Master内容已同步到Slave1
get name
"ssu"
get group
"G1"
#主从复制成功
Slave2
redis-cli -h 192.168.175.103 -p 6379 -a abc123
keys *
#Master内容已同步到Slave2
get name
"ssu"
get group
"G1"
#主从复制成功
4. Redis 哨兵模式
哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式
4.1 哨兵机制
- 主从切换技术的方法是:当服务器宕机后,需要手动一台从机切换为主机,这需要人工干预,不仅费时费力而且还会造成一段时间内服务不可用。为了解决主从复制的缺点,就有了哨兵机制。
- 哨兵的核心功能:在主从复制的基础上,哨兵引入了主节点的自动故障转移,不能实现从节点的自动故障转移
4.2 哨兵模式的作用
- 监控:哨兵会不断地检查主节点和从节点是否运作正常。
- 自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其它从节点改为复制新的主节点。
- 通知(提醒):哨兵可以将故障转移的结果发送给客户端。
4.3 哨兵结构
- 由两部分组成,哨兵节点和数据节点:
- 哨兵节点:哨兵系统由一个或多个哨兵节点组成,哨兵节点是特殊的redis节点,不存储数据。默认端口号26379
- 数据节点:主节点和从节点都是数据节点。端口号6379
4.4 哨兵模式配置
Master节点:192.168.175.101
Slave1节点:192.168.175.102
Slave2节点:192.168.175.103
Master、Slave1、Slave2
cd /opt
cd redis-7.0.13/
ls
cp sentinel.conf /usr/local/redis/conf/
cd !$
ls
ll
chown redis:redis sentinel.conf
ll
vim sentinel.conf
protected-mode no #6行,关闭保护模式
port 26379 #10行,Redis哨兵默认的监听端口
daemonize yes #15行,指定sentinel为后台启动
pidfile /usr/local/redis/log/redis-sentinel.pid #20行,指定 PID 文件
logfile "/usr/local/redis/log/sentinel.log" #25行,指定日志存放路径
dir /usr/local/redis/data #54行,指定数据库存放路径
sentinel monitor mymaster 192.168.175.101 6379 2 #73行,修改 指定该哨兵节点监控192.168.175.101:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移
#sentinel auth-pass mymaster abc123 #76行,可选,指定Master节点的密码,仅在Master节点设置了requirepass
sentinel down-after-milliseconds mymaster 3000 #114行,判定服务器down掉的时间周期,默认30000毫秒(30秒)
sentinel failover-timeout mymaster 180000 #214行,同一个sentinel对同一个master两次failover之间的间隔时间(180秒)
提取IP地址
1.ifconfig ens33 | grep netmask | awk '{print $2}'
2.ip addr | grep ens33 | grep inet | awk '{print $2}' | awk -F/ '{print $1}'
3.ifconfig ens33 | awk 'NR==2 {print $2}'
vim failover.sh
#!/bin/bash
MASTER_IP=$6
#新MASTER地址赋给MASTER_IP变量
INTERFACE="ens33"
#网卡名称
LOCAL_IP=$(ifconfig $INTERFACE | awk 'NR==2 {print $2}')
#当前主机IP地址
VIP="192.168.175.200"
#VIP地址
NETMASK="24"
#掩码
KEY="1"
#网卡接口
if [ "$MASTER_IP" = "$LOCAL_IP" ]
then
#比较新MASTER地址和当前主机地址
/sbin/ifconfig ${INTERFACE}:${KEY} ${VIP}/${NETMASK}
#网卡名称:网卡接口 IP地址/子网掩码
exit 0
else
#地址不一样
/sbin/ifconfig ${INTERFACE}:${KEY} down
#删除VIP地址
fi
exit 1
#返回1 哨兵一直执行脚本
chmod +x failover.sh
ll
./failover.sh 1 1 1 1 1 192.168.175.101 1
ifconfig
./failover.sh 1 1 1 1 1 192.168.175.15 1
ifconfig
scp failover.sh 192.168.175.102:`pwd`
#将脚本远程复制给slave1节点,回车输入yes和密码
pwd
Slave1
cd /usr/local/redis/conf
ls
#查看脚本已经远程拷贝过来
scp failover.sh 192.168.175.103:`pwd`
#将脚本远程复制给slave1节点,回车输入yes和密码
Slave2
cd /usr/local/redis/conf
ls
#查看脚本已经远程拷贝过来
Master、Slave1、Slave2
vim sentinel.conf
sentinel client-reconfig-script mymaster /usr/local/redis/conf/failover.sh #279行
Master、Slave1、Slave2
redis-sentinel ./sentinel.conf &
#启动哨兵模式,&是放入后台执行
netstat -lntp | grep redis
#查看redis端口号
Master
redis-cli -h 192.168.175.101 -p 26379
#登录
info sentinel
#查看哨兵信息
ifconfig
ifconfig ens33:1 192.168.175.200/24
#手动添加VIP地址
ifconfig
4.5 故障转移测试
Slave1
cd /usr/local/redis/
ls
cd log/
ls
tail -f redis-sentinel.log
Slave2
redis-cli -h 192.168.175.103 -p 6379 -a abc123
systemctl stop redis-server.service
#主关闭
Slave1
tail -f redis-sentinel.log
#主转移到Slave1节点
5. Redis群集模式
-
集群,即Redis Cluster,是Redis 3.0开始引入的分布式存储方案。
-
集群由多组节点(Node)组成,Redis的数据分布在这些节点组中。节点组中的节点分为主节点和从节点:只有主节点负责读写请求和集群信息的维护;从节点只进行主节点数据和状态信息的复制。
5.1 群集模式配置
cd ..
ls
mkdir redis-cluster
ls
cd redis-cluster/
ls
mkdir redis600{1..6}
ls
cd /opt/redis-7.0.13/
ls
ls src/
cd -
cd redis6001/
ls
pwd
cd /opt/redis-7.0.13/
ls
for i in {1..6}
do
cp ./redis.conf src/redis-server src/redis-cli /usr/local/redis/redis-cluster/redis600$i
done
cd -
cd ..
ls -R
cd redis6001
ls
vim redis.conf
#bind 0.0.0.0 #87行,注释掉bind项,默认监听所有网卡
protected-mode no #111行,关闭保护模式
port 6001 #138行,修改redis监听端口
daemonize yes #309行,设置为守护进程,后台启动
pidfile /usr/local/redis/log/redis_6001.pid #341行,指定 PID 文件
logfile "/usr/local/redis/log/redis_6001.log" #354行,指定日志文件
dir ./ #504行,指定持久化文件所在目录
appendonly yes #1379行,开启AOF
cluster-enabled yes #1576行,取消注释,开启群集功能
cluster-config-file nodes-6001.conf #1584行,取消注释,群集名称文件设置
cluster-node-timeout 15000 #1590行,取消注释群集超时时间设置
5.2 启动 redis 节点
for i in {2..6};
> do
> \cp -f redis.conf ../redis600$i
> done
cd ..
ls
cd redis6002/
ls
vim redis.conf
sed -n '/6001/p' redis.conf
#查看所有6001行
sed -i 's/6001/6002/' redis.conf
#所有6001修改成6002
sed -n '/6001/p' redis.conf
sed -n '/6002/p' redis.conf
cd ../redis6003/
sed -i 's/6001/6003/' redis.conf
sed -n '/6003/p' redis.conf
cd ../redis6004/
sed -i 's/6001/6004/' redis.conf
cd ../redis6005/
sed -i 's/6001/6005/' redis.conf
cd ../redis6006/
sed -i 's/6001/6006/' redis.conf
pwd
for i in {1..6}
do
cd /usr/local/redis/redis-cluster/redis600$i
./redis-server ./redis.conf
done
ps -elf | grep redis-server
5.3 启动集群
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
redis-cli -p 6001
cluster nodes
redis-cli -p 6001 -c
set group sse