memcached学习之slabs部分

slabs部分的功能介绍

slabs部分是memcached的数据仓库,主要是负责memcached的内存空间的分配,提取以及释放,同时,实际上对这部分的操作是缓存系统的核心,整体上memcached的大部分代码都是围绕这部分来进行的,包括slabs_maintanance_thread,LRU算法,item的增删改查等等。在这里,我并不打算介绍其他部分,是因为后面会有单独章节来介绍item的行为,以及最最关键的LRU算法。另外有一点需要说明,整个系列都没有介绍slabs的maintanance的线程,这里面的功能主要是针对memcached的一个极端情况来处理的,那就是可能出现某个slabclass占据的内存从来没有数据来存储,而有些slabclass却一直分配不到内存空间,这时候需要将没有数据存储的slabclass内存转移给分配不到内存空间的slabclass,这部分由于时间问题,暂时不涉及。

slabs部分的整体逻辑

内部存储结构图

这里写图片描述

slabs部分操作介绍

slabs部分和assoc部分有点不同,对于memcached申请的内存来说,不再是增删改查的操作了,因为对于内存来说,只有使用和释放这种说法,不过这里的释放仅仅是说将该item对应的内存原来数据给清空,然后放到空闲列表中去,而不是真正地释放掉,这部分内存仍然是要被memcached保持和使用的,因此主要的操作实际上只有两个,分别是slabs_new和slabs_free操作。

slabs部分的代码分解

自定义类型

typedef struct {
    //chunk_size, 单个数据块的大小
    unsigned int size;      /* sizes of items */
    //单个slab中包含的item数量,其实也就是chunk的数目
    unsigned int perslab;   /* how many items per slab */
    //item指针的数组
    void *slots;           /* list of item ptrs */
    //当前空闲的item数目
    unsigned int sl_curr;   /* total free items in list */
    //当前层包含slab的数量
    unsigned int slabs;     /* how many slabs were allocated for this class */
    //slab的指针数组
    void **slab_list;       /* array of slab pointers */
    //slab的指针数组的大小
    unsigned int list_size; /* size of prev array */
    //当前请求的内存大小
    size_t requested; /* The number of requested bytes */
} slabclass_t;

变量分解

1、全局静态变量slabclass,上述slabclass_t的一个数组,也是memcached的数据仓库中心;
2、整型mem_limit, 设定的memcached使用的内存限制大小;
3、整型mem_malloced,已分配的内存大小;
4、布尔类型mem_limit_reached,默认是false, 这是一个信号,用于当内存限制大小被突破时启动LRU的maintenance线程;
5、整型power_largest,实际使用到的slabclass的最大层级;
6、指针mem_base,分配内存的基地址;
7、指针mem_current, 分配内存当前使用的地址;
8、整型mem_avail,当前分配内存的剩余可用大小;
9、互斥锁slabs_lock,用于进入分配slab的互斥锁;

代码分解

1、slabs_init函数,确定slabclass中每层chunk的大小,初始化slabclass每层的配置,并根据参数确定是否预分配内存;

void slabs_init(const size_t limit, const double factor, const bool prealloc) {
    int i = POWER_SMALLEST - 1;    //初始化的起始层,默认是0
    unsigned int size = sizeof(item) + settings.chunk_size;    //获取最小层中配置的chunk的大小,为item结构体大小和chunk_size之和

    mem_limit = limit;   //设置内存限制

    if (prealloc) {      //如果预分配
        /* Allocate everything in a big chunk with malloc */
        mem_base = malloc(mem_limit);    //一次性开辟mem_limit内存
        if (mem_base != NULL) {
            mem_current = mem_base;      //尚未有数据存储,mem_current等于mem_base
            mem_avail = mem_limit;       //尚未有数据存储,可用空间即为设置的内存大小
        } 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值