当在redis交互式十删除了二十G的数据,使用free -m,发现操作系统内存并没有释放,消耗掉的内存还是从前。因为redis会通过操作系统的com机制将数据段分为多个数据页面,所以各个页面也许都会你有的key存在,此时你需要使用flushdb刷新一下内存,清空各页面存在的key,此时再使用fee -m会发现内存已释放
rdb存储机制
redis在持久化时会fork一个子进程出来对快照进行持久化进行处理,交进程负责处理客户端的请求,子和父进程 共享内存里面的代码段和数据,子进程做数据持久化,不会修改现在的内存数据结构,它只是对数据结构遍历读取,然后序列化写到磁盘中。父进程不断持续服务客户端请求,然后对内存数据结构进行不间断的修改,这个时候会使用com机制来进行数据段页面的分离,数据段是由很多操作系统的页面组成,当父进程 对其中一个页面的数据进行修改时,会将被共享的页复制一份分离出来,然后对这个复制的页面进行修入,这时子进程相应的页面是没有变化的,还是进程产生那一瞬间的数据,随着父进程修改操作的持续进行,越来越多的共享页面被分离出来,内存就会持续增长,但是也不会超过原有数据内存的两倍大小。另外。另redis实例里冷数据占的比例往往是比较高的,所以很少会出现所有的页面被分离的情况,被分离的往往只有其中一部分页面。每个页面的大小只有四KB,一个redis实例里面一般都会有成千上万个页面。
aof原理
aof日志存储的是redis服务器的顺序指令序列,aof日志只记录对内存进行的修改的指令记录,redis会在收到客户端修改指令后,进行参数校验交,逻辑处理,如果没问题,就立即将指令文本存储到AOF日志中,也就是说,先执行指令才将日志存盘。
aof重写
随着时间的推移,aof的日志会越来越长,日志会越来越大,需要对aof进行瘦身
redis提供了bgrewriteaof指令用于对aof日志进行瘦身,原理就是开辟一个子进程对内存进行遍历,转换成一系列的redis的操作指令,序列化到一个新的aof日志文件中,序列化完毕后再将操作期间发生的增量aof日志追加到这个新的aof日志文件中,追加完毕后就立即替换旧的aof,由于新的aof文件去除了许多没有用占用空间的多余东西,所以新aof文件会比旧的aof占用空间容量要小很多