虚拟内存

Redis的数据保存在内存中,可能出现物理内存不足的情况。物理内存不足时,Redis使用“虚拟内存”解决

Redis的VM与操作系统的VM相似,把很少访问的value保存到磁盘中。同时,Redis把value对应的key都放在内存中,为了能够让Redis快速定位到被换出的value所在磁盘位置,从而将其导入到内存中

相比操作系统的VM,redis的VM的优势:

1.操作系统的VM是基于页的概念,比如Linux系统中每个页是4KB,而Redis大多数对象远小于4KB,一页上可能有多个Redis对象。另外Redis的集合对象类型如List、set可能存在于多个页上。故Redis自己实现可达到控制换入的粒度

2.Redis将交换到磁盘的对象压缩,保存到磁盘的对象可以去除指针和对象元数据信息。一般压缩后的对象比内存中的对象小10倍,这样Redis的VM比操作系统的VM少做很多I/O操作

配置文件信息

#开启VM功能

vm -enabled yes

#交换出来的value保存的文件路径/tmp/redis.swap

vm -swap -file  /tmp/redis.swap

#Redis使用的最大内存上限,超过上限后Redis开始交换value到磁盘文件中

vm -max -memory 268435456

#设置每个页面的大小为32个字节

vm -page -size 32

#最多在文件中使用多少页面,SWAP文件的大小等于vm -page -size * vm -pages

vm -pages 134217728

#用于执行value对象换入换出的工作线程数量。0表示不使用工作线程

vm -max -threads 4

Redis的VM只把value交换到磁盘中,而key依然存储在内存中,目的是让开启VM的Redis和完全使用内存的Redis性能基本保持一致。如果由于太多key而造成内存不足问题,Redis的VM并不能解决

Redis也按照页来交换对象,一页只能保存一个对象,但是一个对象可以保存在多页中。当Redis使用的内存没有超过设置的vm-max-memory之前,不把任何value交换到磁盘中;当超过最大内存限制后,Redis根据以下算法寻找一个对象交换到磁盘中:

swappability = age * log(size_in_memory)

age代表这个对象距离上一次被访问的时间,size_in_memory是这个对象在内存中占用的空间大小。Redis采取的策略是把那些很少访问,而且占用内存又比较大的对象交换到磁盘中,但是第二个因素所占的权重更低,所以在公式中取log值。因为交换大对象时,需要占用更多的I/O和CPU资源

 

对象在SWAP文件中如何存储-->

SWAP文件中采用rdb文件的存储格式。SWAP文件被分割成固定数量的页,每页占用指定数量的字节空间。在redis.conf中根据自己业务需求配置以下两个参数:

vm-page-size:设置每页的大小,默认值为32

vm-pages:设置能够使用的页数,默认值为134217728

Redis在内存中保存一个bitmap以映射这些页是否被占用,每bit代表对应磁盘空间的页是否被使用。内存中保存这样一份映射表极大增强了Redis性能,同时,对内存的使用又非常少

 

开启VM的后台操作-->

Redis默认持久化方式是开启一个子进程创建rdb文件。Redis调用系统的fork函数创建一个子进程,这样得到当前在内存中数据库的一个完全一致的拷贝,因为fork函数复制了当前进程的整个编程内存空间(Copy On Write)

当VM开启时,value可能被交换出内存,并不是在内存中保存所有数据。子进程在执行保存时,与父进程共享同一个SWAP文件,因为:

有命令需要请求交换出内存的数据时,父进程需要把这些对象换回到内存中;子进程需要访问SWAP文件获得完整数据集

为了避免两个进程访问同一个SWAP文件,当有后台子进程在做快照保存时,父进程不允许把内存中的对象交换到SWAP文件

Redis正在进行后台内存快照或者后台重写aof时,不能VM交换

 

交换过程

1.交换对象至SWAP文件

计算保存这个对象需要占用SWAP文件中的多少页

在SWAP文件中寻找一段连续页空间保存这个对象

把对象写入SWAP文件

2.从SWAP文件中加载对象

 

posted @ 2020-08-17 00:50  LinBupt  阅读(241)  评论(0编辑  收藏  举报