设为首页 收藏本站
查看: 1616|回复: 0

[经验分享] Redis VM使用

[复制链接]

尚未签到

发表于 2015-7-21 11:42:42 | 显示全部楼层 |阅读模式
  Redis处理的速度很快,因为它是基于内存的。在内存能够足够容纳数据的时候,所有的数据都存放在内存。这个时候不论是读取数据还是写入数据都是非常快的。但是如果数据量很大,大到内存已经无法全部容纳的时候,我想对存储有一定了解的人都在想,这个时候redis是怎么处理的呢?处理速度是否会直线下降?
  幸亏,答案是否定的。Redis使用到了VM,在redis.conf设置vm-enabled yes 即开启VM功能。 通过VM功能可以实现冷热数据分离。使热数据仍在内存中,冷数据保存到磁盘。这样就可以避免因为内存不足而造成访问速度下降的问题。在这里,需要特别提到的是,Redis并没有使用OS提供的Swap,而是自己实现。作者在自己的blog说明了原因:
  1:OS是基于page(4K)来做的,它的粒度对于Redis来说太大。而redis的大多数对象都远小于4k,所以一个OS页面上可能有多个redis对象。另外redis的集合对象类型如list,set可能存在与多个OS页面上。最终可能造成只有10%的key被经常访问,但是所有OS页面都会被OS认为是活跃的,这样只有内存真正耗尽时OS才会交换页面。
  2:相比于OS的交换方式。redis可以将被交换到磁盘的对象进行压缩,保存到磁盘的对象可以去除指针和对象元数据信息。一般压缩后对象会比内存中对象小10倍。这样redis的vm会比OS vm能少做很多io操作。
  3:OS交换的时候,是会阻塞线程的,而Redis可以设置让工作线程来完成,主线程仍可以继续接收client的请求。
  开启VM功能后,还有其他几个设置需要设置vm-swap-file:设置被交换出的值保存到磁盘的位置。vm-max-memory:设置当内存消耗达到上限时开始将value交换出来。vm-page-size:设置单个页面的大小,单位是字节。vm-pages:设置最多能交换保存多少个页到磁盘。可以算出可以交换出来的最大大小为vm-page-size * vm-pages。vm-max-threads:设置完成交换动作的工作线程数,设置为0表示不使用工作线程而使用主线程,这会以阻塞的方式来运行。建议设置成CPU核个数。
  Redis为了保证查找的速度,只会将value交换出去,而在内存中保留所有的Key。所以它非常适合Key很小,Value很大的存储结构。如果Key很大,value很小,那么vm可能还是无法满足需求。redis规定同一个页面只能保存一个对象。但是一个对象可以保存在多个页面中。在redis使用的内存没超过vm-max-memory之前是不会交换任何value的。当超过最大内存限制后,redis会选择较老的对象。如果两个对象一样老会优先交换比较大的对象,将它从内存中移除,这样会更加节约内存。精确的公式swappability = age*log(size_in_memory)。
  既然对于Redis来说,一个页面只会保存一个对象,也就是一个Value值,所以应该将vm-page-size设置成大多数value可以保存进去。如果设置太小,一个value对象就会占用几个页面,如果设置太大,就会造成页面空闲空间浪费。每个页面,Redis都会在内存中使用1比特(bit)长度来保存页面的空闲状态。如果设置的vm-pages非常大,那么光用来保存页面状态就会花费很大的内存。
  VM的工作机制:分为两种
  第一种:vm-max-threads = 0
  换出
  主线程定期检查使用的内存大小,如果发现内存超出最大上限,会直接以阻塞的方式,将选中的对象保存到换出文件中,并释放对象占用的内存,此过程会一直重复直到下面条件满足:
  1.内存使用降到最大限制以下,2. 设置的交换文件数量达到上限,3. 几乎全部的对象都被交换到磁盘了
  换入
  当有client请求的value之前已被换出时,主线程会以阻塞的方式从换出文件中加载对应的value对象,加载时此时会阻塞所有client,然后再处理client的请求。
  第二种:vm-max-threads > 0
  换出
  当主线程检测到使用内存超过最大上限,会将选中的要交换的对象信息放到一个队列中交由工作线程后台处理,主线程会继续处理client请求。
     换入
  如果有client请求value之前已被换出时,主线程先阻塞当个client,然后将加载对象的信息放到一个队列中,让工作线程去加载,此进主线程继续处理其他client请求。加载完毕后工作线程通知主线程。主线程再执行被阻塞的client的命令。这种方式只阻塞单个client。
  
  
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-89042-1-1.html 上篇帖子: redis key和value数据类型 下篇帖子: Redis 一款服务器数据结构服务器(多用于内存数据库) Junit 测试 Code Speech
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表