目录
一、redis概念
1、redis集群模式
主从复制
哨兵
集群Cluster
2、Redis群集
二、Redis主从复制
1、 主从模式
2、主从复制流程
3、redis配置
验证主从效果
三、redis哨兵
1、哨兵模式
2、哨兵模式主要功能
3、哨兵们监控整个系统节点的过程
4、哨兵模式下的故障迁移
主观下线
客观下线
master选举
故障转移
优缺点:
哨兵配置
验证结果
四、Cluster群集
1、集群原理
配置
测试结果
总结
主从复制是高可用Redis的基础,哨兵和集群都是在主从复制基础上实现高可用的。主从复制主要实现了数据的多机备份,
以及对于读操作的负载均衡和简单的故障恢复。
缺陷:故障恢复无法自动化:写操作无法负载均衡:存储能力受到单机的限制。
在主从复制的基础上,哨兵实现了自动化的故障恢复。
缺陷:写操作无法负载均衡:存储能力受到单机的限制。
通过集群,Redis解决了写操作无法负载均衡,以及存储能力受到单机限制的问题,实现了较为完善的高可用方案
redis是一个开源的kevvalue存储系统,受到了广大互联网公司的青睐。redis3.0版本之前只支持单例模式,在3.0版本及以后才支持集群 redis集群采用P2P模式,是完全去中心化的,不存在中心节点或者代理节点;
为了实现集群的高可用,即判新节点是否健康(能否正常使用), redis-cluster有一个投票容错机制:
如果集群中超过半数的节点投票认为某个节点挂了,那么这个节点就挂了(fail)。这是判断节点是否挂了的方法:
判新集群是否正常:
如果集群中任意一个节点挂了,而且该节点没有从节点(备份节点),那么这个集群就挂了。这是判断集群是否挂了的方法
那么为什么任意一个节点挂了(没有从节点)这个集群就挂了?
因为集群内置了16384个slot(哈希槽),并且把所有的物理节点映射到了这16384[0-16383]个slot上,或者说把这些slot均等的分配给了各个节点。
当需要在Redis集群存放一个数据(key-value)时,redis会先对这个key进行crc16算法,然后得到一个结果再把这个结果对16384进行求余,这个余数会对应[0-16383]其中一个槽,进而决定key-value存储到哪个节点中。所以一旦某个节点挂了,该节点对应的slot就无法使用,那么就会导致集群无法正常工作
示例(三个节点) :
节点A覆盖0-5460;
节点B覆盖5461-10922;
节点C覆盖10923-16383
即:每个节点有5460个哈希槽
新增一个节点:
节占A覆盖1365-5460
节占B覆盖6827-10922
节点C覆盖12288-16383
节点D覆盖0-1364.5461-6826.10923-12287
即:每个节点有4095个哈希槽
简单就是:它存储方式是哈希槽的方式,存储到各个节点的方式是分布式,但类似于串连在一起,一个出现问题,存储任然会给这个固定槽内,同样因为这个槽的原因固定,也是redis快的原因之一
redis两次分发,第一次分发给多个节点,第二次是分给不同槽(每个槽512M)
通过持久化功能,redis保证了即使在服务器重启的情况下也不会丢失(或少量丢失)数据,因为持久化会把内存中的数据保存到硬盘上,重启会从硬盘上加载数据,但是由于数据是存储在一台服务器上的,如果这台服务器出现硬盘故障等问题,也会导致数据丢失。
为了避免单点故障,通常的做法是将数据库复制多个副本以部署在不同的服务器上,这样即使有一台服务器出现故障,其他服务器依然可以继续提供服务,为此,redis提供了复制(replication)功能,可以实现当一台数据库中的数据更新后,自动将更新的数据同步到其他数据库上。
在复制的概念中,数据库分为两类,一类是主数据库(master),另一类是从数据(slave)。主数据可以进行读写操作,当写操做导致数据变化时自动将数据同步给数据库,而从数据库一般是只读的,并接收主数据同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库
若启动一个Slave机器进程,则它会向Master机器发送一个"sync_command"命令,请求同步连接
无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照(RDB)保存到
数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。
后台进程完成缓存操作之后,Master机器就会向Slave机器发送数据文件,Slave端机器将数据
文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
Master机器收到slave端机器的连接后,将其完整的数据文件发送给Slave端机几器,如果Mater同时收到多个slave发来的
同步请求则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。
流程:首先从服务器发送rsync复制请求,主服务器收到请求后,首先会启动主进程,通过派生fork,生成rdb子进程,子进程生成rdb的文件,同时完成后也会通知主进程,释放进程和资源,然后把rdb文件推送给从服务器;从服务器接收到rdb的文件后,先会看看自己的数据库,是否存在这个数据,如果存在,那么会先删除这些数据,如果没有,那直接做恢复操作,这个过程类似做的是全量的复制
然后主服务器会把缓存区的数据,append加入缓冲区,缓冲区直接与从服务器缓冲区对接,做数据的复制,这里的复制类似于增量部分;在后续的主服务器更新数据都是更具主服务器的缓存区增加到缓冲,在直接对接从服务器的,然后从在做保存
安装Redis
三台服务器都需要安装
#按需求关闭安全策略
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
yum -y install gcc gcc-c++ make
主可以写,从只能读
cd /opt
wget -P /opt http://download.redis.io/releases/redis-5.0.9.tar.gz
tar -zxvf redis-5.0.9.tar.gz
cd redis-5.0.9
make && make PREFIX=/usr/local/redis install
#Redis源码包中直接提供了makefile文件 直接执行make与make install命令进行安装
cd /opt/redis-5.0.9/utils/
./install_server.sh
#回车,直到出现以下选项,手动修改为“/usr/local/redis/bin/redis-server”
Please select the redis executable path [/usr/local/bin/redis-server] /usr/local/redis/bin/redis-server
ln -s /usr/local/redis/bin/* /usr/local/bin/
#检查服务状态
ss -natp | grep "redis"
修改Redis配置文件
① Master节点
vim /etc/redis/6379.conf
bind 0.0.0.0
#70行,修改监听地址为 0.0.0.0
daemonize yes
#137行,开启守护进程
logfile /var/1og/redis_6379.1og
#172行,指定日志文件目录
dir /var/lib/redis/6379
#264行,指定工作目录
appendonly yes
#700行,开启 AOF 持久化功能
/etc/init.d/redis_6379 restart
#重启服务使配置生效
② Slave1/2节点
vim /etc/redis/6379.conf
bind 0.0.0.0
#70行,修改监听地址为 0.0.0.0
daemonize yes
#137行,开启守护进程
logfile /var/log/redis_6379.log
#172行,指定日志文件目录
dir /var/lib/redis/6379
#264行,指定工作目录
replicaof 192.168.255.150 6379
#288行,指定要同步的 Master 节点 IP 和端口
appendonly yes
#700行,开启 AOF 持久化功能
/etc/init.d/redis_6379 restart
#重启服务使配置生效
主节点输入
tail -f /var/log/redis_6379.log
哨兵模式集群架构
哨兵是Redis集群架构中非常重要的一个组件,哨兵的出现主要是解决了主从复制出现故障时需要人为干预的问题
集群监控:负责监控Redismaster和slave进程是否正常工作
消息通知:如果某个Redis实例有故障,那么哨兵负责发送消息作为报敬通知给管理员
故障转移:如果masternode挂掉了,会自动转移到slave node上
配置中心:如果故障转移发生了,通知client客户端新的master地址
使用一个或者多个哨兵(Sentinel)实例组成的系统,对redis节点进行监控 在主节点出现故障的情况下, 能将从节点中的一个升级为主节点,进行故障转义,保证系统的可用性
首先主节点的信息是配置在哨兵(Sentinel)的配置文件中
哨兵节点会和配置的主节点建立起两条连接命令连接和订阅连接
PS:Redis发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消 息,订阅者 (sub) 接收消息。
哨兵会通过命令连接每10s发送一次INFO命令,通过INFO命令,主节点会返回自己的run_id和自己的从节点信息
哨兵会对这些从节点也建立两条连接命令连接和订阅连接
哨兵通过命令连接向从节点发送INFO命令,获取到他的一些信息: run id(redis服务器id) 、role(职能)、从服务器的复制偏移量offset、其他
通过命令连接向服务器的sentinel:hello频道发送一条消息,内容包括自己的ip端口、run id、配置(后续投票的时候会用到)等
通过订阅连接对服务器的sentinel:hello频道做了监听,所以所有的向该频道发送的哨兵的消息都能被接受到
解析监听到的消息,进行分析提取,就可以知道还有那些别的哨兵服务节点也在监听这些主从节点了,更新结构体将这些哨兵节点记录下来
向观察到的其他的哨兵节点建立命令连接----没有订阅连接
哨兵(Sentinel)节点会每秒一次的频率向建立了命令连接的实例发送PING命令,如果在down-after-milliseconds毫秒内没有做出有效响应包括(PONG/LOADING/MASTERDOWN)以外的响应,哨兵就会将该实例在本结构体中的状态标记为SRI_S_DOWN主观下线
当一个哨兵节点发现主节点处于主观下线状态是,会向其他的哨兵节点发出询问,该节点是不是已经主观下线了。如果超过配置参数quorum个节点认为是主观下线时,该哨兵节点就会将自己维护的结构体中该主节点标记为SRIO DOWN客观下线询问命令SENTINEL is-master-down-by-addr
在认为主节点客观下线的情况下,哨兵节点节点间会发起一次选举,命令为:SENTINEL is-master-down-by-addr,只是runid这次会将自己的runid带进去,希望接受者将自己设置为主节点。如果超过半数以上的节点返回将该节点标记为leacer的情况下,会有该leader对故障进行迁移
在从节点中挑选出新的主节点(通讯正常-优先级排序-优先级相同时选择offset最大的)
将该节点设置成新的主节点SLAVEOF no one,并确保在后续的INGO命令时 该节点返回状态为master
将其他的从节点设置成从新的主节点复制,SLAVEOF命令
将旧的主节点变成新的主节点的从节点
优点:高可用,哨兵模式是基于主从模式的,所有主从模式的优点,哨兵模式都具有有;主从可以自动切换,系统更健壮,可用性更高
缺点:redis比较难支持在线扩容,在群集容量达到上限时在线扩容会变得很复杂
修改哨兵配置文件[所有节点皆需]
vim /opt/redis-5.0.9/sentinel.conf
#17行,关闭保护模式
protected-mode no
#21行,Redis哨 兵默认的监听端口
port 26379
#26行 开启守护进程
daemonize yes
#36行,指定日志存放路径
logfile "/var/log/sentinel.log"
#65行,指定数据库存放路径
dir "/var/lib/redis/6379"
#84行,指定哨兵节点
#2表示,至少需要 2 个哨兵节点同意,才能判定主节点故障并进行故障转移
sentinel monitor mymaster 192.168.255.150 6379 2
#113行,判定服务器down掉的时间周期,默认30000毫秒 (30秒 )
sentinel down-after-milliseconds mymaster 3000
#146行,故障节点的最大超时时间为180000 (180秒)
sentinel failover-timeout mymaster 180000
6 启动哨兵模式
先启动主节点在启动从节点
cd /opt/redis-5.0.9/
redis-sentinel sentinel.conf &
查看哨兵信息
[root@master redis-5.0.7]# redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.255.150:6379,slaves=2,sentinels=1
模拟故障(rm -rf /var/run/redis_6379.pid)
ps -ef | grep "redis"
#查看 redis-server 的进程号
kill -9 6379
#杀死 Master 节点上的 redis-server 的进程号
查看哨兵信息
[root@master redis-5.0.7]# redis-cli -p 26379 info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=odown,address=192.168.255.150:6379,slaves=2,sentinels=3
PS:status=odown:
o即objectively ,客观
#查看master哨兵日志
验证结果
tail -f /var/log/sentinel.log
redis-cli -p 26379 info Sentinel
redis的哨兵模式基本已经可以实现高可用、读写分离,但是在这种模式每台redis服务器都存储相同的数据,很浪费内存资源,所以在redis3.0上加入了Cluster群集模式,实现了redis的分布式存储,也京是说每台redis节点存储着不同的内容根据官方推荐,集群部署至少要3台以上的master节点,最好使用3主3从六个节点的模式。
Cluster群集由多个redis服务器组成的分布式网络服务群集,群集之中有多个master主节点,每一个主节点都可读可写,节点之间会相互通信,两两相连,redis群集无中心节点
在redis-Cluster群集中,可以给每个一个主节点添加从节点,主节点和从节点直接尊循主从模型的特性,当用户需要处理更多读请求的时候,添加从节点可以扩展系统的读性能redis-cluster的故障转移:redis群集的主机节点内置了类似redissentinel的节点故障检测和自动故障转移功能,当群集中的某个主节点下线时,群集中的其他在线主节点会注意到这一点,并且对已经下线的主节点进行故障转移集群进行故障转移的方法和redis sentinel进行故障转移的方法基本一样,不同的是,在集群里面,故障转移是由集群中,其他在线的主节点负责进行的,所以群集不必另外使用redis sentinel
三台服务器都需要安装
#按需求关闭安全策略
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
yum -y install gcc gcc-c++ make
cd /opt
wget -P /opt http://download.redis.io/releases/redis-5.0.9.tar.gz
tar -zxvf redis-5.0.9.tar.gz
cd redis-5.0.9
make && make PREFIX=/usr/local/redis install
#Redis源码包中直接提供了makefile文件 直接执行make与make install命令进行安装
cd /opt/redis-5.0.9/utils/
./install_server.sh
#回车,直到出现以下选项,手动修改为“/usr/local/redis/bin/redis-server”
Please select the redis executable path [/usr/local/bin/redis-server] /usr/local/redis/bin/redis-server
ln -s /usr/local/redis/bin/* /usr/local/bin/
创建redis 6个端口的工作目录
cd /etc/redis/
mkdir -p redis-cluster/redis600{1..6}
vim /opt/redis.sh
#!/bin/bash
for i in {3..6}
do
cp /opt/redis-5.0.9/redis.conf /etc/redis/redis-cluster/redis600$i
cp /opt/redis-5.0.9/src/redis-cli /opt/redis-5.0.9/src/redis-server /etc/redis/redis-cluster/redis600$i
done
sh -x /opt/redis.sh
cd /etc/redis/redis-cluster/redis 6001
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个配置文件除端口号外改动相同
cp redis.conf ../redis6002/
--->yes
#启动服务
cd /etc/redis/redis-cluster/redis6001
redis-server redis.conf
#根据对应配置文件启动redis
vim /opt/redis_start.sh
#!/bin/bash
for d in {1..6}
do
cd /etc/redis/redis-cluster/redis600$d
redis-server redis.conf
done
ps -ef | grep redis
sh -x /opt/redis_start.sh
加入集群
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 表示每个主节点有一个从节点
#查看节点的哈希槽编号范围
redis在此处可以做为mysql的前置缓存数据库,redis与mysql对接的方式,需要配置线程池,需要定义后端mysql的位置(IP) + port(端口+对接的方式sock文件的位置,其他策略
redis基础功能
用于内存/缓存型快速存储(读取)
实现的方式
是默认将数据存储在内存/缓存中
具有丰富的数据类型,string list hash set && order set等,重要数据持久化的功能,持久化的方式:AOF RDB
单线程模式—》速度快的原因之一:Epoll + I/o复用(cluster中的slots哈希槽可以充当数据读、取的索引)
redis 中算法
LRU :淘汰策略
1)爱存中的数据进行随机淘汰
2)缓存中被设置了过期时间的数据进行随机淘汰
3)缓存中被设置了过期时间的数据,进行惰性删除(仅当访问到的数据过期了,才会删除)
4)当数据持续存储过程中,内存将满,会在设置了过期时间的数据中,进行近期淘汰
令牌桶+漏桶算法:限流
Raft:选举机制,用于选举新的主节点的算法##redis缓存高热数据的机制
高热:命中次数高的:指定提高缓存内数据的命中数,最直接的可以刷脚本,访问这些数据
redis优化
1、单例服务器,服务器本身优化
硬件资源选择->五大资源
1)磁盘固态盘scsi ——》硬件磁盘阵列
2)服务器内存条/云上,选择服务所需要的内存(阿里云)
3 ) CPU核数——》选择
4)网络—》网卡/云上,需要考虑负载压力下的网络流量QPs 4)网络-“网卡/云上,需要考虑负载压力下的网络流量QPS
以上,需要计算费用成本,还需要考虑到该服务器上的服务在运行是消耗的性能比例(需要预留给系统一部分资源)单例服务器,服务本身环境的选择 以上,需要计算费用成本,还需要考虑到该服务器上的服务在运行是消耗的性能比例(需要预留给系统一部分资源)
单例服务器,服务本身环境的选择
1)操作系统(linur发行版centos ubantu redhat server debian alphon mac sSuSE) ++(三阶:虚拟化KVM XEN FUEE ) 1)操作系统(linur发行版centos ubantu redhat server debian alphon mac sSuSE) ++(三阶:虚拟化KVM XEN FUEE )
2)基于操作系统,依赖环境(首当其冲,需要选择是最小化安装,还是指定操作系统版本的安装+内核版本)+软件形式的依赖tconcat-》jdselk (jdk )
3)软件资源优化—》五大负载+内核优化〈TCP协议相关、队列相关、路由转发、重定向、端口、文件打开数、系统的软硬限制)
2、单例服务器应用服务本身优化
软件资源优化-“五大负载+内核优化
1)首先从启动读取的恢复文件来看,基于AoF—》开启AoF功能(RDB是默认)RDB中 save M N触发周期的选择判定,—》影响到磁盘资源的使用
AoF中选择合适的syncwrite 同步写入磁盘的策略everysecond AoF中选择合适的syncwrite 同步写入磁盘的策略everysecond
2)使用过程中,需要考虑到的是内存的使用量(out memory )
内存淘汰策略★(惰性淘汰+定期删除/禁止:淘汰+定期删除)—》选择合适的淘汰策略(配置文件中定义的)
3)持久化方向
持久化的功能在保证数据完整性的同时,依然会持续性的对磁盘产生存储压力(来源于AOF和ROB生成的数据文件aof和rob的日志文件)
数据/日志文件的定期归档 ——日志文件的分割—保存在日志中心——共享存储NFS,GFS,TFS