1.Redis 持久化的意义

redis的数据全部在内存中,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证redis的数据在发生突发状况时不会丢失、或者只丢失少量,于是必须根据一些策略来把redis内存中的数据写到磁盘中,这样当redis服务重启时,就会将硬盘中的数据恢复到内存中。Redis持久化的意义就是为了保证突然宕机,内存数据不会全部丢失。

2.Redis 持久化机制

redis有两种持久化机制:RDB和AOF。每种持久化机制各有优缺点,了解每种持久化机制的原理对我们使用Redis有很大的帮助。Redis4.0后支持RDB和AOF两种持久化机制混合使用,所以存在三种持久化策略。

(1)RDB持久化

RDB是基于快照一次的全量备份,即周期性的把redis当前内存中的全量数据写入到一个快照文件中(周期时间可以通过配置来调整)。redis是单线程程序,这个线程要同时负责多个客户端的读写请求,还要负责周期性的把当前内存中的数据写到快照文件中RDB中,数据写到RDB文件是IO操作,IO操作会严重影响redis的性能,甚至在持久化的过程中,读写请求会阻塞,为了解决这些问题,Redis采用多进程来同时进行读写请求和持久化操作。这样又会导致另外的问题,持久化的过程中,内存中的数据还在改变,假如redis正在进行持久化一个大的数据结构,在这个过程中客户端发送一个删除请求,把这个大的数据结构删掉了,这时候持久化的动作还没有完成,那么redis该怎么办呢?

redis使用操作系统的多进程COW(Copy On Write)机制来实现快照的持久化,在持久化过程中调用 glibc(Linux下的C函数库) 的函数fork()产生一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端的读写请求。子进程刚刚产生时,和父进程共享内存里面的代码段和数据段,这是Linux操作系统的机制,为了节约内存资源,所以尽可能让父子进程共享内存,这样在进程分离的一瞬间,内存的增长几乎没有明显变化。

#1、linux中若父进程退出,子进程尚未结束,子进程不会立即退出。在linux中,所有进程都有一个共同的父进程systemd,如果父进程退出了,子进程还没运行结束,子进程会被systemd(老版本的linux是initd)收养。#2、RDB持久化时,Redis会fork()一个子进程,快照持久化完全交给子进程来处理,父进程继续处理客户端的读写请求。

子进程对当前内存中的数据进行持久化时,并不会修改当前的数据结构,如果父进程收到了读写请求,那么会把处理的那一部分数据复制一份到内存,对复制后的数据进行修改。所以即使对某个数据进行了修改,redis持久化到RDB中的数据也是未修改的数据,这也是把RDB文件称为"快照"文件的原因,子进程所看到的数据在它被创建的一瞬间就固定下来了,父进程修改的某个数据只是该数据的复制品。

实际上,内存中的全量数据由一个个的"数据段页面"组成,每个数据段页面的大小为4K,客户端要修改的数据在哪个页面中,就会复制一份这个页面到内存中,这个复制的过程称为"页面分离",在持久化过程中,随着分离出的页面越来越多,内存就会持续增长,但是不会超过原内存的2倍,因为在一次持久化的过程中,几乎不会出现所有的页面都会分离的情况,读写请求针对的只是原数据中的小部分,大部分redis数据还是"冷数据"。RDB过程整个过程如下图:

热点数据和冷数据是什么

  • 热点数据:读取频率高,如果不做缓存,给数据库造成很大的压力,可能被击穿。
  • 冷数据:读取频率低,数据设置缓存后有可能没有被访问就被挤出内存(超时dele)。

RDB有两种触发方式:自动触发和手动触发。

  • (1)自动触发:在 redis.conf 配置文件中的 SNAPSHOTTING 下配置save参数,来触发Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘。比如“save m n”:表示m秒内数据集存在n次修改时,自动触发bgsave。
//默认如下配置:
save 900 1:每隔900s(15min),如果有超过1个key发生了变化,就写一份新的RDB文件
save 300 10:每隔300s(5min),如果有超过10个key发生了变化,就写一份新的RDB文件
save 60 10000:每隔60s(1min),如果有超过10000个key发生了变化,就写一份新的RDB文件
(配置多种策略可以同时生效,无论满足哪一种条件都会写一份新的RDB文件)
  • (2)手动触发:手动生成新的RDB文件,执行Redis的save、bgsave命令。
save:阻塞主进程,直到生成新的RDB文件;执行save命令期间,Redis不能处理其他命令。
bgsave:异步生成RDB文件,fork子进程去生成新的RDB文件,主进程不阻塞。

(2)AOF持久化

AOF(Append-only file)日志存储的是redis服务器的顺序指令序列,即对内存中数据进行修改的指令记录。当redis收到客户端修改指令后,先进行参数校验,如果校验通过,先把该指令存储到AOF日志文件中,也就是先存到磁盘,然后再执行该修改指令。

redis把操作指令追加到AOF文件这个过程,并不是直接写到AOF文件中,而是先写到操作系统的内存缓存中,这个内存缓存是由操作系统内核分配的,然后操作系统内核会异步地把内存缓存中的redis操作指令刷写到AOF文件中。当redis宕机后重启后,可以读取该AOF文件中的指令,进行数据恢复,恢复的过程就是把记录的指令再顺序执行一次,这样就可以恢复到宕机之前的状态。

这儿存在一个问题,假如内存缓存中的redis指令还没有来得及刷写到AOF文件中就宕机了,那么这部分未刷写的指令就会丢失,不过,glibc函数库提供了 fsync() 函数,该函数可以将指定文件的内容强制从内存缓存中刷写到磁盘上。fsync操作的周期对redis的性能有很大影响,如何配置将在本文后续的内容中给出建议。AOF过程如下图:

redis在长期运行过程中,AOF日志会越来越大,如果redis服务重启后根据很大的AOF文件来顺序执行指令,将会非常耗时,导致redis服务长时间无法对外提供服务,所以需要对AOF文件进行"瘦身""瘦身"的过程称作AOF重写(rewrite)。

AOF Rewrite 的原理是,主进程fork一个子进程,对当前内存中的数据进行遍历,转换成一系列的redis操作指令,并序列化到一个新的AOF日志中,然后把序列化操作期间新收到的操作指令追加到新的AOF文件中,追加完毕后就立即替换旧的AOF文件,这样就完成了"瘦身"工作,即AOF Rewrite。AOF Rewrite过程如下图:

#1、AOF持久策略:fsync的策略,默认为everysec
appendfsync everysec
# everysec:每秒fsync一次,如果Redis宕机,1秒内的指令丢失。
# no:redis不主动fsync,完全交由操作系统决定
# always:1条指令fsync一次,保证数据一条不丢失

(3)混合持久化

redis-4.x后支持了RDB和AOF混合使用。重启redis时,我们很少使用RDB来恢复内存状态,因为会丢失大量数据。我们通常使用AOF日志重放,但是重放AOF日志性能相对RDB来说要慢很多,这样在redis实例很大的情况下,启动需要花费很长的时间。redis-4.0为了解决这个问题,带来了一个新的持久化选项——混合持久化。将RDB文件的内容和增量的AOF日志文件存在一起,这里的AOF日志不再是全量 的日志,而是RDB久化开始 到 RDB持久化结束的这段时间发生的增量AOF日志,通常这部分AOF日志很小。redis-4.x混合持久化机制如下图:

3.redis 持久化机制对比

(1)RDB的优缺点

优点:

  • RDB会生成多个数据文件,每个数据文件都代表了某一个时刻中redis的数据,这种多个数据文件的方式,非常适合做冷备,可以将这种完整的数据文件发送到一些远程的安全存储上去。

  • 生成RDB文件的时候,主进程不需要进行任何磁盘IO操作。当进行RDB持久化时,对redis服务处理读写请求的影响非常小,可以让redis保持高性能,因为redis主进程只需要fork一个子进程,让子进程执行磁盘IO操作来进行RDB持久化即可。生成一次RDB文件的过程就是把当前时刻内存中的数据一次性写入文件中,而AOF则需要先把当前内存中的小量数据转换为操作指令,然后把指令写到内存缓存中,然后再刷写入磁盘。

  • RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。AOF存放的是指令日志,做数据恢复的时候,要回放和执行所有的指令日志,从而恢复内存中的所有数据;而RDB,就是一份数据文件,恢复的时候,直接加载到内存中即可。

缺点:

  • RDB方式数据没办法做到实时持久化/秒级持久化,会导致数据丢失。一般来说,RDB数据快照文件,都是每隔5分钟,或者更长时间生成一次,这个时候就得接受一旦redis进程宕机,那么会丢失最近5分钟的数据。这个问题,也是RDB最大的缺点,就是不适合做第一优先的恢复方案,如果你依赖RDB做第一优先恢复方案,会导致数据丢失的比较多。

  • RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题(版本不兼容)。

  • RDB每次在fork子进程来执行RDB快照数据文件生成的时候,如果数据文件特别大,可能会导致对客户端提供的服务暂停数毫秒,甚至数秒。所以一般不要让生成RDB文件的间隔太长,否则每次生成的RDB文件太大了,对redis本身的性能会有影响。

(2)AOF的优缺点

优点:

  • AOF可以更好的保护数据不丢失,一般AOF会每隔1秒,通过一个后台线程执行一次fsync操作,最多丢失1秒钟的数据。

  • AOF日志文件以append-only模式(追加)写入,所以没有任何磁盘寻址的开销,写入性能非常高,而且文件不容易破损,即使文件尾部破损,也很容易修复。

  • AOF日志文件即使过大的时候,出现后台重写操作,也不会影响客户端的读写。因为在rewrite的时候,会对其中的指令进行压缩,会创建出一份需要恢复数据的最小日志出来。

  • AOF日志文件的命令通过非常可读的方式进行记录,这个特性非常适合做灾难性的误删除的紧急恢复。比如某人不小心用flushall命令清空了所有数据,只要这个时候后台rewrite还没有发生,那么就可以立即拷贝AOF文件,将最后一条flushall命令给删了,然后再将该AOF文件放回去,就可以通过恢复机制,自动恢复所有数据。

缺点:

  • 对于同一份数据来说,AOF日志文件通常比RDB数据快照文件更大。因为AOF是指令文件,RDB是二进制文件。

  • AOF的写性能比RDB的写性能低,因为AOF一般会配置成每秒fsync一次日志文件,当然,每秒一次fsync,性能也还是很高的,只不过比起RDB来说性能低,如果要保证一条数据都不丢,也是可以的,AOF的fsync设置成每写入一条数据,fsync一次,但是这样,redis的性能会大大下降。

  • 基于AOF文件做恢复的速度不如基于RDB文件做恢复的速度。

(3)混合持久化的优缺点

  • 优点:结合了RDB和AOF的优点,使得数据恢复的效率大幅提升

  • 缺点:兼容性不好,redis-4.x新增,虽然最终的文件也是.aof格式的文件,但在4.0之前版本都不识别该aof文件,同时由于前部分是RDB格式,阅读性较差。

(4)如何选择redis持久化机制

RDB和AOF到底该如何选择

  • 不要仅仅使用RDB,因为那样会导致丢失很多数据。

  • 也不要仅仅使用AOF,一是数据恢复慢,二是可靠性也不如RDB,毕竟RDB文件中存储的就是某一时刻实实在在的数据,而AOF只是操作指令,把数据转换为操作指令不一定是百分百没问题的。

  • 综合使用AOF和RDB两种持久化机制,用AOF来保证数据不丢失,作为数据恢复的第一选择; 用RDB来做不同程度的冷备,在AOF文件都丢失或损坏不可用的时候,还可以使用RDB来进行快速的数据恢复。

(5)AOF和RDB同时工作

  • redis在写RDB文件的时候不会执行AOF rewrite;redis在执行AOF rewrite的时候不会生成新的RDB。

  • 如果redis正在生成新的RDB文件,此时用户执行bgrewriteaof命令手动重写AOF文件,那么等RDB快照生成之后,才会去执行AOF rewrite。

  • 同时有RDB文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整。

4.redis 持久化机制的配置

######################### 通用 ########################## 持久化文件(包括RDB文件和AOF文件)的存储目录,默认.
dir dir /home/hadoop/data/redis/6379######################### RDB ########################## RDB文件的文件名称,默认dump.rdb
dbfilename dump.rdb# 生成RDB文件的策略,默认为以下3种,意思是:
# 每隔60s(1min),如果有超过10000个key发生了变化,就写一份新的RDB文件
# 每隔300s(5min),如果有超过10个key发生了变化,就写一份新的RDB文件
# 每隔900s(15min),如果有超过1个key发生了变化,就写一份新的RDB文件
# 配置多种策略可以同时生效,无论满足哪一种条件都会写一份新的RDB文件
save 900 1
save 300 10
save 60 10000# 是否开启RDB文件压缩,该功能可以节约磁盘空间,默认为yes
rdbcompression yes# 在写入文件和读取文件时是否开启rdb文件检查,检查是否有无损坏
# 如果在启动时检查发现文件损坏,则停止启动,默认yes
rdbchecksum yes######################### AOF ########################## 是否开启AOF机制,默认为no
appendonly yes# AOF文件的名称,默认为appendonly.aof
appendfilename "appendonly.aof"# fsync的策略,默认为everysec
# everysec:每秒fsync一次
# no:redis不主动fsync,完全交由操作系统决定
# always:1条指令fsync一次
appendfsync everysec# AOF文件rewrite策略
# 当上一次重写后的AOF文件的增长比例达到100%
# 比如上一次重写AOF文件后,新文件大小为128M
# 当新文件再次增长了100%,达到了256M
# 并且增长了100%后的文件的大小大于64M,那么开始重写AOF文件
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb# 是否加载破损的AOF文件,默认为yes,如果设置为no
# 那么redis启动时如果发现AOF文件破损,就会报错并且拒绝启动redis服务。
aof-load-truncated yes######################### 混合持久化 ########################## 是否开启混合持久化机制,默认为no
aof-use-rdb-preamble no

5.其他相关命令

  • 手动生成新的RDB文件
# 阻塞主进程,直到生成新的RDB文件
save
# 异步生成RDB文件,fork子进程去生成新的RDB文件,主进程不阻塞
bgsave
  • 手动重写AOF文件
bgrewriteaof
  • 停止redis服务
# 安全停止redis服务,在停止之前会生成一份新的RDB文件
redis-cli SHUTDOWN
# 不安全,会造成数据丢失
kill -9 redis_pid
  • 检查持久化文件
# 检查AOF文件
redis-check-aof /your/path/appendonly.aof
# 检查RDB文件
redis-check-rdb /your/path/dump.rdb
  • 修复AOF文件
#如果redis在append数据到AOF文件时,机器宕机了,可能会导致AOF文件破损,使用以下命令修复AOF文件
$REDIS_HOME/bin/redis-check-aof --fix
  • 查看持久化信息
# 查看持久化信息
info Persistence
# 查看状态信息
info stats

202年06月06日 晚 于北京记

Redis之持久化机制和实现原理相关推荐

  1. Redis数据持久化机制AOF原理分析一---转

    http://blog.csdn.net/acceptedxukai/article/details/18136903 http://blog.csdn.net/acceptedxukai/artic ...

  2. Redis数据持久化机制AOF原理分析二

    本文所引用的源码全部来自Redis2.8.2版本. Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c 在阅 ...

  3. Redis的持久化机制与内存管理机制

    1.概述 Redis的持久化机制有两种:RDB 和 AOF ,这两种机制有什么区别?正式环境应该采用哪种机制? 我们的服务器内存资源是有限的,如果内存被Redis的缓存占满了怎么办?这就要看Redis ...

  4. 执行一次怎么会写入两次数据_Java进阶知识:一文详解缓存Redis的持久化机制,新手看完也会用

    Redis 的数据全部在内存里,如果突然宕机,数据就会全部丢失,因此必须有一种机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的持久化机制. Redis有两种持久化的方式: ...

  5. redis的持久化机制详解

    redis的持久化机制 因为Redis的数据都储存在内存中,当进程退出时,所有数据都将丢失.为了保证数据安全,Redis支持RDB和AOF两种持久化机制有效避免数据丢失问题.RDB可以看作在某一时刻R ...

  6. 04【Redis的持久化机制】

    四.Redis的持久化机制 由于 Redis 是一个内存数据库,所谓内存数据库,就是将数据库中的内容保存在内存中,这与传统的MySQL,Oracle等关系型数据库直接将内容保存到硬盘中相比,内存数据库 ...

  7. redis rdb aof区别_理解Redis的持久化机制:RDB和AOF

    什么是Redis持久化? Redis作为一个键值对内存数据库(NoSQL),数据都存储在内存当中,在处理客户端请求时,所有操作都在内存当中进行,如下所示: 这样做有什么问题呢? 注 意 文末有:362 ...

  8. 面试官:能说说Redis的持久化机制吗?

    我们先来看这么一段面试场景-- 面试官:你们项目缓存技术用到了什么缓存技术? 小帅:Redis 面试官:那么问一下,Redis缓存技术用到的持久化机制是哪一种机制? 小帅:AOF 面试官:好吧,回去等 ...

  9. Redis面试 - Redis的持久化机制

    Redis面试 - Redis的持久化机制 面试题 redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的? 面试官心理分析 redis 如果仅仅只是将数据缓 ...

最新文章

  1. (0061)iOS开发之iPad开发:UISplitViewController分割视图控制器
  2. 01H5-fe-html5-005插入音频
  3. erlang进程的调度效率
  4. ngx_event_expire_timers
  5. 团队天梯赛L1-001
  6. (原)python爬虫入门(2)---排序爬取的辽宁科技大学热点新闻
  7. 多吉搜索不能用了_「转载」一个纯粹的中文搜索引擎:「Doge Doge」多吉搜索
  8. 自动驾驶 4-1 二维运动学建模Kinematic Modeling in 2D
  9. python能运行vb_vb编程 vb还是python强大
  10. 毫米和像素怎么换算_像素和厘米怎么换算?
  11. Badboy内置浏览器,提示脚本错误解决方法
  12. Partitioning by Palindromes UVA - 11584(DP)
  13. Word文档怎么横向排版?这三种方法简单高效专业
  14. VBA使用PING测试网络连接
  15. 破解服务中共性问题的繁琐处理方式——接入 API 网关
  16. 自动取款机取款属于计算机应用,贵州电大2018年春季学期计算机应用基础01任务(含答案)...
  17. 苹果x怎么关闭应用程序_苹果x手机密码忘记了怎么解锁
  18. 复合继承关系下的构造和析构
  19. Office Excel 文件格式保存--兼容模式
  20. 离职后如何清空电脑账号资料

热门文章

  1. “妈妈说”马云:创业要在合适的时间拿适量的钱
  2. 微星VS华硕!谁才是伟大的AMD主板之王
  3. 魅族mx3升级到android6.0,魅族MX3怎么升级系统?魅族MX3固件升级图文教程详解
  4. 即时通讯音视频开发之移动端开发的几个建议
  5. 全链路设计师是什么?如何打造全链路设计师?
  6. 【ADC】ADC介绍
  7. 色彩鲜艳摄影调色效果lr预设
  8. QQ视频下载并转化为mp4
  9. Codeforces Round #481 (Div. 3) F. Mentors(思维+二分)
  10. 黑马java学成在线项目 第1天 讲义-项目概述 CMS接口开发 三