Redis集群高可用环境

本文使用的是redis5.0.7版本

一、主从复制

单个Redis如果因为某种原因宕机的话,可能会导致Redis服务不可用,可以使用主从复制实现一主多从,主节点负责写的操作,从节点负责读的操作,主节点会定期将数据同步到从节点中,保证数据一致性的问题。

在这里插入图片描述

1.配置
##在需在从(一或多个)节点redis.conf文件中配置以下
slaveof 192.168.75.128 6379 ##主节点ip和端口
masterauth 123456 ## 主节点密码
2.主从复制数据同步的过程

1.Redis从节点向主节点建立socket连接

2.Redis采用全量或者增量的形式将数据同步给从节点

从Redis2.8版本以后 过程采用增量和全量同步

全量复制:一般用于在初次的复制场景(从节点与主节点一次建立)

增量复制:网络出现问题,从节点再次连接主节点时,主节点补发缺少的数据,每次数据增量同步

3.缺陷

若主节点宕机,将会导致整个redis环境不可进行写操作,需要人为更改主操作。

解决方案:使用哨兵机制实现Redis集群主从选举策略

二、Redis哨兵机制

Redis的哨兵机制是为了解决以上的主从复制的缺点(选举问题),解决问题保证我们的Redis高可用,实现自动化故障发现与故障转移。

在这里插入图片描述

1.原理
  1. 哨兵机制每个10s时间只需要配置监听我们的主节点就可以获取当前整个Redis集群的环境列表,采用info 命令形式。

  2. 哨兵不建议是单机的,最好每个Redis节点都需要配置哨兵监听。

  3. 哨兵集群原理是如何:多个哨兵都执行同一个主的master节点,订阅到相同都通道,有新的哨兵加入都会向通道中发送自己服务的信息,该通道的订阅者可以发现新哨兵的加入,随后相互建立长连接。

  4. Master的故障发现 单个哨兵会向主的master节点发送ping的命令,如果master节点没有及时的响应,哨兵会认为该master节点为“主观不可用状态”会发送给其他都哨兵确认该Master节点是否不可用,当前确认的哨兵节点数>=quorum(可配置),会实现重新选举。

2.实现
## 将redis源文件的sentinel.conf,copy到你redis的目录
vi sentinel.conf

##配置主机信息 和选举同意人数
sentinel monitor mymaster 192.168.75.128 6379 2
##master的密码
sentinel auth-pass mymaster 123456
##sentinel心跳检测主3秒内无响应,视为挂掉,开始切换其他从为主
sentinel down-after-milliseconds mymaster 3000
##每次最多可以有1个从同步主。一个从同步结束,另一个从开始同步。
sentinel parallel-syncs mymaster 1
##主从切换超时时间
sentinel failover-timeout mymaster 18000
##启动哨兵
./redis-sentinel ./sentinel.conf

##其他 检查哨兵状态
redis-cli -h 192.168.31.187 -p 5000
sentinel master mymaster
SENTINEL slaves mymaster
SENTINEL sentinels mymaster
SENTINEL get-master-addr-by-name mymaster

三、Redis安全控制

1.缓存穿透

产生的背景:

缓存穿透是指使用不存在的key进行大量的高并发查询,导致缓存无法命中,每次请求都要都要穿透到后端数据库查询,使得数据库的压力非常大,甚至导致数据库服务压死;

(高并发下,redis中不存在key,每次都要请求数据库,导致数据库服务器压力大)

解决方案:

  1. 接口层实现api限流、用户授权、id检查等;

  2. 从缓存和数据库都取不到数据的话,一样将数据库空值放入缓存中,设置30s有效期避免使用同一个id对数据库攻击压力大;

2.缓存击穿

产生背景:

在高并发的情况下,当一个缓存key过期时,因为访问该key请求较大,多个请求同时发现缓存过期,因此对多个请求同时数据库查询、同时向Redis写入缓存数据,这样会导致数据库的压力非常大;

(高并发下,key过期,多个请求同时发现过期,同时请求数据库,同时写入缓存,导致数据库服务器压力大)

解决方案:

  1. 使用分布式锁

保证在分布式情况下,使用分布式锁保证对于每个key同时只允许只有一个线程查询到后端服务,其他没有获取到锁的权限,只需要等待即可;这种高并发压力直接转移到分布式锁上,对分布式锁的压力非常大。

  1. 使用本地锁

使用本地锁与分布式锁机制一样,只不过分布式锁适应于服务集群、本地锁仅限于单个服务使用。

  1. 软过过期

设置热点数据永不过期或者异步延长过期时间;

  1. 布隆过滤器
3.缓存雪崩
			缓存雪崩指缓存服务器重启或者大量的缓存集中在某个时间段失效,突然给数据库产生了巨大的压力,甚至击垮数据库的情况。(大量key同时失效)
		
		解决思路:对不用的数据使用不同的失效时间,加上随机数

四、Redis Cluster集群

1.传统Redis集群存在那些问题

Redis哨兵集群模式,每个节点都保存全量同步数据,冗余的数据比较多;而在Redis Cluster模式中集群中采用分片集群模式,可以减少冗余数据,缺点就是构建该集群模式成本非常高。

2.传统RedisCluster集群的原理

Redis3.0开始官方推出了集群模式 RedisCluster,原理采用hash槽的概念,预先分配16384个卡槽,并且将该卡槽分配给具体服务的节点;通过key进行crc16(key)%16384 获取余数,余数就是对应的卡槽的位置,一个卡槽可以存放多个不同的key,从而将读或者写转发到该卡槽的服务的节点。 最大的优点:动态扩容、缩容。

3.RedisCluster集群模式环境搭建
mkdir rediscluster
cd rediscluster/
mkdir redis7000
mkdir redis7001
mkdir redis7002
mkdir redis7003
mkdir redis7004
mkdir redis7005

##每个配置文件内容
daemonize yes #后台启动
protected-mode no ; ## 允许外部访问
port 7005 #修改端口号,从7000到7005
cluster-enabled yes #开启cluster,去掉注释
cluster-config-file 7000nodes.conf #自动生成
cluster-node-timeout 15000 #节点通信时间
logfile /usr/rediscluster/redis7005/redis.log

##启动我们的redis
/usr/redis/bin/redis-server /usr/rediscluster/redis7000/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7001/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7002/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7003/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7004/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7005/redis.conf

##连接一个redis
/usr/redis/bin/redis-cli -h 192.168.212.163 -p 7000
> set wmh karma
(error) CLUSTERDOWN Hash slot not served  ##说明没有分配hash槽
##分配卡槽
> /usr/redis/bin/redis-cli --cluster create  192.168.212.163:7000  192.168.212.163:7001  192.168.212.163:7002  192.168.212.163:7003  192.168.212.163:7004  192.168.212.163:7005  --cluster-replicas 1 (建议最好使用服务器的ip地址搭建)

在这里插入图片描述

> /usr/redis/bin/redis-cli -h 192.168.212.163 -p 7000
(error MOVED 16365 127.0.0.1:7002)
## 添加-c 可自动跳转到该key存储的分片
> /usr/redis/bin/redis-cli -h 192.168.212.163 -p 7000 –c
> /usr/redis/bin/redis-cli --cluster help

4.RedisCluster集群模式扩容缩容节点

/usr/redis/bin/redis-server /usr/rediscluster/redis7006/redis.conf
/usr/redis/bin/redis-server /usr/rediscluster/redis7007/redis.conf
/usr/redis/bin/redis-cli -h 192.168.212.163 -p 7000

##Redis扩容
## 新增一个主节点 为7006
/usr/redis/bin/redis-cli --cluster add-node 192.168.212.163:7006   192.168.212.163:7000
## 新增一个从节点 为7007
/usr/redis/bin/redis-cli --cluster add-node   192.168.212.163:7007  192.168.212.163:7000  --cluster-slave   --cluster-master-id  5d94171eb34ed4396bf5b9db8efaab4d96d0cf10
## 新增的7006 是没有任何槽位 
## 分配Redis槽位扩容
cluster slots 
/usr/redis/bin/redis-cli --cluster reshard  192.168.212.163:7000

##Redis缩容
/usr/redis/bin/redis-cli --cluster  reshard  192.168.212.163:7000  --cluster-from   5d94171eb34ed4396bf5b9db8efaab4d96d0cf10  --cluster-to 511058958a3b80dd600e060c2500050c6c5a02ab  --cluster-slots