持久化(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。
持久化Redis全部数据保持在内存中,对数据的更新将异步地保存到磁盘上。redis
快照方式持久化就是在某时刻把全部数据进行完整备份。sql
例:Mysql的Dump方式、Redis的RDB方式。数据库
写日志方式持久化就是把用户执行的全部写指令(增删改)备份到文件中,还原数据时只须要把备份的全部指令从新执行一遍便可。安全
例:Mysql的Binlog、Redis的AOF、Hbase的HLog。服务器
RDB持久化方式可以在指定的时间间隔能对你的数据进行快照存储。
在默认状况下, Redis 将数据库快照保存在名字为 dump.rdb的二进制文件中。
在 Redis 运行时, RDB 程序将当前内存中的数据库快照保存到磁盘文件中, 在 Redis 重启动时, RDB 程序能够经过载入 RDB 文件来还原数据库的状态。app
当 Redis 须要保存 dump.rdb 文件时, 服务器执行如下操做:异步
这种工做方式使得 Redis 能够从写时复制(copy-on-write)机制中获益。工具
save
命令执行一个同步操做,以RDB文件的方式保存全部数据的快照。性能
127.0.0.1:6379> save OK
因为 save
命令是同步命令,会占用Redis的主进程。若Redis数据很是多时,save
命令执行速度会很是慢,阻塞全部客户端的请求。
所以不多在生产环境直接使用SAVE 命令,可使用BGSAVE 命令代替。若是在BGSAVE命令的保存数据的子进程发生错误的时,用 SAVE命令保存最新的数据是最后的手段。优化
bgsave
命令执行一个异步操做,以RDB文件的方式保存全部数据的快照。
127.0.0.1:6379> bgsave Background saving started
Redis使用Linux系统的fock()
生成一个子进程来将DB数据保存到磁盘,主进程继续提供服务以供客户端调用。
若是操做成功,能够经过客户端命令LASTSAVE来检查操做结果。
save
与 bgsave
对比命令 | save | bgsave |
---|---|---|
IO类型 | 同步 | 异步 |
阻塞? | 是 | 是(阻塞发生在fock(),一般很是快) |
复杂度 | O(n) | O(n) |
优势 | 不会消耗额外的内存 | 不阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 须要fock子进程,消耗内存 |
除了手动执行 save
和 bgsave
命令实现RDB持久化之外,Redis还提供了自动自动生成RDB的方式。
你能够经过配置文件对 Redis 进行设置, 让它在“ N 秒内数据集至少有 M 个改动”这一条件被知足时, 自动进行数据集保存操做。
好比说, 如下设置会让 Redis 在知足“ 60 秒内有至少有 1000 个键被改动”这一条件时, 自动进行数据集保存操做:
save 60 1000
# RDB自动持久化规则 # 当 900 秒内有至少有 1 个键被改动时,自动进行数据集保存操做 save 900 1 # 当 300 秒内有至少有 10 个键被改动时,自动进行数据集保存操做 save 300 10 # 当 60 秒内有至少有 10000 个键被改动时,自动进行数据集保存操做 save 60 10000 # RDB持久化文件名 dbfilename dump-<port>.rdb # 数据持久化文件存储目录 dir /var/lib/redis # bgsave发生错误时是否中止写入,一般为yes stop-writes-on-bgsave-error yes # rdb文件是否使用压缩格式 rdbcompression yes # 是否对rdb文件进行校验和检验,一般为yes rdbchecksum yes
快照功能(RDB)并非很是耐久(durable): 若是 Redis 由于某些缘由而形成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。 从 1.1 版本开始, Redis 增长了一种彻底耐久的持久化方式: AOF 持久化。
你能够在配置文件中打开AOF方式:
appendonly yes
打开AOF后, 每当 Redis 执行一个改变数据集的命令时(好比 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 从新启时, 程序就能够经过从新执行 AOF 文件中的命令来达到重建数据集的目的。
你能够经过配置文件配置 Redis 多久才将数据 fsync 到磁盘一次。
每次有新命令追加到 AOF 文件时就执行一次 fsync :很是慢,也很是安全。
每秒 fsync 一次:足够快(和使用 RDB 持久化差很少),而且在故障时只会丢失 1 秒钟的数据。
推荐(而且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略能够兼顾速度和安全性。
从不 fsync :将数据交给操做系统来处理,由操做系统来决定何时同步数据。更快,也更不安全的选择。
命令 | 优势 | 缺点 |
---|---|---|
always | 不丢失数据 | IO开销大,通常SATA磁盘只有几百TPS |
everysec | 每秒进行与fsync,最多丢失1秒数据 | 可能丢失1秒数据 |
no | 不用管 | 不可控 |
推荐(而且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略能够兼顾速度和安全性。
由于 AOF 的运做方式是不断地将命令追加到文件的末尾, 因此随着写入命令的不断增长, AOF 文件的体积也会变得愈来愈大。举个例子, 若是你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就须要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其他 99 条记录实际上都是多余的。
为了处理这种状况, Redis 支持一种有趣的特性: 能够在不打断服务客户端的状况下, 对 AOF 文件进行重建(rebuild)。执行 bgrewriteaof 命令, Redis 将生成一个新的 AOF 文件, 这个文件包含重建当前数据集所需的最少命令。
Redis 2.2 须要本身手动执行 bgrewriteaof 命令; Redis 2.4 则能够经过配置自动触发 AOF 重写。
bgrewriteaof 命令
Redis bgrewriteaof 命令用于异步执行一个 AOF(AppendOnly File)文件重写操做。重写会建立一个当前AOF文件的体积优化版本。
即便 bgrewriteaof 执行失败,也不会有任何数据丢失,由于旧的AOF文件在 bgrewriteaof 成功以前不会被修改。
AOF 重写由 Redis 自行触发,bgrewriteaof 仅仅用于手动触发重写操做。
具体内容:
配置名 | 含义 |
---|---|
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) * 100 / aof_base_size > auto-aof-rewrite-percentage
假设 Redis 的配置项为:
auto-aof-rewrite-min-size 64mb auto-aof-rewrite-percentage 100
当AOF文件的体积大于64Mb,而且AOF文件的体积比上一次重写之久的体积大了至少一倍(100%)时,Redis将执行 bgrewriteaof 命令进行重写。
# 开启AOF持久化方式 appendonly yes # AOF持久化文件名 appendfilename appendonly-<port>.aof # 每秒把缓冲区的数据同步到磁盘 appendfsync everysec # 数据持久化文件存储目录 dir /var/lib/redis # 是否在执行重写时不一样步数据到AOF文件 # 这里的 yes,就是执行重写时不一样步数据到AOF文件 no-appendfsync-on-rewrite yes # 触发AOF文件执行重写的最小尺寸 auto-aof-rewrite-min-size 64mb # 触发AOF文件执行重写的增加率 auto-aof-rewrite-percentage 100
- | RDB | AOF |
---|---|---|
启动优先级 | 低 | 高 |
体积 | 小 | 大 |
恢复速度 | 快 | 慢 |
数据安全性 | 丢数据 | 根据策略决定 |
通常来讲, 若是想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
若是你很是关心你的数据, 但仍然能够承受数分钟之内的数据丢失, 那么你能够只使用 RDB 持久化。
有不少用户都只使用 AOF 持久化, 但并不推荐这种方式: 由于定时生成 RDB 快照(snapshot)很是便于进行数据库备份, 而且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快。