1.4.1 配置文件中修改 maxmemory-policy 属性值
2.4.4 修改 Redis 配置文件(Master节点操作)
2.4.5 修改 Redis 配置文件(Slave节点操作)
3.6.2 修改Redis 哨兵模式的配置文件(所有节点操作)
一、redis性能管理
1.1 查看Redis内存使用
127.0.0.1:6379> info memory
1.2 内存碎片率
操作系统分配的内存值 used_memory_rss 除以 Redis 使用的内存总量值 used_memory 计算得出。内存值 used_memory_rss 表示该进程所占物理内存的大小,即为操作系统分配给 Redis 实例的内存大小。除了用户定义的数据和内部开销以外,used_memory_rss 指标还包含了内存碎片的开销, 内存碎片是由操作系统低效的分配/回收物理内存导致的(不连续的物理内存分配)。
(1)内存碎片率稍大于1是合理的,这个值表示内存碎片率比较低,也说明 Redis 没有发生内存交换。
(2)内存碎片率超过1.5,说明Redis消耗了实际需要物理内存的150%,其中50%是内存碎片率。需要在redis-cli工具上输入shutdown save 命令,让 Redis 数据库执行保存操作并关闭 Redis 服务,再重启服务器。
(3)内存碎片率低于1的,说明Redis内存分配超出了物理内存,操作系统正在进行内存交换。需要增加可用物理内存或减少 Redis 内存占用。
1.3 内存使用率
redis实例的内存使用率超过可用最大内存,操作系统将开始进行内存与swap空间交换。
1.3.1 避免内存交换发生的方法
(1)针对缓存数据大小选择安装 Redis 实例
(2)尽可能的使用Hash数据结构存储
(3)设置key的过期时间
1.4 内回收key
内存清理策略,保证合理分配redis有限的内存资源。当达到设置的最大阀值时,需选择一种key的回收策略,默认情况下回收策略是禁止删除。
1.4.1 配置文件中修改 maxmemory-policy 属性值
vim /etc/redis/6379.conf
(1)volatile-lru:使用LRU算法从已设置过期时间的数据集合中淘汰数据(移除最近最少使用的key,针对设置了TTL的key)
(2)volatile-ttl:从已设置过期时间的数据集合中挑选即将过期的数据淘汰(移除最近过期的key)
(3)volatile-random:从已设置过期时间的数据集合中随机挑选数据淘汰(在设置了TTL的key里随机移除)
(3)allkeys-lru:使用LRU算法从所有数据集合中淘汰数据(移除最少使用的key,针对所有的key)
(4)allkeys-random:从数据集合中任意选择数据淘汰(随机移除key)
(5)noenviction:禁止淘汰数据(不删除直到写满时报错)
1.5 缓存穿透
1.5.1 原因
黑客或者其他非正常用户频繁进行很多非正常的 url 访问,使得 redis 查询不到数据库。
1.5.2 条件
(1)应用服务器压力变大
(2)redis 命中率降低
(3)一直查询数据库,使得数据库压力太大而压垮
1.5.3 解决方案
(1)对空值缓存:如果一个查询返回的数据为空(不管是数据是否不存在),我们仍然把这个空结果(null)进行缓存,设置空结果的过期时间会很短,最长不超过五分钟。
(2)设置可访问的名单(白名单):使用 bitmaps 类型定义一个可以访问的名单,名单 id 作为 bitmaps 的偏移量,每次访问和 bitmap 里面的 id 进行比较,如果访问 id 不在 bitmaps 里面,进行拦截,不允许访问。
(3)采用布隆过滤器:布隆过滤器(Bloom Filter)是 1970 年由布隆提出的。它实际上是一个很长的二进制向量 (位图) 和一系列随机映射函数(哈希函数)。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
(4)进行实时监控:当发现 Redis 的命中率开始急速降低,需要排查访问对象和访问的数据,和运维人员配合,可以设置黑名单限制服务。
1.6 缓存击穿
1.6.1 原因
redis 某个 key 过期了,大量访问使用这个 key(热门 key)
1.6.2 现象
数据库访问压力瞬时增加,数据库崩溃,redis 里面没有出现大量 key 过期。
1.6.3 解决方案
(1)预先设置热门数据:在 redis 高峰访问之前,把一些热门数据提前存入到 redis 里面,加大这些热门数据 key 的时长。
(2)实时调整:现场监控哪些数据热门,实时调整 key 的过期时长。
(3)使用锁:就是在缓存失效的时候(判断拿出来的值为空),不是立即去 load db。先使用缓存工具的某些带成功操作返回值的操作(比如 Redis 的 SETNX)去 set 一个 mutex key。当操作返回成功时,再进行 load db 的操作,并回设缓存,最后删除 mutex key;当操作返回失败,证明有线程在 load db,当前线程睡眠一段时间再重试整个 get 缓存的方法。
1.7 缓存雪崩
1.7.1 缓存雪崩与缓存击穿的区别
(1)缓存雪崩是指在同一时间内,缓存中大量的或者说大规模的key集体失效,这可能是由于缓存设置了相同的过期时间,导致在这一时间点上大量请求落到数据库上,造成数据库压力急剧上升,甚至可能导致数据库崩溃。因此,缓存雪崩针对的是很多key的缓存。
(2)缓存击穿是指一个热点key突然失效(例如过期),而这个时候恰好有大量的并发请求查询这个key,因为缓存中已经没有这个数据,所有的请求都会落到数据库上,对数据库造成巨大压力。缓存击穿通常针对的是单一key的高并发访问。
1.7.2 解决方案
(1)构建多级缓存架构:nginx 缓存 + redis 缓存 + 其他缓存(ehcache 等)。
(2)使用锁或队列:用加锁或者队列的方式来保证不会有大量的线程对数据库一次性进行读写,从而避免失效时大量的并发请求落到底层存储系统上,该方法不适用高并发情况。
(3)设置过期标志更新缓存:记录缓存数据是否过期(设置提前量),如果过期会触发通知另外的线程在后台去更新实际 key 的缓存。
(4)将缓存失效时间分散开:比如可以在原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。
二、主从复制
2.1 概念
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(Master),后者称为从节点(Slave);数据的复制是单向的,只能由主节点到从节点。默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
2.2 作用
(1)数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
(2)故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
(3)负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
(4)高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
2.3 流程
(1)若启动一个Slave机器进程,则它会向Master机器发送一个“sync command”命令,请求同步连接。
(2)无论是第一次连接还是重新连接,Master机器都会启动一个后台进程,将数据快照保存到数据文件中(执行rdb操作),同时Master还会记录修改数据的所有命令并缓存在数据文件中。
(3)后台进程完成缓存操作之后,Master机器就会向Slave机器发送数据文件,Slave端机器将数据文件保存到硬盘上,然后将其加载到内存中,接着Master机器就会将修改数据的所有操作一并发送给Slave端机器。若Slave出现故障导致宕机,则恢复正常后会自动重新连接。
(4)Master机器收到Slave端机器的连接后,将其完整的数据文件发送给Slave端机器,如果Mater同时收到多个Slave发来的同步请求,则Master会在后台启动一个进程以保存数据文件,然后将其发送给所有的Slave端机器,确保所有的Slave端机器都正常。
2.4 配置
2.4.1 关闭防火墙和核心防护
systemctl stop firewalld
setenforce 0
2.4.2 安装
yum install -y gcc gcc-c++ make
tar zxvf redis-5.0.7.tar.gz -C /opt/
或wget -p /opt http://download.redis.io/releases/redis-5.0.7.tar.gz
cd /opt/redis-5.0.7/
make
make PREFIX=/usr/local/redis install
cd /opt/redis-5.0.7/utils
./install_server.sh
2.4.3 软连接
ln -s /usr/local/redis/bin/* /usr/local/bin/
2.4.4 修改 Redis 配置文件(Master节点操作)
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行,指定工作目录
appendonly yes #700行,开启AOF持久化功能
/etc/init.d/redis_6379 restart
2.4.5 修改 Redis 配置文件(Slave节点操作)
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.133.10 6379 #288行,指定要同步的Master节点IP和端口
appendonly yes #700行,开启AOF持久化功能
/etc/init.d/redis_6379 restart
三、哨兵
3.1 概念
当服务器宕机后,需要手动一台从机切换为主机,这需要人工干预,不仅费时费力而且还会造成一段时间内服务不可用。为了解决主从复制的缺点,就有了哨兵机制。
3.2 原理
哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。 哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过 sentinel代理访问redis的主节点,当出现故障时通过投票机制选择新的 Master并将所有slave连接到新的 Master。所以整个运行哨兵的集群的数量不得少于3个节点,并且将新的master信息通知给client端。
这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息。Redis服务是通过配置文件启动的,比如上面的从节点设置了只读模式,它被选举成了master之后就是可读写的了。
3.3 作用
监控:哨兵会不断地检查主节点和从节点是否运作正常。
自动故障转移:当主节点不能正常工作时,哨兵会开始自动故障转移操作,它会将失效主节点的其中一个从节点升级为新的主节点,并让其它从节点改为复制新的主节点。
通知(提醒):哨兵可以将故障转移的结果发送给客户端。
3.4 故障转移机制
1、由哨兵节点定期监控发现主节点是否出现了故障
每个哨兵节点每隔1秒会向主节点、从节点及其它哨兵节点发送一次ping命令做一次心跳检测。如果主节点在一定时间范围内不回复或者是回复一个错误消息,那么这个哨兵就会认为这个主节点主观下线了(单方面的)。当超过半数哨兵节点认为该主节点主观下线了,这样就客观下线了。
2、当主节点出现故障,此时哨兵节点会通过Raft算法(选举算法)实现选举机制共同选举出一个哨兵节点为leader,来负责处理主节点的故障转移和通知。所以整个运行哨兵的集群的数量不得少于3个节点。
3、由leader哨兵节点执行故障转移,过程如下:
(1)将某一个从节点升级为新的主节点,让其它从节点指向新的主节点;
(2)若原主节点恢复也变成从节点,并指向新的主节点;
(3)通知客户端主节点已经更换。
3.5 主节点的选举
1、过滤掉不健康的(已下线的),没有回复哨兵 ping 响应的从节点。
2、选择配置文件中从节点优先级配置最高的。(replica-priority,默认值为100)
3、选择复制偏移量最大,也就是复制最完整的从节点。
哨兵的启动依赖于主从模式,所以须把主从模式安装好的情况下再去做哨兵模式。
3.6 配置
3.6.1 关闭防火墙和核心防护
systemctl stop firewalld
setenforce 0
3.6.2 修改Redis 哨兵模式的配置文件(所有节点操作)
vim /opt/redis-5.0.7/sentinel.conf
17 protected-mode no #关闭保护模式
21 port 26379 #Redis哨兵默认的监听端口
26 daemonize yes #指定sentinel为后台启动
36 logfile "/var/log/sentinel.log" #指定日志存放路径
65 dir "/var/lib/redis/6379" #指定数据库存放路径
84 sentinel monitor mymaster 192.168.133.10 6379 2 #指定该哨兵节点监控192.168.133.10:6379这个主节点,该主节点的名称是mymaster,最后的2的含义与主节点的故障判定有关:至少需要2个哨兵节点同意,才能判定主节点故障并进行故障转移
113 sentinel down-after-milliseconds mymaster 30000 #判定服务器down掉的时间周期,默认30000毫秒(30秒)
146 sentinel failover-timeout mymaster 180000 #146行,故障节点的最大超时时间为180000 (180秒 )
3.6.3 启动哨兵模式
注意:先启master,再启slave
cd /opt/redis-5.0.7/
redis-sentinel sentinel.conf &
3.6.4查看哨兵信息
redis-cli -p 26379 info sentinel
3.6.5 故障模拟
1、查看并杀死master节点的redis-server
ps -ef | grep redis
kill -9 进程号 #Master节点上redis-server的进程号
2、再次查看哨兵信息
redis-cli -p 26379 INFO Sentinel
补充 :脚本