Redis高可用
一、Redis高可用概念
Redis当中,高可用的概念更加宽泛一些。除了正常的冗余功能之外,数据量的扩容,数据安全等也属于Redis高可用的内容。
1.1 实现高可用的方式
- 持久化
- 主从复制
- 哨兵(主从复制基础上)
- Redis集群(cluster)
其中持久化是最简单的高可用方法,以至于有时会被从高可用的范畴中移除。持久化是简单、基础而重要的功能。
1.2 Redis的持久化
持久化就是把内存当中的数据保存到硬盘。开启持久化之后会有一个持久化文件,通过文件进行恢复。
Redis提供的持久化方式:RBD持久化和AOF持久化。
二、RBD持久化
2.1 RDB持久化原理
RDB持久化,会定时地将内存当中的数据保存到磁盘上,类似于快照的形式用二进制压缩存储,后缀名是.rdb
每次Redis重新启动时,都会重新读取rdb文件
2.2 RDB持久化配置方法
vim /etc/redis/6379.conf
# --254行--
dbfilename dump.rdb
## RDB持久化的默认文件# --264行--
dir /var/lib/redis/6379
## RDB持久化文件的保存目录# --219-221行--
## 格式save time count
## 当时间到time秒,如果Redis的数据发生了count次变化,就会执行bgsave
save 900 1
## 当时间到900秒,如果Redis的数据发生了1次变化,就会执行bgsave
save 300 10
## 当时间到了300秒,如果Redis的数据发生了10次变化,就会执行bgsave
save 60 10000
## 当时间到了60秒,如果Redis的数据发生了10000次变化,就会执行bgsave
2.3 为什么使用bgsave而不是save
生产环境中,save是禁用的。因为一旦执行save,创建rdb文件是由Redis主进程进行创建,此时Redis主进程会进入阻塞状态,读写都要等待,直到save完成。
bgsave相当于rdb快照保存的方式。bgsave提交到主进程,会fork(后台进程)创建一个子进程,在生成子进程的过程中,主进程会进入阻塞,直到子进程生成完毕,主进程解除阻塞(这个阻塞的时间很短)。然后由fork的子进程生成dump.rdb文件,生成完成后主进程回收子进程。
如果bgsave的时候,子进程已存在,正在执行,则主进程不会调用fork,会正常工作,直接由已存在的子进程创建rdb文件。
在执行关闭Redis的时候,会把缓存中的数据同步到从,相当于执行bgsave。
bgsave是主从复制的默认恢复模式,从节点执行全量恢复操作,主节点通过bgsave命令把rbd文件发送给从节点。
除了配置文件,save time count中的配置之外,开启Redis也会执行bgsave。
三、AOF持久化
3.1 AOF持久化原理
AOF持久化是把操作的数据库执行命令以日志形式保存在指定的文件当中,文件的后缀名.aof。类似于mysql的binlog,通过命令的方式进行恢复。但比binlog格式更简单一些,没有时间,没有位置,只有命令。
AOF的持久化的实时性更好,只要是操作了都会记录在日志文件中,进程出现意外时,丢失的数据更少,AOF是主流的持久化方式。
RDB和AOF两者是配合使用的,一般全量备份用RDB。
AOF默认是关闭的,需要开启。如果同时开启RDB和AOF,系统默认会选择AOF进行恢复。所以RDB一般不需要特意去关闭。
3.2 AOF持久化配置
vim /etc/redis/6379.conf# --700行-- 修改
appendonly yes
## 启用AOF持久化# --704行--
appendfilename "appendonly.aof"
## 默认AOF持久化文件名# --730行--
appendfsync everysec
##每秒都会自动更新一次# --752行--
no-appendfsync-on-rewrite no
## 控制在执行 AOF 重写时是否允许在重写期间执行 `fsync()` 操作。no即不允许# --800行--aof-load-truncated yes
## 如果发现AOF文件被截断,Redis在启动时会自动修复AOF的文件,尽可能的对数据进行恢复。
## 如果设置为no,Redis发现AOF文件被截断会拒绝启动。
3.3 AOF持久化的工作方式
bgwriteaof
命令,提交到主进程,主进程fork
一个子进程,子进程来创建AOF文件。fork
的过程中主进程会阻塞,直到子进程fork
完成。
子进程创建AOF文件完成后,主进程会回收子进程,如果子进程存在时继续提交bgwriteaof
,会在当前子进程上继续创建AOF文件,写入到旧的AOF文件当中。
重写:bgrewriteaof
一旦开启AOF持久化之后,所有的数据库操作记录必然都会写入AOF持久化文件当中。
问题就此出现:AOF文件会随着操作记录的增多而越来越大。一旦要恢复,速度会很慢。
AOF重写就是为了压缩AOF持久化文件,是 Redis 的一种优化操作,它会重写当前 AOF 文件,去除其中的冗余写操作,从而减小 AOF 文件的大小,并且保持了数据的完整性。
在执行 BGREWRITEAOF
命令时,Redis 会启动一个后台进程来执行 AOF 重写操作,这个过程中会扫描现有的 AOF 文件,生成一个新的更紧凑的 AOF 文件,用于替换旧的 AOF 文件。这样可以减少磁盘空间的使用,并且在 Redis 重启时加快 AOF 文件的加载速度。
后续有新的读写,会继续追加到AOF文件。
3.4 RBD持久化和AOF持久化的优缺点
-
RDB文件小,传输速度很快,恢复速度也很快,适合全量复制,所以是主从复制的默认模式,性能上影响较小。
-
AOF是秒级的持久化,数据量全,兼容性也好,适合做数据迁移。缺点是文件大,回复速度慢,性能影响较大。支持全量和增量。
-
生产环境中,数据安全是最重要的指标,所以AOF的应用场景更广。
四、对Redis做资源限制
进入Redis查询资源使用情况
#查看Redis占用内存
info memory
#对查询结果的解释
# Memory
used_memory:853336
## Redis中数据占用内存的大小,单位字节
used_memory_human:833.34K
used_memory_rss:14639104
## Redis向系统申请的内存,随着数据占用的大小,自动扩容
used_memory_rss_human:13.96M
used_memory_peak:853336
## Redis占用系统内存的峰值
used_memory_peak_human:833.34K#设置Redis各项阈值
vim /etc/redis/6379.conf
# --567行-- 取消注释
maxmemory 2gb
##设置Redis占用系统内存的最大值
内存碎片化率:
内存碎片化率=Redis向系统申请的内存/Redis数据实际占用的内存
#查看内存碎片化率
redis-cli info memory | grep ratio
#对查询结果的解释
allocator_frag_ratio:1.27
##分配器的碎片化比例,值越大,碎片越多,内存浪费也越多
allocator_rss_ratio:9.54
##分配器占用物理内存的比例
rss_overhead_ratio:1.26
##表示占用物理内存的额外开销的比例,这个值越小越好
##说明Redis实际使用的物理内存比rss更接近
mem_fragmentation_ratio:20.87
##表示内存的碎片比例,已经分配但是没有利用的内存
清理内存碎片
vim /etc/redis/6379.conf
#自动清理内存碎片,解注释以下行,1370行左右
activedefrag yes#手动清理内存碎片
redis-ctl memory purge
五、redis的故障:缓存击穿和缓存雪崩
5.1 缓存雪崩
Redis产生了大面积的故障,大量缓存数据丢失,所有的请求全部转发到了数据库。而数据库不适合处理高并发,很快会导致集群崩溃,然后系统瘫痪。
可能原因:
- 缓存数据大量的同时过期,新的缓存没有及时生成
- Redis服务集群崩溃了
- 人为
怎么预防:
- Redis集群做高可用方案:持久化、主从、哨兵、集群。
- 如果访问量过大, 超过了Redis本身的负载能力,应用熔断机制,Hystrix可以实现熔断,降级、限流来降低雪崩的概率。
5.2 缓存击穿
可能原因
- Redis的缓存数据有一部分丢失,导致对这部分数据的请求转发到了数据库
- 或者是缓存杠杠过期,新缓存还没有建立,对这部分数据的请求转发到了数据库
防范机制:
- 数据库的热点缓存数据设置为永不过期
- 持久化、高可用
举例:
发现经常使用的热点语句,查询速度突然变的很慢,查找问题,发现该热点数据对应的缓存键值对消失了。
因为我没有Redis的密码,我报告给了数据库的部门。
或我进入了Redis的数据库,set重新创建了这个热点数据的缓存,解决了这个问题。
5.3 缓存穿透
现象:
- 非常少见,很大几率是被黑客攻击。
- 利用缓存和数据库里都没有的数据,用户一直在发起请求,利用大量的请求压垮数据库,进而导致网站崩溃。
防范机制
- 防火墙,只能起到一定的作用
- 验证拦截(消息队列),需要手动完成,可以判断是否是攻击行为
- 缓存空的数据,生命周期短一些,以防止恶意攻击