持久化的作用
什么是持久化
redis所有数据保存在内存中,对数据的更新将异步地保存在磁盘上
持久化的实现方式
- 快照:例如redis的RDB,MySQL的dump
- 写日志:例如MySQL的Binlog,Hbase的Hlog,redis的AOF
RDB
1.什么是RDB
一种快照,用于数据恢复和备份
2. 触发机制-主要三种方式
- save(同步)
127.0.0.1:6382> save
OK
因为是同步命令,所以容易对其他命令造成阻塞
文件策略:如果存在老的RDB文件,新替换老
复杂度:O(N)
2. bgsave(异步)
输入异步命令之后,redis会使用linux的fork函数生成主进程的一个子进程,由子进程去生成rdb,rdb生成之后会告诉主进程rdb文件生成成功。(fork()很快)
save与bgsave区别
3. 自动
redis的配置文件中有三条配置
save 900 1
save 300 10
save 60 10000
如果redis的数据在900秒内改变1次或者300秒内改变10次或者60秒内改变10000次,那么redis会自动执行bgsave来生成RDB文件。
缺点:我们无法控制RDB文件生成的频率,或者RDB生成频率太高,会对硬盘造成一定的压力
关于rdb的其他配置
dbfilename dump.rdb # RDB的文件名
dir ./ # 日志文件都存在当前目录下
stop-writes-on-bgsave-error yes # 如果bgsave发生错误,是否停止写入
rdbcompression yes # RDB文件是否采用压缩的格式
rdbchecksum yes # 是否对RDB文件进行检验
3. 触发机制-不容忽略方式
- 全量复制(主从复制时,会自动生成RDB文件)
- debug reload
- shutdown
4. 试验
127.0.0.1:6382> info memory # redis已使用内存
used_memory_human:890.05K
- save阻塞
- bgsave fork
- 真的自动
[root@iZ8vbhgs0bdip8zvxd6xjjZ logs]# tail -f 6382.log # 查看日志文件
26479:C 27 Nov 14:09:00.578 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
26479:C 27 Nov 14:09:00.578 # Redis version=4.0.6, bits=64, commit=00000000, modified=0, pid=26479, just started
26479:C 27 Nov 14:09:00.578 # Configuration loaded
26480:M 27 Nov 14:09:00.579 # Creating Server TCP listening socket 127.0.0.1:6382: bind: Address already in use
RDB总结
- RDB是Redis内存到硬盘的快照,用于持久化。
- save通常会阻塞Redis
- bgsave不会阻塞Redis,但是会fork新进程
- save自动配置满足任一就会被执行
- 有些触发机制不容忽视
AOF
RDB现存问题
- 耗时,耗性能(* O(n)数据:耗时;* fork():消耗内存,copy-on-write策略;*Disk I/O:IO性能)
- 不可控,丢失数据
T3-T4时间点的数据写入就会丢失
什么是AOF
redis宕机后,我们可以使用AOF将redis的数据进行恢复,而且它的恢复是实时的,因为只要我们写入一条命令,就会追加到AOF文件中。
AOF三种策略
- always
redis写命令不是直接写在硬盘中,而是写在硬盘的缓冲区中,缓冲区会根据一些策略将其刷新到硬盘中,
这样不会造成数据的丢失。 - everysec(每秒策略,是redis的默认值)
每秒刷新到硬盘中。
- no
操作系统决定什么时候刷新到硬盘中
三种策略比较
通常使用第二种策略。
AOF重写
AOF重写就是把重复的,过期的,没用的命令,都进行一个化简,化简成很小的AOF文件,达到以下两个命令,一是减少硬盘占用量;二是加速恢复速度。
AOF重写实现的两种方式
- bgrewriteaof
- AOF重写配置
no-appendfsync-on-rewrite 配置是指当AOF重写时,是否进行AOF正常的append操作,yes是不做,no是做,这里是不写,因为AOF重写是非常消耗性能的,因为要将子进程的数据刷到磁盘中,会有磁盘的消耗,而正常AOF也要将文件写道磁盘中,这两者会有一定的冲突。意思是在这期间,我是否允许数据的丢失,通常会选择在性能上做一个优先级。
AOF演示
127.0.0.1:6382> config get appendonly # 是否开启AOF
1) "appendonly"
2) "no"
127.0.0.1:6382> config set appendonly yes # 开启AOF
OK
127.0.0.1:6382> config rewrite # 开启重写
OK
127.0.0.1:6382> set hello world
OK
127.0.0.1:6382> set hello java
OK
127.0.0.1:6382> set hello redis
OK
127.0.0.1:6382> incr counter
(integer) 1
127.0.0.1:6382> rpush list a
(integer) 1
127.0.0.1:6382> rpush list b
(integer) 2
127.0.0.1:6382> rpush list c
(integer) 3
[root@iZ8vbhgs0bdip8zvxd6xjjZ logs]# ls # 此时生成了aof文件
6382.log access.log appendonly.aof dump.rdb error.log uwsgi.log
127.0.0.1:6382> bgrewriteaof # 重写AOF文件
Background append only file rewriting started
RDB和AOF的抉择
RDB和AOF比较
RDB最佳策略
- 将RDB关掉
- 集中管理,对数据备份有一定作用,按天,小时备份数据,RDB是个不错的选择,因为文件较小,传输速度较快,对备份数据有帮助。
- 主从,从开?在从节点开启RDB,这样可以保存历史的RDB文件,有一定优势。
AOF最佳策略
- 开
- AOF重写集中管理
- everysec
最佳策略
- 小分片(max memory)
- 缓存或存储
- 监控(硬盘,内存,网络,负载)