一、Linux服务器源码安装Redis6和相关依赖
二、这样安装部署Redis存在哪些问题?
三、Redis6.X 主从复制 1主2从架构搭建
四、Redis6.X主从复制-读写分离原理解析
五、这种主从的方式又存在哪些问题呢?
六、Redis6.X节点高可用监控之Sentinel
七、Redis6.X节点高可用监控之Sentinel哨兵搭建
八、SpringBoot中怎么用主从+Sentinel哨兵这种模式?
导读:高可用有2个含义:一个是数量尽量不丢失,二是保证服务尽可能的可用。AOF和RDB保证了数据尽量不丢失,那么本博文通过阿里云服务器搭建Redis6.x主从+哨兵模式尽可能的保障服务故障自动切换可用。
先看下源码安装步骤:
#安装gcc
yum install -y gcc-c++ autoconf automake
#centos7 默认的 gcc 默认是4.8.5,版本小于 5.3 无法编译,需要先安装gcc新版才能编译
gcc -v
#升级新版gcc,配置永久生效
yum -y install centos-release-scl
yum -y install devtoolset-9-gcc devtoolset-9-gcc-c++ devtoolset-9-binutils
scl enable devtoolset-9 bash
echo "source /opt/rh/devtoolset-9/enable" >>/etc/profile
#将源码包放到 /usr/local/software目录下
#tar -zxvf redis-6.2.1.tar.gz
#编译redis
cd redis
make
#安装到指定目录
mkdir -p /usr/local/redis
make PREFIX=/usr/local/redis install
启动服务端:
存在的问题:
单机部署简单,但是可靠性低,且不能很好利用CPU多核处理能力
生产环境-必须要保证高可用-一般不可能单机部署
读写分离是可用性要求不高、性能要求较高、数据规模小的情况;
我们的目标是:
读写分离,扩展主节点的读能力,分担主节点读压力
容灾恢复,一旦主节点宕机,从节点作为主节点的备份可以随时顶上来
Redis主从架构介绍:
先来看下redis.conf里面那些个配置都是什么意思:
#绑定指定ip访问,0.0.0.0是不限制,配置多个ip例子 12.13.432.12 31.12.43.13 用空格隔开
bind 0.0.0.0
#端口号 默认6379
port 6379
#配置后台运行,默认no
daemonize yes
#密码配置
requirepass "123456"
#日志存放地址
logfile "/usr/local/redis/log/redis3.log"
#配置redis持久化文件名称
dbfilename "wnn3.rdb"
#配置redis持久化文件存储地址
dir "/usr/local/redis/data"
#开启AOF方式存储
appendonly yes
appendfilename "appendonly3.aof"
#哪个主节点进行复制
replicaof 112.74.xxx.xxx 6379
#从节点访问主节点的密码,和requirepass一样
masterauth "123456"
在以下redis.conf中,因为部分中文格式等会导致乱码解析失败等的,直接把注释都去掉了。开始我们的主从搭建吧!
第一步 先建一主二从存数据的文件夹:
mkdir -p /data/redis/master/data
mkdir -p /data/redis/slave1/data
mkdir -p /data/redis/slave2/data
第二步 再cd到这些目录下,分别创建redis.conf
主节点 6379操作步骤:
cd /data/redis/master/data
touch redis.conf
vim redis.conf
bind 0.0.0.0
port 6379
daemonize yes
requirepass "123456"logfile "/usr/local/redis/log/redis1.log"
dbfilename "wnn.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly1.aof"
masterauth "123456"
从节点6380操作步骤:
cd /data/redis/slave1/data
touch redis.conf
vim redis.conf
bind 0.0.0.0
port 6380
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis2.log"
dbfilename "wnn2.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly2.aof"
replicaof 112.74.xxx.xxx 6379
masterauth "123456"
从节点6381的配置:
cd /data/redis/slave2/data
touch redis.conf
vim redis.conf
bind 0.0.0.0
port 6381
daemonize yes
requirepass "123456"
logfile "/usr/local/redis/log/redis3.log"
dbfilename "wnn3.rdb"
dir "/usr/local/redis/data"
appendonly yes
appendfilename "appendonly3.aof"
replicaof 112.74.xxx.xxx 6379
masterauth "123456"
配置好后,按顺序启动三个节点:
分别进入到cd /usr/local/redis/bin目录下
主节点 6379 ./redis-server /data/redis/master/data/redis.conf
从一节点6380 ./redis-server /data/redis/slave1/data/redis.conf
从二节点 6381 ./redis-server /data/redis/slave2/data/redis.conf
启动完之后通过lsof -i:6379查看端口是否存在
在bin目录中可通过redis-cli客户端连接上去,通过info replication 查看下状态 6379是主节点,拥有2个从节点,一个是6380 一个是6381
主节点可以进行读写操作,但是 从节点只可以读取,在从节点写数据会报错的。
主从的配置是不是很简单! 那么思考下主从同步是如何完成的?Master库数据是一次性传给Slave库还是分批传呢?正常运行怎么传给Slave?要是主从直接的网络断了,重新连接后又怎么传呢?
认真的看下去~
主从复制分两种(主从刚连接的时候,进行全量同步;全同步结束后,进行增量同步)
从服务器初始启动时候,全量复制同步的日志:
Full resync for master
全量复制
第一步、Slave第一次连接Master,发送Sync ,master服务器会执行bgsave命令,开启一个后台进程用于将redis中的数据生成一个rdb文件
第二步、主服务器会缓存所有接收到的来自客户端的写命令,当后台保存进程 处理完毕后,会将该rdb文件传递给slave服务器
第三步、slave服务器会将rdb文件保存在磁盘并通过读取该文件将数据加载到内存
第四步、在此之后master服务器会将在此期间缓存的命令通过redis传输协议发送给slave服务器
第五步、然后slave服务器将这些命令依次作用于自己本地的数据集上最终达到数据的一致性
增量复制
Slave初始化后开始正常工作时主服务器发生的写操作同步到从服务器的过程
服务器每执行一个写命令就会向从服务器发送相同的写命令,从服务器接收并执行收到的写命令
注意:Redis 2.8之后,已经使用psync来替代sync,因为sync命令非常消耗资源,而且不支持部分同步,psync效率更高,支持部分同步。
部分同步的工作原理大致如下:
Slave执行relicaof命令,判断从服务器是否第一次复制,是则向master发送psync -1,master则响应Full Resync【run id】【offset】执行全量的同步。如果不是第一次复制,则向master发送psync 【run id】【offset】,master响应continue ,执行部分同步。其中run id是上次复制保存的master节点的runid,offset是上次复制截止时候slave节点保存的复制偏移量。
特点:
主从复制对于 主/从 redis服务器来说是非阻塞的,所以同步期间都可以正常处理外界请求
一个主redis可以含有多个从redis,每个从redis可以接收来自其他从redis服务器的连接
从节点不会让key过期,而是主节点的key过期删除后,成为del命令传输到从节点进行删除
从节点开启 sync 看日志:
设置个key,5秒过期
主节点:
从节点的sync:
加速复制:
完全重新同步需要在磁盘上创建一个RDB文件,然后加载这个文件以便为从服务器发送数据
在比较低速的磁盘,这种操作会给主服务器带来较大的压力
新版支持无磁盘的复制,子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储
repl-diskless-sync yes (默认是no)
问题:
当主服务器宕机后,需要手动把一台从服务器切换为主服务器,人工干预费事费力,还会造成一段时间内服务不可用
哨兵模式的介绍:
Redis提供了哨兵的命令,是一个独立的进程
原理 哨兵通过发送命令给多个节点,等待Redis服务器响应,从而监控运行的多个Redis实例的运行情况
当哨兵监测到master宕机,会自动将slave切换成master,通过通知其他的从服务器,修改配置文件切换主机
Sentinel三大工作任务
监控(Monitoring)
Sentinel 会不断地检查你的主服务器和从服务器是否运作正常
提醒(Notification)
当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应用程序发送通知自动故障迁移(Automatic failover)
当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作, 它会将失效主服务器的其中一个从服务器升级为新的主服务器, 并让失效主服务器的其他从服务器改为复制新的主服务器
当客户端试图连接失效的主服务器时, 集群也会向客户端返回新主服务器的地址, 使得集群可以使用新主服务器代替失效服务器
那么问题来了,一个哨兵够吗?一个哨兵进程对Redis服务器进行监控,可能会出现问题
一般是使用多个哨兵进行监控,各个哨兵之间还会进行监控,形成多哨兵模式。
多哨兵模式下线名称介绍:
主观下线(Subjectively Down, 简称 SDOWN)
是单个 Sentinel 实例对服务器做出的下线判断,比如网络问题接收不到通知等
一个服务器没有在 down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线客观下线(Objectively Down, 简称 ODOWN)
指的是多个 Sentinel 实例在对同一个服务器做出 SDOWN 判断, 并且通过 SENTINEL is-master-down-by-addr 命令互相交流之后, 得出的服务器下线判断
一个 Sentinel 可以通过向另一个 Sentinel 发送 SENTINEL is-master-down-by-addr 命令来询问对方是否认为给定的服务器已下线
客观下线条件只适用于主服务器仲裁 qurum
Sentinel 在给定的时间范围内, 从其他 Sentinel 那里接收到了【足够数量】的主服务器下线报告, 那么 Sentinel 就会将主服务器的状态从主观下线改变为客观下线
这个【足够数量】就是配置文件里面的值,一般是Sentinel个数的一半加1,比如3个Sentinel则就设置为2
down-after-milliseconds 是一个哨兵在超过规定时间依旧没有得到响应后,会自己认为主机不可用
当拥有认为主观下线的哨兵达到sentinel monitor所配置的数量时,就会发起一次投票,进行failover
核心流程:
每秒ping,超过时间不响应 则认为主观下线
满足多个,则认为是客观下线
投票选择主节点
如果没有足够的节点同意master下线,则状态会被移除
环境准备:
配置3个哨兵,每个哨兵的配置都是一样的
启动顺序 先启动主再启动从,最后启动3个哨兵
哨兵端口是 【26379】记得开放
样例配置:
#不限制ip
bind 0.0.0.0
# 让sentinel服务后台运行
daemonize yes
# 配置监听的主服务器,mymaster代表服务器的名称,自定义,112.74.xx.xxx 代表监控的主服务器,6379代表端口,
#2代表只有两个或两个以上的哨兵认为主服务器不可用的时候,才会进行failover操作。
sentinel monitor mymasterwnn 112.74.xx.xxx 6379 2
# sentinel auth-pass定义服务的密码,mymasterwnn是服务名称,123456是Redis服务器密码
sentinel auth-pass mymasterwnn 123456
#超过5秒master还没有连接上,则认为master已经停止
sentinel down-after-milliseconds mymasterwnn 5000
#如果该时间内没完成failover操作,则认为本次failover失败
sentinel failover-timeout mymaster 30000
第一步:
创建3个文件 cd /usr/local/redis/conf
在目录下创建3个文件sentinel-1.conf、sentinel-2.conf、sentinel-3.conf
第二步:
给这三个文件分别加上配置内容:
port 26379
bind 0.0.0.0
daemonize yes
pidfile "/var/run/redis-sentinel-1.pid"
logfile "/var/log/redis/sentinel_26379.log"
dir "/tmp"
sentinel monitor mymasterwnn 112.74.xx.xx 6379 2
sentinel down-after-milliseconds mymasterwnn 5000
sentinel auth-pass mymasterwnn 123456
sentinel failover-timeout mymasterwnn 30000
port 26380
bind 0.0.0.0
daemonize yes
pidfile "/var/run/redis-sentinel-2.pid"
logfile "/var/log/redis/sentinel_26380.log"
dir "/tmp"
sentinel monitor mymasterwnn 112.74.xx.xx 6379 2
sentinel down-after-milliseconds mymasterwnn 5000
sentinel auth-pass mymasterwnn 123456
sentinel failover-timeout mymasterwnn 30000
port 26381
bind 0.0.0.0
daemonize yes
pidfile "/var/run/redis-sentinel-3.pid"
logfile "/var/log/redis/sentinel_26381.log"
dir "/tmp"
sentinel monitor mymasterwnn 112.74.xx.xx 6379 2
sentinel down-after-milliseconds mymasterwnn 5000
sentinel auth-pass mymasterwnn 123456
sentinel failover-timeout mymasterwnn 30000
第三步 启动哨兵集群 /usr/local/redis/bin
./redis-server /usr/local/redis/conf/sentinel-1.conf --sentinel
./redis-server /usr/local/redis/conf/sentinel-2.conf --sentinel
./redis-server /usr/local/redis/conf/sentinel-3.conf --sentinel
都启动后,查看状态和日志
停掉主节点6379后,查看下日志 (主自动切换到了6381节点 )
再来看下6381的redis.conf 在选举成master之后,配置内容被做了更改
这时候再把刚才停掉的6379主节点启动起来,日志输出如下 :变成从节点加入了
到这为止,一主二从和3个哨兵模式监听就完成啦~
将原来单节点引入的host,port去掉,改成sentinel master和nodes即可
篇尾: Sentinel解决了主从架构故障自动迁移的问题,但是Master主节点的写能力和存储能力依旧受限, 使用Redis的集群cluster就是为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,在下一篇博文中将会介绍集群Cluster的分片和虚拟哈希槽以及三主三从搭建和Springboot项目整合~