天天看点

Redis实战(13)虚拟内存

首先说明下redis 的虚拟内存与操作系统的虚拟内存不是一码事,但是思路和目的都是相同

的。就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的内存空间用于其他

需要访问的数据。尤其是对于redis 这样的内存数据库,内存总是不够用的。除了可以将数

据分割到多个redis server 外。另外的能够提高数据库容量的办法就是使用虚拟内存把那些

不经常访问的数据交换的磁盘上。如果我们的存储的数据总是有少部分数据被经常访问,大

部分数据很少被访问,对于网站来说确实总是只有少量用户经常活跃。当少量数据被经常访

问时,使用虚拟内存不但能提高单台redis server 数据库的容量,而且也不会对性能造成太

多影响。

redis 没有使用操作系统提供的虚拟内存机制而是自己在实现了自己的虚拟内存机制,主要

的理由有两点:

1、操作系统的虚拟内存是已4k 页面为最小单位进行交换的。而redis 的大多数对象都远小

于4k,所以一个操作系统页面上可能有多个redis 对象。另外redis 的集合对象类型如list,set

可能存在与多个操作系统页面上。最终可能造成只有10%key 被经常访问,但是所有操作系

统页面都会被操作系统认为是活跃的,这样只有内存真正耗尽时操作系统才会交换页面。

2、相比于操作系统的交换方式,redis 可以将被交换到磁盘的对象进行压缩,保存到磁盘的对

象可以去除指针和对象元数据信息,一般压缩后的对象会比内存中的对象小10 倍,这样redis

的虚拟内存会比操作系统虚拟内存能少做很多io 操作。

#下面是vm 相关配置
vm-enabled yes #开启vm 功能
vm-swap-file /tmp/redis.swap #交换出来的value 保存的文件路径
vm-max-memory 1000000 #redis 使用的最大内存上限
vm-page-size 32 #每个页面的大小32 个字节
vm-pages 134217728 #最多使用多少页面
vm-max-threads 4 #用于执行value 对象换入换出的工作线程数量      

redis 的虚拟内存在设计上为了保证key 的查找速度,只会将value 交换到swap 文件中。所

以如果是内存问题是由于太多value 很小的key 造成的,那么虚拟内存并不能解决,和操作

系统一样redis 也是按页面来交换对象的。redis 规定同一个页面只能保存一个对象。但是一

个对象可以保存在多个页面中。在redis 使用的内存没超过vm-max-memory 之前是不会交换

任何value 的。当超过最大内存限制后,redis 会选择较过期的对象。如果两个对象一样过期

会优先交换比较大的对象,精确的公式swappability = age*log(size_in_memory)。对于

vm-page-size 的设置应该根据自己的应用将页面的大小设置为可以容纳大多数对象的大小,

太大了会浪费磁盘空间,太小了会造成交换文件出现碎片。对于交换文件中的每个页面,redis

会在内存中对应一个1bit 值来记录页面的空闲状态。所以像上面配置中页面数量(vm-pages

134217728 )会占用16M 内存用来记录页面空闲状态。vm-max-threads 表示用做交换任务的

线程数量。如果大于0 推荐设为服务器的cpu 内核的数量,如果是0 则交换过程在主线程进行。

继续阅读