日志
AOF
AOF日志
在Redis的写操作过程中 每次执行命令都会把命令通过追加顺序写入文件中
同时AOF还支持三种写会机制有·
- Always
- EverySec
- No
缺点
AOF记录的是命令 如果在同步的时候AOF过大会导致恢复数据缓慢 引起阻塞
AOF如果记录的命令过长 也会有重做日志的操作来优化大小
AOF的重写机制
AOF日志是一个文件 随着时间推移会越来越大 为了避免AOF文件过大 Redis提供了一种重写AOF机制来压缩文件
bgrewriteaof
为什么使用子进程?
- AOF重写期间不会阻塞主进程
- 子进程带有主进程的数据副本 这里用的是进程不是线程 因为线程会共享资源
如果多线程同时访问相同资源时需要加锁 会影响性能
CopyOnWrite(COW)
主进程在fork子进程bgrewriteaof
的时候 会把主进程的页表
复制一份给子进程
这个页表记录了虚拟地址和物理地址的映射关系 不会复制物理内存,即主子进程的虚拟内存不同但是对应的物理内存的映射是相同的
这样就可以做到父子进程共享同一块内存的读操作
COW 只在写的时候复制「写时复制(Copy On Write)」。
如果父子进程需要对这块内存进行写操作 那么就会中断CPU的保护,将父子进程的权限设置为可读写 并且复制一份内存给子进程
为什么要Cow?
这就同时牵扯到大Key问题 在发生写操作的时候OS才去复制物理内存 这样做的目的主要是防止fork子进程创建时 由于物理内存数据过大导致复制时间过长 从而引起阻塞问题、
通过这个机制 就可以很优雅的解决重写AOF日志过程中由于复制时间过长导致主进程阻塞的问题
缓冲区
AOF重写缓冲区
、AOF缓冲区
如果在重写AOF日志过程中,主进程修改了已经存在的Key-Value,那么就会导致父子进程之间的数据不一致
在AOF重做期间 ,Redis执行完命令后 会同时将这个命令写入AOF缓冲区
和AOF重写缓冲区
当子进程完成AOF重写后 会将缓冲区中的命令也追加到新的AOF文件中
然后修改AOF文件名覆盖旧的文件
总结
AOF重写日志
会自己起一个子线程去记录恢复过程中的新数据
在renameAOF文件之前合并
RDB
RDB快照
记录的是某一时刻的所有数据
save 和 bgsave
bgsave过程
该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。
两种日志都会起fork线程来记录
内存过期删除策略
过期策略的底层源码
1.惰性删除
在访问一个key的时候再去检查下他的存活时间 判断他是否删除了
显然这样就存在一个问题:
如果一个key过期后再也没有被访问过了 那么他就会一直存在内存中站着茅坑不拉屎 那么就会造成内存空间的大量损耗!
2.周期删除
这个策略会周期的抽取部分过期的key然后删除
过期删除的流程:
1.随机抽取20个key
2.如果这20个key中有超过5个key过期了 就继续重复步骤1 进行循环删除(应该是认为有相当一部分的key可能同时过期了)