Redis 是内存数据库,如果不将内存中的数据库状态保存到磁盘,那么一旦服务器进程退出,服务器中的数据库状态也会消失。所以 Redis 提供了持久化功能!
Redis 提供了不同级别的持久化方式: RBD(redis database) 和 AOF(Append Only File)
RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.
AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.
如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始:
原理:
当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作:
Redis 调用forks. 同时拥有父进程和子进程。
子进程将数据集写入到一个临时 RDB 文件中。
当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。
这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。主从复制的时候一般拿RDB文件来做从机上面的数据源
在默认情况下, Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。你可以对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被满足时, 自动保存一次数据集。
你也可以通过调用 SAVE或者 BGSAVE , 手动让 Redis 进行数据集保存操作。
比如说, 以下设置会让 Redis 在满足“ 600 秒内有至少有 5 个键被改动”这一条件时, 自动保存一次数据集。
tips:这里只有到了600s之后才会生成dump文件,
1.只需要将rdb文件放在我们redis启动目录就可以,redis启动的时候会自动检查dump.rdb 恢复其中的数据!
2.查看需要存在的位置
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/bin" # 如果在这个目录下存在 dump.rdb 文件,启动就会自动恢复其中的数据
1.满足save的条件。例如:save 900 1 15分钟内有1条就保存
2.退出redis。就是shutdown
3.flushall命令,但是这个命令优点问题,会产生文件,但是内容是空的。如下图所示。
###########################################
#flushall这种方式不能重新加载数据,dump文件是可以生成,但是没有数据。怀疑只是生成文件,但是内容是空的
127.0.0.1:6379> set name xht
OK
127.0.0.1:6379> set age 26
OK
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> shutdown
not connected> exit
[root@izbp19nv7e19wvineu7g9uz bin]# redis-server xhtconfig/redis.conf
[root@izbp19nv7e19wvineu7g9uz bin]# redis-cli -p 6379
127.0.0.1:6379>
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379>
flushall虽然可以生成rdb文件,但是并不会有数据保存!
这是flushall之后生成的dump.rdb文件
这是shutdown,exit之后文件的内容,可以看出内容还是有不一致的地方。
执行命令截图:可以看出没有数据!持久化失败。
这是shutdown之后的dump.rdb文件
这是执行的命令截图:
快照功能并不是非常耐久(dura ble): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。
从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。
将我们的所有命令都记录下来,history,恢复的时候就把这个文件全部在执行一遍!
AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制:
1.Redis 执行 fork() ,现在同时拥有父进程和子进程。
2.子进程开始将新 AOF 文件的内容写入到临时文件。
3.对于所有新执行的写入命令,父进程一边将它们累积到一个内存缓存中,一边将这些改动追加到现有 AOF 文件的末尾,这样样即使在重写的中途发生停机,现有的 AOF 文件也还是安全的。
4.当子进程完成重写工作时,它给父进程发送一个信号,父进程在接收到信号之后,将内存缓存中的所有数据追加到新 AOF 文件的末尾。
5.搞定!现在 Redis 原子地用新文件替换旧文件,之后所有命令都会直接追加到新 AOF 文件的末尾。
Aof保存的是 appendonly.aof 文件
1.为最新的 dump.rdb 文件创建一个备份。为最新的 dump.rdb 文件创建一个备份。
2.执行以下两条命令:config set appendonly yes config set save "" tips:这里用命令的形式,并不会改变文件里面的内容,所以重启之后需要手动改配置文件的这2个配置,否则重启不生效!
3.确保写命令会被正确地追加到 AOF 文件的末尾。
1.你可以在配置文件中打开AOF方式: appendonly yes
2.同时在rdb设置里面,save "",方可生效!!!!这样shutdown之后,也不会生成rdb文件!
aof 默认就是文件的无限追加,文件会越来越大!
如果 aof 文件大于 64m,太大了! fork一个新的进程来将我们的文件进行重写!
日志重写相当于是把命令重组了,类似于:set name xht set name xht1 set name xht2 合并成 set name xht2---------据说有bug0.0可能最终的结果有些出入
因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。举个例子, 如果你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。
为了处理这种情况, Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对 AOF 文件进行重建(rebuild)。执行 BGREWRITEAOF 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。Redis 2.2 需要自己手动执行 BGREWRITEAOF 命令; Redis 2.4 则可以自动触发 AOF 重写, 具体信息请查看 2.4 的示例配置文件。
推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
1.每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全
2.每秒 fsync 一次:足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
3.从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。
文件出现问题,启动server服务就不成功
解决:回退到bin目录下面,执行命令---redis-check-aof --fix appendonly.aof
1、适合大规模的数据恢复!(体积相对于aof较小)
2、对数据的完整性要不高!
1、需要一定的时间间隔进程操作!如果redis意外宕机了,这个最后一次修改数据就没有的了!
2、fork进程的时候,会占用一定的内容空间。
1、每一次修改都同步,文件的完整会更加好!
2、每秒同步一次,可能会丢失一秒的数据
1、相对于数据文件来说,aof远远大于 rdb,修复的速度也比 rdb慢!
2、Aof 运行效率也要比 rdb 慢,所以我们redis默认的配置就是rdb持久化
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
Note: 因为以上提到的种种原因, 未来官方可能会将 AOF 和 RDB 整合成单个持久化模型。
1.因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留 save 900 1 这条规则。
2.如果Enable AOF ,好处是在最恶劣情况下也只会丢失不超过两秒数据,启动脚本较简单只load自己的AOF文件就可以了,代价一是带来了持续的IO,二是AOF rewrite 的最后将 rewrite 过程中产生的新数据写到新文件造成的阻塞几乎是不可避免的。只要硬盘
许可,应该尽量减少AOF rewrite的频率,AOF重写的基础大小默认值64M太小了,可以设到5G以上,默认超过原大小100%大小重写可以改到适当的数值。
3.如果不Enable AOF ,仅靠 Master-Slave Repllcation 实现高可用性也可以,能省掉一大笔IO,也减少了rewrite时带来的系统波动。代价是如果Master/Slave 同时倒掉,会丢失十几分钟的数据,启动脚本也要比较两个 Master/Slave 中的 RDB文件,载
入较新的那个,微博就是这种架构。
原文:https://www.cnblogs.com/xiahaitao/p/14761705.html