redis持久化
-
RDB持久化:定时的将redis在内存的数据进行快照并压缩保存到硬盘里
- 手动触发:手动执行 bgsave 命令
- 自动触发:满足配置文件中 save n m 的规则(在n秒内发生了m次数据更新就会自动触发);主从复制在做全量复制时;执行shutdown命令关闭数据库时
- 工作流程:redis主进程会fork子进程来进行RDB持久化快照保存内存数据到硬盘里,文件名为 dump.rdb
- 优缺点:RDB持久化保存的文件占用空间较小,网络传输快,恢复速度比AOF更快,性能影响比AOF更小
- 实时性不如AOF,兼容性较差,持久化期间在fork子进程时会阻塞redis主进程响应客户端命令
-
AOF持久化:实时的以追加的方式将redis写操作命令保存到aof文件里
- 工作流程:命令追加(将写操作命令追加到aof_buf缓冲区)
- 文件写入和同步(按照同步策略将缓冲区里的数据同步到硬盘,文件名:appendonly.aof;同步策略:everysec(每秒刷盘一次)、always(每条命令写入都刷盘)、no(让系统自行刷盘))
-文件重写(减少aof文件占用空间和加快恢复速度,定时执行bgrewriteaof命令触发)
- 文件写入和同步(按照同步策略将缓冲区里的数据同步到硬盘,文件名:appendonly.aof;同步策略:everysec(每秒刷盘一次)、always(每条命令写入都刷盘)、no(让系统自行刷盘))
- 优缺点:实时性比RDB更好,支持秒级持久化,兼容性较好;
- 持久化保存的文件占用空间更大,恢复速度更慢,性能影响更大,AOF文件重写期间在fork子进程时也会阻塞redis主进程,且IO压力更大
- 工作流程:命令追加(将写操作命令追加到aof_buf缓冲区)
RDB和AOF的区别可从 工作方式、实时性、占用空间、恢复速度、兼容性、IO性能影响 这几方面进行描述。
redis性能优化:
- 设置内存上限(maxmemory),并设置内存数据淘汰策略(maxmemory-policy),一般采用lru或random
- 开启AOF持久化(实时性好),设置AOF刷盘策略为everysec;关闭自动AOF文件重写,采用定期在业务低峰期执行bgrewriteaof命令触发AOF文件重写,减少IO的压力
- 开启自动内存碎片清理(activedefrag yes)
- 缩短键值对存储长度,避免存储bigkey导致操作耗时(建议string类型数据控制在20KB以内,hash、list、set、zset控制元素数量在5000以内)
- 给key设置合理的过期时间,尽量避免大量key集中过期
- 开启lazy-free机制(lazyfree-lazy-* yes),将删除过期key的操作放到后台线程执行,减少大量的删除操作对redis主进程的阻塞
- 尽量使用物理机而非虚拟机部署redis服务,使用高速固态硬盘作为AOF日志的写入盘
- 使用分布式架构(主从复制、哨兵、集群)实现读写分离、分散bigkey来提升读写速度,并实现高可用
- 禁用内存大页(echo never > /sys/kernel/mm/transparent_hugepage/enabled),因为开启内存大页会到fork子进程的速度变慢,也会拖慢写操作的执行速度
redis的三大缓存问题:
正常情况下,大部分的访问请求应该时先被redis缓存响应,在redis那里得不到响应的小部分访问请求才会去请求MySQL数据库获取数据,这样MySQL数据库的负载压力会非常小,能够正常稳定工作。
缓存雪崩/穿透/击穿问题的根本原因是在于redis缓存命中率下降,大量请求会直接发送给MySQL数据库,导致数据库负载压力过大而崩溃。
缓存雪崩:redis中大量不同的缓存key集中过期
缓存穿透:大量请求访问redis和MySQL数据库都不存在的数量
缓存击穿:redis中一个热点key过期,此时又有大量请求访问这个热点key
缓存雪崩解决方案:
使用随机数设置key的过期时间,防止集中过期
设置二级缓存
使用互斥锁,在查数据库时加锁,缓冲大量请求
缓存穿透解决方案:
使用布隆过滤器进行判断拦截一定不存在的无效请求
对空值数据也进行缓存
在业务层使用脚本等方式对用户的请求进行校验,排查非法请求
缓存击穿解决方案:
对热点缓存不设置过期时间
预先对热点数据进行缓存预热
使用互斥锁,在查数据库时加锁,缓冲大量请求