目录
一、Redis主从复制
1、Redis主从复制概述
1.1、Redis主从复制概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave);数据的复制是单向的,只能由主节点到从节点
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点
1.2、Redis主从复制的作用
提高读取性能:通过将读取操作分摊到多个服务器上,可以提高系统的整体读取性能。客户端可以向任何一个从服务器发送读取请求,从而减轻主服务器的负载
数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余
负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量
高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础
1.3、Redis主从复制的流程
- 若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接
- 无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中
- 后台进程完成缓存操作之后,Maste机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接
- Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Mater同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常
2、搭建Redis主从复制
主机名称 | 操作系统 | IP地址 | 软件 / 安装包 / 工具 |
---|---|---|---|
master_redis | CentOS7 | 172.16.88.44 | redis-5.0.7.tar.gz |
slave1_redis | CentOS7 | 172.16.88.55 | redis-5.0.7.tar.gz |
slave2_redis | CentOS7 | 172.16.88.66 | redis-5.0.7.tar.gz |
(1)关闭所有设备的防火墙和核心防护
[root@localhost ~]#systemctl stop firewalld
[root@localhost ~]#setenforce 0
(2)修改三台服务器的主机名,方便区分
[root@localhost ~]#hostnamectl set-hostname master_redis
[root@localhost ~]#bash #修改master服务器主机名
[root@localhost ~]#hostnamectl set-hostname slave1_redis
[root@localhost ~]#bash #修改slave1服务器主机名
[root@localhost ~]#hostnamectl set-hostname slaver2_redis
[root@localhost ~]#bash #修改slave2服务器主机名
(3)安装master主服务器、slave1从服务器、slave2从服务器的redis-5.0.7软件
redis安装包官网下载:http://download.redis.io/releases/
yum install -y gcc gcc-c++ make #安装依赖包
#事先准备好安装包:redis-5.0.7.tar.gz,解压后进入安装包目录编译安装即可
cd /opt
tar zxvf redis-5.0.7.tar.gz
cd /opt/redis-5.0.7/
make
make PREFIX=/usr/local/redis install
#执行软件包提供的 install_server.sh 脚本文件,设置 Redis 服务所需要的相关配置文件
cd /opt/redis-5.0.7/utils
./install_server.sh
…… 一直回车
直到出现:Please select the redis executable path []
然后在这句话后面手动输入
/usr/local/redis/bin/redis-server #注意要一次性正确输入
#没有一次性输入正确,那么要保证后面一定作软链接
ln -s /usr/local/redis/bin/* /usr/local/bin/
/etc/init.d/redis_6379 start #启动redis服务
2.1、修改主服务器配置文件
修改master_redis主服务器的redis配置文件
[root@master_redis ~]#vim /etc/redis/6379.conf
bind 0.0.0.0 #70行,修改bind 项,0.0.0.0监听所有网段
daemonize yes #137行,开启守护进程
logfile /var/log/redis_6379.log #172行,指定日志文件目录
dir /var/lib/redis/6379 #264行,指定工作目录
appendonly yes #700行,开启AOF持久化功能
[root@master_redis ~]#/etc/init.d/redis_6379 restart
2.2、修改从服务器配置文件
slave1从服务器、slave2从服务器都需要修改各自的redis主配置文件
vim /etc/redis/6379.conf
bind 0.0.0.0 #70行,修改bind 项,0.0.0.0监听所有网卡
daemonize yes #137行,开启守护进程
logfile /var/log/redis_6379.log #172行,指定日志文件目录
dir /var/lib/redis/6379 #264行,指定工作目录
replicaof 172.16.88.77 6379 #288行,指定要同步的Master节点IP和端口
appendonly yes #700行,开启AOF持久化功能
/etc/init.d/redis_6379 restart
2.3、测试
(1)在master_redis主服务器上查看日志
[root@master_redis ~]#tailf /var/log/redis_6379.log
(2)在master_redis主服务器上查看从节点服务器
[root@master_redis ~]#redis-cli info replication
#解释输出的这段信息是关于Redis的主服务器的状态报告
role:master:这表示当前Redis实例的角色是主服务器。
connected_slaves:这表明当前有几个从服务器连接到主服务器进行复制
slave0和slave1: 这些是从服务器的信息,包括IP地址、端口号、状态(在线)、偏移量(offset)和延迟(lag)。这些信息显示了每个从服务器的连接状态、同步进度等
master_replid:这是主服务器的复制ID,用于标识主服务器的数据集
master_replid2: 这是一个备用的主服务器复制ID,通常在故障转移时使用
master_repl_offset: 这是主服务器当前的复制偏移量,表示主服务器目前复制的进度
second_repl_offset: 这是备用的主服务器复制偏移量,在故障转移时可能会被使用
repl_backlog_active: 这表示复制后备日志是否处于活动状态
repl_backlog_size: 这是后备日志的大小
repl_backlog_first_byte_offset: 这是后备日志中第一个字节的偏移量
repl_backlog_histlen: 这是后备日志历史长度,表示当前后备日志中包含的最新数据的长度
(3)在master主服务器上写入数据,查看能否同步到两个slave从服务器
redis-cli #登录到本地的redis数据库
keys * #查看当前数据库中的所有键
在master主服务器上的编号为0的数据库中创建数据
测试:在两个slave从服务器上查看是否能获取到同步的数据
二、Redis哨兵模式
1、Redis哨兵模式概述
1.1、Redis哨兵模式概念
Redis 哨兵模式用于监控Redis实例的运行状况,并在主节点发生故障时自动进行故障转移,确保系统的持续可用性。Redis 哨兵通过不断地检查主节点和从节点的状态来实现这一目标,并在需要时自动执行故障转移操作
哨兵系统通常由多个哨兵节点组成,它们之间通过消息传递来协调监控任务和决策。当主节点出现故障或不可用时,哨兵系统会选举一个从节点作为新的主节点,并通知其他节点更新配置,使系统能够继续正常工作
通过使用哨兵模式,Redis可以实现自动化的故障处理和主从切换,提高了系统的可用性和稳定性。同时,哨兵还可以进行监控、通知和自动故障恢复等功能,使Redis集群更加健壮和可靠
1.2、Redis哨兵模式功能
监控:哨兵会不断地检查主节点和从节点是否运作正常
自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其他从节点改为复制新的主节点
通知(提醒):哨兵可以将故障转移的结果发送给客户端
即哨兵的核心功能:在主从复制的基础上,哨兵引入了主节点的自动故障转移
1.3、Redis哨兵模式原理
哨兵(sentinel):是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的 Master 并将所有 Slave 连接到新的 Master。所以整个运行哨兵的集群的数量不得少于3个节点
1.4、Redis哨兵模式工作流程
(1)哨兵对主从复制集群进行监控,监控对象“所有redis数据节点”
(2)哨兵与哨兵之间进行相互监控,监控的对象:哨兵彼此
(3)监控目的
(3.1)哨兵与哨兵之间的监控目的:检测彼此的存活状态
(3.2)哨兵监控所有的redis数据库的目的:为了实现故障自动故障切换
故障切换原理
① 当master 挂掉,哨兵会及时发现,发现之后,进行投票机制,选举出一个新的master服务器(投票数一定是奇数)
② 完成salve ---> master的从向主进行切换
③ 完成其他的从服务器对新的master配置
1.5、故障转移机制
① 由哨兵节点定期监控发现主节点是否出现了故障
每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了
② 当主节点出现故障,此时哨兵节点会通过Raft算法(选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。所以整个运行哨兵的集群的数量不得少于3个节点
③ 由leader哨兵节点执行故障转移,过程如下:
将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
若原主节点恢复也变成从节点,并指向新的主节点;
通知客户端主节点已经更换。
需要特别注意的是,客观下线是主节点才有的概念;如果从节点和哨兵节点发生故障,被哨兵主观下线后,不会再有后续的客观下线和故障转移操作。
1.6、主节点的选举
- 过滤掉不健康的(已下线的),没有回复哨兵 ping 响应的从节点
- 选择配置文件中从节点优先级配置最高的。(replica-priority,默认值为100)
- 选择复制偏移量最大,也就是复制最完整的从节点
2、搭建Redis哨兵模式
2.1、修改所有服务器节点的配置文件
vim /opt/redis-5.0.7/sentinel.conf
protected-mode no #17行,关闭保护模式
port 26379 #21行,Redis哨兵默认的监听端口
daemonize yes #26行,指定sentinel为后台启动
logfile "/var/log/sentinel.log" #36行,指定日志存放路径
dir "/var/lib/redis/6379" #65行,指定数据库存放路径
sentinel monitor mymaster 172.16.12.10 6379 2
#84行,修改 指定该哨兵节点监控172.16.12.10:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移
sentinel down-after-milliseconds mymaster 30000
#113行,判定服务器down掉的时间周期,默认30000毫秒(30秒)
sentinel failover-timeout mymaster 180000
#146行,故障节点的最大超时时间为180000(180秒)
2.2、启动哨兵模式
先启master主服务器,再启slave1和slave2从服务器
cd /opt/redis-5.0.7/
redis-sentinel sentinel.conf &
注意!先启动主服务器,再启动从服务器
主服务器
从服务器
查看redis-server进程号
ps aux | grep redis
查看哨兵模式详细信息
redis-cli -p 26379 info sentinel
#哨兵信息详解
sentinel_masters:1
#这表示有一个 Redis 主服务器被 Sentinel 监控管理
sentinel_tilt:0
#这个值表示当前没有倾斜(tilt)事件发生,即系统处于正常状态
sentinel_running_scripts:0
#表示没有正在运行的脚本
sentinel_scripts_queue_length:0
#这表示脚本队列中没有等待执行的脚本
sentinel_simulate_failure_flags:0
#这个参数指示没有设置用于模拟故障的标志
master0:name=mymaster,status=ok,address=172.16.12.10:6379,slaves=2,sentinels=3
#这是关于名为“mymaster”的主 Redis 服务器的详细信息。它显示了主服务器的名称、状态(正常)、地址(IP地址和端口号)、从服务器的数量(2个)以及 Sentinel 实例的数量(3个)
2.3、模拟故障切换
模拟master故障:杀死 master主服务器上的redis-server进程号
[root@master_redis redis-5.0.7]#ps aux | grep redis
[root@master_redis redis-5.0.7]#kill -9 108408
查看哨兵模式详细信息:是否完成自动故障切换
redis-cli -p 26379 info sentinel
查看日志文件:是否完成自动故障切换
tailf /var/log/sentinel.log #实时监控日志文件后十行
三、Redis集群
1、Redis集群模式概述
1.1、Redis集群模式概念
Redis集群模式是Redis数据库的一种部署方式,用于提高Redis的性能和可伸缩性。在Redis集群模式中,数据被分片(sharding)存储在多个Redis实例中,每个实例负责存储其中一部分数据。这样可以让Redis集群处理更大量的数据,并提供更高的读写性能
Redis集群模式通常包括多个主节点和若干个从节点。主节点负责处理客户端的读写请求,而从节点用于备份数据和提供读取服务。Redis集群模式还提供了自动的故障转移和数据重分片功能,以确保集群的高可用性和稳定性
通过Redis集群模式,可以横向扩展Redis数据库,应对大规模数据和高并发访问的需求,是一种常见的实现高性能、高可用性的方案之一
1.2、Redis集群模式作用
集群的作用,可以归纳为两点:
(1)数据分区:数据分区(或称数据分片)是集群最核心的功能
集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加;另一方面每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力
Redis单机内存大小受限问题,在介绍持久化和主从复制时都有提及;例如,如果单机内存太大,bgsave和bgrewriteaof的fork操作可能导致主进程阻塞,主从环境下主机切换时可能导致从节点长时间无法提供服务,全量复制阶段主节点的复制缓冲区可能溢出
(2)高可用:集群支持主从复制和主节点的自动故障转移(与哨兵类似);当任一节点发生故障时,集群仍然可以对外提供服务
1.3、Redis集群的工作模式
redis cluster 提供自动故障转移功能,这些机制可以监测 redis 节点的健康状态,当 master 节点不可用时,自动升级一个 slave 为新的 master,然后重新分配槽位等操作以确保集群的正常运行
心跳:在分布式系统中,心跳通常用于检测节点的存活状态。在 redis 集群中,master 节点之间会定期发送心跳消息以确认彼此的存活状态。这有助于及时发现节点失效或网络问题,并采取相应的措施来维护集群的稳定性
同步:对于 redis 集群中的 master 节点,同步是指将数据从一个 master 节点复制到另一个 master 节点,以确保所有节点上的数据保持一致。当一个 master 节点接收到写入操作时,它会将这些更新通过复制机制传播到其他节点,以实现数据的同步。不过采用哈希数据分片的方式进行数据存储,每个键被映射到特定的分片上,而每个分片由一个主节点负责。因此,在标准的 redis 集群中,主节点之间不会直接同步数据
① 读写可以负载均衡
Redis Cluster 实现了读写请求的负载均衡,客户端可以根据数据分片情况将请求路由到不同的节点上,提高了系统的整体处理能力
② 自动故障转移(高可用)
当主节点发生故障时,Redis Cluster 会自动进行故障转移,将一个从节点晋升为新的主节点,从而保证数据的可用性
③ 突破了单机的存储限制
通过数据分片和分布式存储,Redis Cluster 可以突破单机存储容量的限制,将数据存储在多个节点上,实现了存储的水平扩展
④ 数据分片
Redis Cluster 将数据分为多个槽(slot),每个槽对应一个数据分片。这些数据分片分布在不同的节点上,实现数据的分布式存储
1.4、Redis集群的数据分片
Redis集群引入了哈希槽的概念
Redis集群有16384个哈希槽(编号0~16383)
集群的每个节点负责一部分哈希槽
每个Key通过CRC16校验后对16384取余来决定放置哪个哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作
#以3个节点组成的集群为例:
节点A包含0到5460号哈希槽
节点B包含5461到10922号哈希槽
节点C包含10923到16383号哈希槽
1.5、Redis集群的主从复制模型
集群中具有A、B、C三个节点,如果节点B失败了,整个集群就会因缺少5461-10922这个范围的槽而不可以用。
为每个节点添加一个从节点A1、B1、C1整个集群便有三个Master节点和三个slave节点组成,在节点B失败后,集群选举B1位为的主节点继续服务。当B和B1都失败后,集群将不可用。
2、搭建Redis集群模式
redis的集群一般需要6个节点,即3主3从
方便起见,这里所有节点在同一台服务器上模拟:
以端口号进行区分:3个主节点端口号:6001/6002/6003,对应的从节点端口号:6004/6005/6006,主节点对应的从节点端口号是随机分配的
主机名称 | 操作系统 | IP地址 | 端口 | 软件/安装包/工具 |
---|---|---|---|---|
Master1 | CentOS7 | 172.16.88.44 | 6001 | redis-5.0.7.tar.gz |
Slave1 | CentOS7 | 172.16.88.44 | 6002 | redis-5.0.7.tar.gz |
Master2 | CentOS7 | 172.16.88.44 | 6003 | redis-5.0.7.tar.gz |
Slave2 | CentOS7 | 172.16.88.44 | 6004 | redis-5.0.7.tar.gz |
Master3 | CentOS7 | 172.16.88.44 | 6005 | redis-5.0.7.tar.gz |
Slave3 | CentOS7 | 172.16.88.44 | 6006 | redis-5.0.7.tar.gz |
关闭所有设备的防火墙和核心防护
[root@localhost ~]#systemctl stop firewalld
[root@localhost ~]#setenforce 0
安装redis-5.0.7软件
yum install -y gcc gcc-c++ make #安装依赖包
#事先准备好安装包:redis-5.0.7.tar.gz,解压后进入安装包目录编译安装即可
cd /opt
tar zxvf redis-5.0.7.tar.gz
cd /opt/redis-5.0.7/
make
make PREFIX=/usr/local/redis install
#执行软件包提供的 install_server.sh 脚本文件,设置 Redis 服务所需要的相关配置文件
cd /opt/redis-5.0.7/utils
./install_server.sh
…… 一直回车
直到出现:Please select the redis executable path []
然后在这句话后面手动输入
/usr/local/redis/bin/redis-server #注意要一次性正确输入
#没有一次性输入正确,那么要保证后面一定作软链接
ln -s /usr/local/redis/bin/* /usr/local/bin/
/etc/init.d/redis_6379 start #启动redis服务
2.1、拷贝配置文件到不同的目录
[root@localhost ~]#cd /etc/redis/
[root@localhost redis]#mkdir -p redis-cluster/redis600{1..6}
[root@localhost redis]#for i in {1..6}
do
cp /opt/redis-5.0.7/redis.conf /etc/redis/redis-cluster/redis600$i
cp /opt/redis-5.0.7/src/redis-cli /opt/redis-5.0.7/src/redis-server /etc/redis/redis-cluster/redis600$i
done
2.2、开启集群功能
[root@localhost redis]#cd /etc/redis/redis-cluster/redis6001
[root@localhost redis6001]#vim redis.conf
#bind 127.0.0.1 #69行,注释掉bind 项,默认监听所有网卡
protected-mode no #88行,修改,关闭保护模式
port 6001 #92行,修改,redis监听端口,
daemonize yes #136行,开启守护进程,以独立进程启动
cluster-enabled yes #832行,取消注释,开启群集功能
cluster-config-file nodes-6001.conf #840行,取消注释,群集名称文件设置
cluster-node-timeout 15000 #846行,取消注释群集超时时间设置
appendonly yes #700行,修改,开启AOF持久化
其他5个文件夹的配置文件以此类推修改,注意6个配置文件中的6个端口都要不一样
[root@localhost redis6001]#for i in {2..6}
do
cp /etc/redis/redis-cluster/redis6001/redis.conf /etc/redis/redis-cluster/redis600$i
done
#将修改好的redis6001目录下的文件覆盖掉其他目录下的配置文件,这样只需要修改不同目录对应的不同的端口号和群集名称文件
[root@localhost redis6001]#cd ../redis6002
[root@localhost redis6002]#vim redis.conf
port 6002 #92行,修改,redis监听端口
cluster-config-file nodes-6002.conf #840行,取消注释,群集名称文件设置
[root@localhost redis6002]#cd ../redis6003
[root@localhost redis6003]#vim redis.conf
port 6003 #92行,修改,redis监听端口
cluster-config-file nodes-6003.conf #840行,取消注释,群集名称文件设置
[root@localhost redis6003]#cd ../redis6004
[root@localhost redis6004]#vim redis.conf
port 6004 #92行,修改,redis监听端口
cluster-config-file nodes-6004.conf #840行,取消注释,群集名称文件设置
[root@localhost redis6004]#cd ../redis6005
[root@localhost redis6005]#vim redis.conf
port 6005 #92行,修改,redis监听端口
cluster-config-file nodes-6005.conf #840行,取消注释,群集名称文件设置
[root@localhost redis6005]#cd ../redis6006
[root@localhost redis6006]#vim redis.conf
port 6006 #92行,修改,redis监听端口
cluster-config-file nodes-6006.conf #840行,取消注释,群集名称文件设置
2.3、启动Redis节点
分别进入那六个文件夹,执行命令:redis-server redis.conf ,来启动redis节点
[root@localhost redis6006]#for d in {1..6}
do
cd /etc/redis/redis-cluster/redis600$d
redis-server redis.conf
done
[root@localhost redis6006]#ps aux | grep redis #查看服务进程
2.4、启动集群
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个从节点
#IP地址可写127.0.0.1也能写本机IP
2.5、测试集群
[root@localhost ~]#redis-cli -p 6001 -c #加-c参数,节点之间就可以互相跳转
cluster slots #查看所有节点的哈希槽编号范围
输入数据(每次轮询存储在不同的master主服务器中),然后slave服务器只能查看其对应的master主服务器的同步的数据
set k6002 22222
set k6003 33333
set k6004 44444
[root@localhost ~]#redis-cli -p 6005 -c
keys *
[root@localhost ~]#redis-cli -p 6006 -c
keys *
[root@localhost ~]#redis-cli -p 6004 -c
keys *