Redis 持久化RDB与AOF
一、RDB与AOF持久化简介
RDB持久化【保存的是数据】方式能够在指定的时间间隔能对你的数据进行快照存储.【就是镜像备份文件(save 900 10)[dbfilename dump.rdb]】
单独使用缺点:1、异常重启时会丢失指定时间间隔内的数据。
AOF持久化【保存的是所有执行的命令】方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的 操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
单独使用缺点:1、RDB 恢复数据集的速度也要比 AOF 恢复的速度要快
2、使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
二、RDB和AOF内存占用问题
若是启用了Redis快照功能,应该设置“maxmemory”值为系统可使用内存的45%,因为快照时需要一倍的内存来复制整个数据集,也就是说如果当前已使用45%,在快 照期间会变成95%(45%+45%+5%),其中5%是预留给其他的开销。 如果没开启快照功能,maxmemory最高能设置为系统可用内存的95%。
三、Redis持久化磁盘IO方式及其带来的问题
有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持久化的fork系统调用造成内存占用加倍而导致的,这种观点是不准确的,因为fork 调用的copy-on-write机制是基于操作系统页这个单位的,也就是只有有写入的脏页会被复制,但是一般你的系统不会在短时间内所有的页都发生了写入而导致复制,那么是什么原因导致Redis崩溃的呢?
答案是Redis的持久化使用了Buffer IO造成的,所谓Buffer IO是指Redis对持久化文件的写入和读取操作都会使用物理内存的Page Cache,而大多数数据库系统会使用Direct IO来绕过这层Page Cache并自行维护一个数据的Cache,而当Redis的持久化文件过大(尤其是快照文件),并对其进行读写时,磁盘文件中的数据都会被加载到物理内存中作为操作系统对该文件的一层Cache,而这层Cache的数据与Redis内存中管理的数据实际是重复存储的,虽然内核在物理内存紧张时会做Page Cache的剔除工作,但内核很可能认为某块Page Cache更重要,而让你的进程开始Swap ,这时你的系统就会开始出现不稳定或者崩溃了。我们的经验是当你的Redis物理内存使用超过内存总容量的3/5时就会开始比较危险了。
解决方案:设置maxmemory以及maxmemory-policy。
maxmemory-policy volatile-lru
内存不足"时,数据清除策略,默认为"volatile-lru"。
volatile-lru ->对"过期集合"中的数据采取LRU(近期最少使用)算法.如果对key使用"expire"指令指定了过期时间,那么此key将会被添加到"过期集合"中。将已经过期/LRU的数据优先移除.如果"过期集合"中全部移除仍不能满足内存需求,将OOM.
allkeys-lru ->对所有的数据,采用LRU算法
volatile-random ->对"过期集合"中的数据采取"随即选取"算法,并移除选中的K-V,直到"内存足够"为止. 如果如果"过期集合"中全部移除全部移除仍不能满足,将OOM
allkeys-random ->对所有的数据,采取"随机选取"算法,并移除选中的K-V,直到"内存足够"为止
volatile-ttl ->对"过期集合"中的数据采取TTL算法(最小存活时间),移除即将过期的数据.
noeviction ->不做任何干扰操作,直接返回OOM异常
另外,如果数据的过期不会对"应用系统"带来异常,且系统中write操作比较密集,建议采取"allkeys-lru"
三、redis持久化使用场景
1、数据备份
2、容灾备份
四、对于我们常用redis的场景下,我们一般不会只用redis的持久化,也会持久化数据到物理数据库中。那么,对于AOF持久化我个人觉得跟物理数据库是一个作用了。
那么重启redis,恢复内存数据有三种场景:
1、在只开启了redis RDB持久化的情况下,可恢复到指定版本。【恢复效率高,但存在数据丢失】
2、在只开启了redis AOF持久化的情况下,可根据aof备份恢复完整数据。 【恢复效率低于RDB,但数据完整】
3、同时开始RDB和AOF时,redis默认以AOF文件恢复。
4、编写代码,查询物理数据库中的数据,存储到redis,恢复时执行程序。【实现复杂,效果最差,不推荐】
五、redis持久化推荐配置
建议只开启AOF持久化。【redis承担数据缓存的责任,另外有数据库进行存贮】
1、RDB持久化:定时生成 RDB 快照(snapshot)非常便于进行数据库备份【可以根据需求恢复到不同版本的数据集.】。
【维护redis,确保数据备份的方法】
- 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个 RDB 文件备份到另一个文件夹。
- 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每日快照。
- 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理机器之外。
2、AOF持久化:AOF 文件所保存的数据通常是最完整。【恢复完整数据】