Redis 中所有数据保存在内存中,对数据的更新将异步保存到磁盘上。
主流数据库持久化方式:
1.快照:某个时间点数据的完整备份。例如 MySQL Dump、Redis RDB
2.写日志:数据库做了任何更新都写在日志中,当需要恢复数据的时候,只需要把日志拿过来重新走一遍这些操作。例如 MySQL Binlog、Hbase HLog、Redis AOF。
redis持久化的两种方式:
1.RDB
将redis内存中的数据完整的生成一个快照,然后保存到硬盘中一个RDB文件(二进制)。它也是一个复制的媒介,主从复制的时候会用到RDB的持久化方式,然后做一个复制文件的传输。
触发机制:
save 同步命令,会阻塞,其他命令都会排队,等save完成后才做其他命令。
执行save会生成RDB文件,如果存在老的文件,会被替换掉。
时间复杂度 o(n)
bgsave 异步命令,不会阻塞。
执行bgsave会使用linux的fork(),函数生成一个子进程,子进程完成RDB的生成。fork()会阻塞redis其他命令。
redis中查看上一次fork使用时间的命令 info:latest_fork_usec
生成RDB文件,如果存在老的文件,会被替换掉。
时间复杂度 o(n)
命令 | save | bgsave |
IO类型 | 同步 | 异步 |
阻塞 | 是 | 仅发生在fork() |
复杂度 | o(n) | o(n) |
优点 | 不会消耗额外内存 | 不会阻塞客户端命令 |
缺点 | 阻塞客户端命令 | 需要fork,消耗内存 |
自动
配置save触发RDB
配置 | seconds | changes | 触发自动RDB |
save | 900 | 1 | 900秒内改变1条数据,则触发自动RDB,用bgsave |
save | 300 | 10 | 300秒内改变10条数据,则触发自动RDB,用bgsave |
save | 60 | 10000 | 60秒内改变10000条数据,则触发自动RDB,用bgsave |
除save之外还有一些RDB相关配置属性
配置属性 | 默认配置 | 意思 | 推荐配置 |
save | 见上一个表格 | 建议关闭save | |
dbfilename | dump.rdb | 生成的RDB文件叫什么名字 | dump-${port].rdb |
dir | ./ | 生成的RDB文件、AOF文件、日志文件保存在什么路径中 | 不要使用当前目录,选择比较大的硬盘路径,可能还需要硬盘分盘 |
stop-writes-on-bgsave-error | yes | 如果bgsave发生了错误,是否停止写入 | yes |
rdbcompression | yes | RDB文件是否采用压缩格式 | yes |
rdbchecksum | yes | 是否对RDB文件进行检验 | yes |
全量复制(主从复制的时候主会生成RDB文件)触发RDB
debug reload 触发RDB
shutdown save触发RDB
2.AOF
数据库做了任何更新操作都写在AOF文件中。
AOF的三种策略
always redis每条命令都会fsync到硬盘AOF文件中,这种策略,恢复数据的时候不会有数据丢失。
everysec 默认用这种。每秒把缓冲区fsync到硬盘AOF文件中,这种策略,高写入量时,会适当保护硬盘。出现故障可能会丢失一秒的数据。
no 把缓冲区fsync到硬盘AOF文件中由操作系统觉得,操作系统觉得什么时候fsync就什么时候。
比较
命令 | always | everysec | no |
优点 | 不丢失数据 | 每秒一次fsync 可能会丢一秒的数据 |
不用管 |
缺点 | IO开销较大,一般sata盘只有几百TPS | 可能会丢一秒的数据 | 不可控 |
AOF重写
AOF重写,解决AOF文件无限增大的问题,减少硬盘占用量、加上恢复速度。
原生AOF | AOF重写 |
set hello word set hello word1 set hello word2 |
set hello word2 |
incr counter incr counter |
set count 2 |
rpush mylist a rpush mylist b rpush mylist c |
rpush mylist a b c |
AOF重写的两种实现方式
bgrewriteaof 用fork()函数出一个子进程,在子进程中重写AOF文件
AOF自动重写配置
配置名 | 含义 |
auto-aof-rewrite-min-size | AOF文件多大时才需要重写 |
auto-aof-rewrite-percentage | AOF文件增长率,下一次重写的条件 |
统计名 | 含义 |
aof_current_size | AOF当前尺寸(单位:字节) |
aof_base_size | AOF上次启动和重写的尺寸(单位:字节) |
AOF相关配置
配置属性 | 默认配置 | 意思 | 推荐配置 |
appendonly | no | 要使用AOF功能就要打开这个属性 | yes |
appendfilename | appendonly.aof | 生成的AOF文件叫什么名字 | appendonly-${port].aof |
appendfsync | .everysec | AOF同步的三种策略 | everysec |
dir | ./ | 生成的RDB文件、AOF文件、日志文件保存在什么路径中 | 不要使用当前目录,选择比较大的硬盘路径,可能还需要硬盘分盘 |
no-appendfsync-on-rewrite | no | AOF重写的时候不做正常的AOF append操作 | yes |
auto-aof-rewrite-percentage | 100 | AOF文件增长率,下一次重写的条件 | 100 |
auto-aof-rewrite-min-size | 64mb | AOF文件多大时才需要重写 | 64mb |
RDB和AOF的对比
RDB最佳策略
1.主节点关闭RDB
2.集中管理
3.从节点开RDB,不要太频繁。
AOF最佳策略
1.需要持久化就打开AOF,如果只把redis当缓存用,就没必要打开AOF了
2.AOF重写集中管理
3.建议使用everysec
最佳策略
1.小分片:控制redis的最大可用内存(maxmemory),不要太大了,建议4G左右。
2.监控(硬盘、内存、负载、网络)
3.机器内存大