zoukankan      html  css  js  c++  java
  • Memcached的LRU和缓存命中率

    缓存命中率

    命中:直接从缓存中读取到想要的数据。
    未中:缓存中没有想要的数据,还需要到数据库进行一次查询才能读取到想要的数据。
    命中率越高,数据库查询的次数就越少。
    读取缓存的速度远比数据库查询的速度高得多。
    所以命中率越高,性能越高。

    LRU

    Memcached使用的是LRU(Least Recently Used最近最少使用)算法来回收缓存,将那些属于LRU的数据移出内存,从而腾出空间来加载另外的数据。

    Memcached的内存分配原理

    memcached.jpg

    上图涉及了slab_class、slab、page、chunk四个概念,它们之间的关系是:

    • MemCache将内存空间分为一组slab
    • 每个slab下又有若干个page,每个page默认是1M,如果一个slab占用100M内存的话,那么这个slab下应该有100个page
    • 每个page里面包含一组chunk,chunk是真正存放数据的地方,同一个slab里面的chunk的大小是固定的
    • 有相同大小chunk的slab被组织在一起,称为slab_class

    MemCache内存分配的方式称为allocator,slab的数量是有限的,几个、十几个或者几十个,这个和启动参数的配置相关。
    MemCache中的value存放的地方是由value的大小决定的,value总是会被存放到与chunk大小最接近的一个slab中,比如slab1的chunk大小为80字节、slab[2]的chunk大小为100字节、slab[3]的chunk大小为128字节(相邻slab内的chunk基本以1.25为比例进行增长,MemCache启动时可以用-f指定这个比例),那么过来一个88字节的value,这个value将被放到2号slab中。放slab的时候,首先slab要申请内存,申请内存是以page为单位的,所以在放入第一个数据的时候,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk数组,最后从这个chunk数组中选择一个用于存储数据。

    如果这个slab中没有chunk可以分配了怎么办,如果MemCache启动没有追加-M(禁止LRU,这种情况下内存不够会报Out Of Memory错误),那么MemCache会把这个slab中最近最少使用的chunk中的数据清理掉,然后放上最新的数据。

    针对MemCache的内存分配及回收算法,总结三点:

    1. MemCache的内存分配chunk里面会有内存浪费,88字节的value分配在128字节(紧接着大的用)的chunk中,就损失了30字节,但是这也避免了管理内存碎片的问题
    2. MemCache的LRU算法不是针对全局的,是针对slab的
    3. 应该可以理解为什么MemCache存放的value大小是限制的,因为一个新数据过来,slab会先以page为单位申请一块内存,申请的内存最多就只有1M,所以value大小自然不能大于1M了
  • 相关阅读:
    js中(function(){…})()立即执行函数写法理解
    JS 立即执行的函数表达式(function)写法
    javascript中call,apply,bind的用法对比分析
    C++成员函数指针的应用
    typeid详解
    dynamic_cast
    C++标准转换运算符dynamic_cast
    继承的构造函数
    考虑写一个不抛出异常的swap函数
    布隆过滤器(转)
  • 原文地址:https://www.cnblogs.com/timeismoney/p/7342005.html
Copyright © 2011-2022 走看看