springboot实战电商项目mall4j (https://gitee.com/gz-yami/mall4j)
Redis持久化及内存优化
通过redis的配置文件来进行的一些持久化及内存优化操作,如有错误欢迎指导。
1. 为什么需要持久化
如果将用户数据保存到内存中,在服务器断电或者宕机时则会导致内存数据将清空,导致缓存数据清空。
2. 关于持久化文件使用流程
在我们安装了redis之后,所有的配置都在redis.conf文件中,里面保存了RDB和AOF两种持久化机制的各种配置。
命令:
save: 表示当前数据持久化一次,生成RDB文件。
bgsave: 内存数据在后台持久化一次,生成RDB文件。
命令区别:
save: 当执行save指令时不允许用户继续set操作,陷入阻塞。
bgsave: 当执行bgsave时,表示通知redis需要进行持久化操作了,这时redis会根据用户的使用情况进行持久化,不会陷入阻塞,类似于gc(垃圾回收机制)。
持久化文件使用规则:
当程序正常运行时会生成持久化文件,如果当服务器宕机后重启时,会根据配置文件中指定的持久化文件,进行数据的恢复。
3. RDB模式
3.1 说明:
RDB优势
-
RDB模式是redis默认的持久化策略,文件紧凑,全量备份,非常适合用于进行备份和灾难恢复。
-
生成RDB文件的时候,redis主进程会fork()一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。
-
RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。
-
RDB模式每次操作时记录内存数据的快照,持久化文件较小。
RDB问题:
1.耗时,内存消耗,IO性能消耗,将内存中的所有数据转储到硬盘上需要花费一定的时间时间。Bgsave模式fork()子进程占用额外的内存,大量的硬盘读写也会消耗IO性能。
2.无法控制的数据丢失,在停机期间,上次快照之后写入的内存数据将丢失。
3.2 修改持久化文件的名称和持久化文件保存的路径
3.3 RDB模式默认快照方式
save 900 1 在900s之内,至少有1个key发生变化,则将快照写入磁盘。
save 300 10 在300之内,至少有10个key发生变化,则将快照写入磁盘。
save 60 10000 在60s之内,至少有10000个key发生变化,则将快照写入磁盘。
4. AOF模式
4.1什么是AOF
Redis的RDB模式全量备份总是耗时的,AOF模式是对RDB模式的补充。当开启AOF模式(两种都打开时AOF的优先级高于RDB模式)时,每次执行redis write命令时,该命令会同时记录日志(以AOF结尾的日志文件)。当Redis发生故障时,只要执行日志回放,就可以恢复数据。
4.2 开启AOF模式
修改Redis配置文件,改为yes即可。
4.3 AOF的持久化策略
#appendfsync always #每次有数据发生变化时都会写入appendonly.aof
#appendfsync everysec #默认方式,每秒同步一次到appendonly.aof
#appendfsync no #不同步,数据不会持久化
no-appendfsync-on-rewrite no #当AOF日志文件即将增长到指定百分比时,redis通过调用BGREWRITEAOF是否自动重写AOF日志文件。
通常使用everysec策略,这也是AOF的默认策略。
4.4 AOF日志重写功能
当AOF的日志文件过大,redis会自动重写AOF日志,append模式不断的将更新记录写入到老日志文件中,同时redis还会创建一个新的日志文件用于追加后续的记录。
Aof重写可以大大减小最终日志文件的大小。从而减少磁盘消耗并加快数据恢复。例如,我们有一个计数服务,该计数服务具有许多自动递增操作,例如将密钥自动递增到1亿,这对于AOF文件来说是1亿incr。Aof重写仅记录一个记录。
4.5 两种AOF重写的方法
- Bgrewriteaof命令触发AOF重写 Redis客户端将bgrewriteaof命令发送到Redis,并且Redis服务器派生一个子进程来完成AOF重写。此处的AOF重写是将Redis内存中的数据追溯到AOF文件。而不是重写AOF文件以生成要替换的新AOF文件。
- AOF 重写配置
- auto-aof-rewrite-min-size:重写AOF文件所需的大小
- auto-aof-rewrite-percentage :AOF文件增长
- aof_current_size:计算AOF的当前大小(字节)
- aof_base_size:上一次启动和重写AOF的大小(字节)
- AOF自动重写的触发时间应同时满足以下两点:
- aof_current_size > auto-aof-rewrite-min-size
- aof_current_size - aof_base_size/aof_base_size > auto-aof-rewrite-percentage
5. RDB和AOF对比
启动优先级 | 低 | 高 | 当同时启用RDB和AOF时,重新启动Redis后选择AOF进行恢复。在大多数情况下,它保存的数据比RDB更新 |
体积 | 小 | 大 | RDB以二进制模式存储并压缩。尽管AOF被AOF重写,但是它的容量相对较大。毕竟它是以日志记录的形式 |
恢复速度 | 快 | 慢 | RDB体积小,恢复速度较快。AOF量大,恢复缓慢。 |
数据安全 | 丢数据 | 根据策略决定 | RDB在最后一个快照后会丢失数据。AOF根据Always,everysec和No的策略来决定是否丢失数据。 |
轻重 | 重 | 轻 | Aof是一个追加日志,因此它是一个轻量级的操作。RDB是一项占用大量CPU的操作,会占用大量磁盘以及对内存消耗会比较大。 |
6. Redis内存优化策略
Redis支持多种内存驱逐策略以限制内存使用量,部分基于LRU和LFU的算法。
6.1 LRU算法
LRU是Least Recently Used的缩写,即最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。该算法赋予每个页面一个访问字段,用来记录一个页面自上次被访问以来所经历的时间 t,当须淘汰一个页面时,选择现有页面中其 t 值最大的,即最近最少使用的页面予以淘汰。
时间T:数据自上一次到现在的时间。
6.2 LFU算法
说明:LFU算法是redis5以后才提出的。
LFU(least frequently used (LFU) page-replacement algorithm)。即最不经常使用页置换算法,要求在页置换时置换引用计数最小的页,因为经常使用的页应该有一个较大的引用次数。但是有些页在开始时使用次数很多,但以后就不再使用,这类页将会长时间留在内存中,因此可以将引用计数寄存器定时右移一位,形成指数衰减的平均使用次数。
6.3 Redis内存优化
noeviction (default) | 如果在尝试插入更多数据时内存溢出,则返回错误 |
allkeys-lru(recommended if unsure) | 从所有数据中删除最近最少使用的数据 |
allkeys-lfu | 从所有数据中删除最不常用的数据 |
allkeys-random | 从所有数据中随机删除数据 |
volatile-lru | 删除所有数据中最近最少使用的数据,并设置“过期”字段 |
volatile-lfu | 从设置了“过期”字段的所有数据中删除最不常用的数据 |
volatile-random | 设定了“过期”字段的数据随机删除 |
volatile-ttl | 在设置了“过期”字段的所有数据中,删除最短的生存时间数据。 |
5.4 修改redis配置文件
修改maxmemory-policy属性,选择合适的策略即可。