Redis的持久化机制-RDB和AOF

1.什么是持久化

        简单的说就是指数据放到断电后,仍然不会丢失的设备上,也就是我们通常理解的硬盘上

2.数据库在进行写操作的时候,经历那些过程

  1. 客户端数据库服务端发送写操作(数据在客户端的内存中)
  2. 数据库服务端接收到写请求的数据(数据在服务端的内存中)
  3. 数据库服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)
  4. 操作系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)
  5. 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)

3.Redis提供了两种持久化机制

  1. RDB持久化机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘
  2. AOF持久化机制redis会将每一个收到的写命令都通过write函数追加到文件中(默认是 appendonly.aof)去

4.RDB持久化机制的详细介绍

    4.1-RDB是redis默认的持久化机制,这种方式是将内存中的数据以快照的形式写入到二进制文件中去,默认文件

名为dump.rdb

    4.2-实现方式是通过redis.conf文件中的配置实现的

save 900 1 //900秒内,如果超过了1个key被修改,则发起快照保存
save 300 10 //300秒内,如果超过了10个key被修改,则发起快照保存
save 60 10000

   4.3-RDB文件的保存过程

      4.3.1 符合RDB持久化条件时,redis调用fork,开启子进程,现在存在两个进程一个父进程,一个子进程

      4.3.2 父进程负责处理客户端请求,子进程负责把内存中的数据写入临时文件

      4.3.3 当子进程将快照完整的写入临时文件后,用临时文件替换原来的快照文件,退出子进程

          由于os的写时复制机制(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时

os会为父进程要修改的页面创建副本,而不是写共享的页面。所以子进程的地址空间内的数据是fork时刻

整个数据库的一个快照。

     4.4-redis-cli端也可以通过save或者bgsave命令来通知redis做一次快照持久化,save操作时通过主线程进行快照操作的,

由于redis是用一个主线程进行处理所有client端的请求,所以这种方式会阻塞所有的客户端请求

     4.5-采用RDB方式的优点

  1. 一旦采用这种方式,那么整个reids数据库就只包含一个文件,这样方便进行数据的备份(直接拷贝整个文件就可)
  2. 方便备份,可以很容易的把一个一个的RDB文件拷贝到其他存储介质上
  3. RDB在进行大数据集的恢复时,比AOF方式速度块
  4. RDB方式可以使Redis最大性能化,父进程在保存RDB文件数据时唯一要做的就是fork出一个子进程,子进程进行处理接下来RDB文件保存的所有工作,父进程无需进行任何的磁盘I/O操作

5.AOF持久化机制的详细介绍

     5.1 AOF持久化机制实现的方式-当redis重启时会通过重新执行appendonly.aof文件中的命令来在内存中重建整个数据库

     5.2 AOF持久化机制的实现方式

appendonly no // 默认不开启 开启配置 yes

appendfilename "appendonly.aof" // 默认redis写操作命令保存文件的文件名

# appendfsync always //每次收到写命令,立即强转写入磁盘,最慢的,保证完整的持久化
appendfsync everysec // 默认每秒强制写入磁盘一次,在性能和持久化方面做了折中,推荐
# appendfsync no //完全依赖os,性能最好,持久化没保证

    5.3 AOF持久化机制带来的问题,持久化文件会越来越大;但是文件中可能存在冗余的命令,举例说明:

执行incr count 命令100次,aof文件会记录100条命令的记录

上面的命令等价于

set count 100

如果能把上面100条命令替换成 下面的 一条命令,这样可以节省99条命令的空间

    5.4 针对aof记录冗余命令的情况,redis-cli客户端提供了bgrewriteaof命令,来压缩aof的持久化文件;收到此命令,redis会

使用与快照类似的方式将内存中的数据 以命令的方式写入到临时文件中去,最后替换原来的文件

      5.4.1 当redis-cli执行bgrewriteaof命令时,redis调用fork,开启子进程,现在存在两个进程一个父进程,一个子进程 

      5.4.2 子进程根据内存中的数据库快照,往临时文件中写入重建数据库的命令

      5.4.3 父进程继续处理client端的请求,此时,父进程除了把写命令写入原aof的持久化文件外;同时把收到的写命令缓存

起来,这部分命令是在子进程进行快照处理期间发生的操作,需要在临时文件快照处理完成后,追加到临时文件中去,这样

才能用临时文件替换原来的aof持久化文件

     5.4.4 当子进程把数据库快照内容已命令的方式写入临时文件完成后,子进程发送信号通知父进程,然后父进程把缓存的

命令写入临时文件

     5.4.5 现在父进程可以使用临时文件替换老的aof文件,后面收到的写命令也开始往新的aof文件中追加 

  5.5 AOF持久化的优势

    5.5.1  AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据

    5.5.2 AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek(查询) , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写

   5.5.3 AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析也很轻松。 导出 AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

注意可以开启混合持久化-配置属性为 aof-use-rdb-preamble yes

转载地址:http://www.cnblogs.com/xingzc/p/5988080.html

猜你喜欢

转载自blog.csdn.net/lihongtai/article/details/84852328