9.单机持久化
- 持久化的思路
无论mysql还是redis持久化思路大致两个方案:
1.快照
2.日志
-
Linux 系统默认进程间数据隔离,但是父进程可以让子进程看见父进程的变量
-
创建子进程:
1.创建子进程的速度
2.创建子进程需要复制父进程的变量,内存是否够
- fork()
1.速度相对快
2.占用空间相对下
3.copyonwrite
- redis 非阻塞对外提供服务的情况下如何做数据RDB?
image.png
image.png
image.png
- RDB
优点:
节省空间
恢复数据速度快
缺点:
数据丢失
- AOF
redis写操作记录追加到文件中
- 优点
丢失数据少
可与RDB同时开启,AOF开启时只会以AOF进行恢复数据
4.0版本后将AOF中包RDB全量+AOF增量
- 缺点
占用空间大
恢复数据速度慢
- AOF做了那些优化
4.0前合并/抵消写日志
4.0后重写后RDB+AOF增量
开启AOF后,redis增删改等写操作将触发IO,当写操作过多时影响redis相应时间
appendfsync always:总是写入aof文件,并完成磁盘同步
appendfsync everysec:每一秒写入aof文件,并完成磁盘同步
appendfsync no:写入aof文件,不等待磁盘同步。
可见,从持久化角度讲,always是最安全的。从效率上讲,no是最快的。而redis默认设置进行了折中,选择了everysec。合情合理。
bgrewriteaof机制,在一个子进程中进行aof的重写,从而不阻塞主进程对其余命令的处理,同时解决了aof文件过大问题。
现在问题出现了,同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形,现在no-appendfsync-on-rewrite参数出场了。如果该参数设置为no,是最安全的方式,不会丢失数据,但是要忍受阻塞的问题。如果设置为yes呢?这就相当于将appendfsync设置为no,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),但是如果这个时候redis挂掉,就会丢失数据。丢失多少数据呢?在linux的操作系统的默认设置下,最多会丢失30s的数据。
因此,如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为yes。如果应用系统无法忍受数据丢失,则设置为no。