what
处理请求响应在同一个线程,无抢占式的调度系统,核心业务按照event loop顺序执行。
磁盘写日志开销很大,提供两种持久化方案。
分类
RDB Redis DataBase
按指定的时间间隔执行数据集的时间点快照。
默认持久化方案。
指定时间间隔内,写操作达到指定的次数,则会将内存中的数据写入到磁盘RDB文件中(fork一个child progress 把内存中的数据序列化到临时文件,在main event loop中原子的更换文件名。利用了操作系统VM的copy-on-write机制,在不阻塞主线程的情况下,利用子进程和父进程共享的data segment实现snapshot)。
RDB是一个十分紧凑的文件,比较容易备份。适合容灾备份。
Redis父进程不会执行磁盘I/O等操作的持久化操作,使用fork()才能使用子进程将其持久化在磁盘上。
RDB允许大型数据集更快地启动。
并不能完全保证数据的安全性。如果数据集database size很大,每一次snapshot可能会耗时过多。并且数据集很大且CPU性能不佳时,则可能导致Redis停止客户端服务几毫秒甚至一秒钟。该过程中如果出现宕机,则有可能数据丢失。
RDB持久化配置
redis.config中定位到 SNAPSHOTTING
save <seconds><changes>
save <指定时间间隔><执行指定次数更新操作>
满足条件就将内存中的数据同步到硬盘中。
dbfilename
指定本地数据库文件名,默认文件名为dump.rdb
dir
指定数据库存放目录
rdbcompression
开启数据压缩 默认为yes Redis采用LZF压缩方式。
RDB关闭
把官方默认的配置注释掉
save 900 1
save 300 10
save 60 10000
RDB快照触发
bgsave机制实现快照触发
- save策略触发
flush
命令(清空数据库所有数据)shutdown
(关闭redis)
RDB恢复
将dump.rdb
文件拷贝到redis的安装目录的bin目录下,重启redis服务即可。
AOF Append Only File (WAL)
记录服务器接收的每个写入操作,这些操作在服务器启动时再次播放,重建原始数据集。使用与Redis协议本身相同的格式记录命令,并且采用仅追加方式。日志太大时,可在后台重写日志。
优点
- 弥补RDB数据的不一致性的不足,采用日志的形式记录每个写操作,并追加到文件中。
- 更加持久,提供不同的fsync策略:
-
- 完全没有fsync
- 每秒fsync
- 每个查询fsync
- 使用默认fsync策略时,每秒的写入性能仍然很好(fsync是使用后台线程执行的,并且在没有进行fsync的情况下,主线程将尽力执行写入操作。
- 仅追加日志,日志错误也可以使用redis-check-aof工具修复。
- 通常情况下fsync设置为每秒的情况下,性能仍然很高。禁用fsync情况下,即使在高负载的情况下,理论上与RDB一样快。
缺点
- AOF文件大于等效RDB文件,并在特定的fsync策略时,AOF比RDB效率低。
- 即使在巨大的写负载的情况下,RDB仍然能提供有关最大延迟的更多个。但是如果fsync策略为always,则随着集群负载增大,AOF记录的内容越大,文件也会越来越多,数据恢复也会越来越慢。
将写操作追加到文件中,文件的冗余内容会越来越多。所以Redis 新增了重写机制,通过auto-aof-rewrite-min-size控制。当AOF文件的大小超过所设定的阈值时,Redis就会对AOF文件的内容压缩。
- 磁盘的操作依然比内存慢好几个数量级,频繁的操作容易产生瓶颈。
- 如果数据量操作频繁,会产生大量的重复日志数据,导致恢复时间太长。
AOF持久化配置
redis.config 中定位APPEND ONLY MODE
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-prewrite-percentage 100
auto-aof-rewrite-min-size 64mb
appendonly
配置redis 默认关闭 开启需要需要手动把no改成yes
appendfielname
制定本地数据库文件名,默认值为appendonly.aof
appendfsync
everysec 指定每秒更新(always everysec no)
auto-aof-rewrite-min-size
配置重写触发机制 当AOF文件大小是上次rewrite后大小的已被且文件大于64M触发
AOF触发
根据配置文件策略触发,可以是每次执行触发(always),可以是每秒触发(everysec),可以不同步(no)
AOF恢复
将appendonly.aof
文件拷贝到redis的安装目录bin下,重启redis服务即可。
可以通过redis-check-aof --fix appendonly.aof
修复
混合
AOF重建原始数据集,可以保证是最完整的。
禁用
只作为缓存服务器,对数据的持久性无要求。
how
- 文件写操作消耗的时间很长,redis会先把记录日志写在内存buffer中,在每一次event loop结束之后,根据配置判断是否做写操作。每个buffer的大小有限制,这样每次写操作时间不会太长。
- 即便是调用write操作,OS并没有立即写入磁盘,redis 同样提供了一些方案决定刷新OS IO buffer的时机(1秒、从不、每次)。
- 提供一种AOF重写的方式
rewriteAppendOnlyFile
来处理AOF文件过大情况。
- 为了避免加锁,redis 依然创建了一个child process,利用VM的copy-on-write,共享数据。同时保证主线程依然可以处理client请求。
- 根据KV的类型,先从内存读取数据,然后再写数据到磁盘,和之前的AOF文件无关。
- 那么当子进程rewrite AOF的过程中,main thread依然可以处理新的client request。新增的数据会被放在rewrite buffer中,而且写到原有的AOF文件中。
- child process完成后会通知主线程。主线程有一个定时任务,也就是会不断轮询child process是否已经完成(通过信号量)。
- 主线程会merge变化的数据到temp file。
- 主线程原子的rename到一个新的AOF文件,之前的AOF就不起作用了。
- 除了merge 和 rename需要阻塞主线程,rewrite不会阻塞主线程。(前提是使用bgrewrite command)。