一 持久化
Redis提供了2个不同形式的持久化方式 RDB 和 AOF
1.1 RDB
1)在指定的时间间隔内将内存中的数据集快照写入磁盘,也就是行话讲的Snapshot快照,它恢复时是将快照文件直接读到内存里。
2)备份是如何执行的
Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。
3)关于fork
在Linux程序中,fork()会产生一个和父进程完全相同的子进程,但子进程在此后多会exec系统调用,出于效率考虑,Linux中引入了“写时复制技术”,一般情况父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。
4)RDB保存的文件
在redis.conf中配置文件名称,默认为dump.rdb。
dbfilename dump.rdb
5)RDB文件的保存路径
默认为Redis启动时命令行所在的目录下,也可以修改。
6)RDB的保存策略
save 900 1
save 300 10
save 60 10000
7)手动保存快照
save:只管保存,其他不管,全部阻塞。
bgsave:按照保存策略自动保存。
8)RDB 的相关配置
①stop-writes-on-bgsave-error yes
- 当Redis无法写入磁盘的话,直接关掉Redis的写操作
②rdbcompression yes
- 进行rdb保存时,将文件压缩
③rdbchecksum yes
- 在存储快照后,还可以让Redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
9)RDB的备份和恢复
①备份:先通过config get dir 查询rdb文件的目录,将*.rdb的文件拷贝到别的地方。
②恢复:关闭Redis,把备份的文件拷贝到工作目录下,启动redis,备份数据会直接加载。
10)RDB 优缺点
①优点:节省磁盘空间,恢复速度快
②缺点:虽然Redis 在fork 时使用了写时复制技术,但是如果数据庞大的话还是比较消耗性能的,在备份周期在一定间隔时间做一次备份,所以如果Redis 意外 down 掉的话,就会失去最后一次快照后的所有修改。
1.2 AOF
1)以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据,换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。
2)AOF默认不开启,需要手动在配置文件中配置
# 开启AOF
appendonly yes
3)可以在 redis.conf 中配置文件名称,默认为 appendonly.aof
appendfilename "appendonly.aof"
4)AOF 和RDB 同时开启,那么Redis 会听谁的呢
5)AOF文件故障备份
- AOF的备份机制和性能虽然和RDB不同, 但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载
6)AOF文件故障恢复
- 如遇到AOF文件损坏,可通过
redis-check-aof --fix appendonly.aof
进行恢复
7)AOF 同步频率设置
# if unsure, use "everysec"
appendfsync always # 每执行一条命令就持久化一次
appendsync everysec # 每隔一秒钟就持久化一次
appendfsync no # 持久化的时机交给操作系统完成
8)Rewrite
- AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集.可以使用命令bgrewriteaof。
- Redis如何实现重写:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似
- 何时重写:重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。
1.3 混合持久化
1)Redis 在 4.0 版本之后,引入了混合持久化方式,而且在 5.0 版本后默认开启。前面讲到 RDB 加载速度快,但构建慢,缺少最新数据。AOF 持续追加最新写记录,可以包含所有数据,但冗余大,加载速度慢。混合模式一体化使用 RDB 和 AOF,综合 RDB 和 AOF 的好处。即可包含全量数据,加载速度也比较快。可以使用 aof-use-rdb-preamble 配置来明确打开混合持久化模式。
2)混合持久化也是通过 bgrewriteaof 来实现的。当启用混合存储后,进行 bgrewriteaof 时,主进程首先依然是 fork 一个子进程,子进程首先将内存数据以 RDB 的二进制格式写入 AOF 临时文件中。然后,再将落地期间缓冲的新增写指令,以命令的方式追加到临时文件。然后再通知主进程落地完毕。主进程将临时文件修改为 AOF 文件,并关闭旧的 AOF 文件。这样主体数据以 RDB 格式存储,新增指令以命令方式追加的混合存储方式进行持久化。后续执行的任务,以正常的命令方式追加到新的 AOF 文件即可。
3)混合持久化综合了 RDB 和 AOF 的优缺点,优势是包含全量数据,加载速度快。不足是头部的 RDB 格式兼容性和可读性较差。
二 事务
1)Redis事务是通过MULTI,EXEC,DISCARD,WATCH这四个命令来完成的。
2)Redis的单个命令都是原子性的,所以这里确保事务性的对象是命令的集合。
3)Redis将命令的集合序列化并确保处于同一事务的命令集合连续且不被打断的执行。
4)Redis不支持回滚的操作。
2.1 相关命令
- multi
1)用于标记事务块的开始
2)Redis会将后续的命令逐个放到队列中,然后使用exec命令原子化的执行这个命令序列。
3)语法:multi
- exec
1)在一个事务中执行所有先前放入队列的命令,然后恢复正常的连接状态
2)语法:exec
- discard
1)清除所有先前在一个事务中放入队列的命令,然后恢复正常的连接状态
2)语法:discard
- watch
1)当某个事务需要按条件执行时,就要使用这个命令将给定的键设置为受监控的状态
2)语法:watch key [key …..]
3)注:这个命令可以实现reids的乐观锁
- unwatch
1)清除所有先前为一个事务监控的键
2)语法:unwatch