热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

[Memcached]SlabAllocation的MC项占用空间分析及实践

引子从SlabAllocation原理知道,当MC选择一个Slabclass的Chunk存放item数据,必须计算item的空间大小以选择合适的Slabclass。按照很多人理解,

引子

从Slab Allocation原理知道,当MC选择一个Slab class的Chunk存放item数据,必须计算item的空间大小以选择合适的Slab class。按照很多人理解,item是不是只包含缓存对象的value?假设不是,那如何精确计算item的空间大小呢?从这个问题延伸,Chunk是不是只存放缓存对象的value?

源码分析

先看图1的item结构体,包含item、key、suffix、data等内容,注意key/data存放的数据不只是我们认为的key/value,下面将从源码层面计算item的长度。

《[Memcached] Slab Allocation的MC项占用空间分析及实践》 图1 item结构体

摘录函数item_make_header()计算item长度的代码如下:

sizeof(item) + nkey + *nsuffix + nbytes;//计算总大小

从下面一行代码,可知nkey = key.length + 1。

size_t ntotal = item_make_header(nkey + 1, flags, nbytes, suffix, &nsuffix);

从函数do_item_alloc()函数注释知nbytes是要存储的value长度+2,因为在value的结尾处还要加上”\r\n”,即 nbytes = value.length + 2。
从下面一行代码,可知nsuffix后缀长度为:

*nsuffix = (uint8_t) snprintf(suffix, 40, " %d %d\r\n", flags, nbytes - 2);

所以ntotal=sizeof(item)+key.length+1+(” %d %d\r\n”, flags, nbytes – 2).length+value.lenght+2,其中32位机器item结构是32字节,64位机器item结构是48字节。
从下面一行代码,如果开启CAS功能,ntotal += sizeof(uint64_t),uint64_t是8字节。

if (settings.use_cas) {//开启了CAS功能
ntotal += sizeof(uint64_t);
}

static size_t item_make_header(const uint8_t nkey, const int flags, const int nbytes,
char *suffix, uint8_t *nsuffix) {
/* suffix is defined at 40 chars elsewhere.. */
*nsuffix = (uint8_t) snprintf(suffix, 40, " %d %d\r\n", flags, nbytes - 2);
return sizeof(item) + nkey + *nsuffix + nbytes;//计算总大小
}
//key、flags、exptime三个参数是用户在使用set、add命令存储一条数据时输入的参数。
//nkey是key字符串的长度。nbytes则是用户要存储的data长度+2,因为在data的结尾处还要加上"\r\n"
//cur_hv则是根据键值key计算得到的哈希值。
item *do_item_alloc(char *key, const size_t nkey, const int flags,
const rel_time_t exptime, const int nbytes,
const uint32_t cur_hv) {
uint8_t nsuffix;
item *it = NULL;
char suffix[40];
//要存储这个item需要的总空间。要注意第一个参数是nkey+1,所以上面的那些宏计算时
//使用了(item)->nkey + 1
size_t ntotal = item_make_header(nkey + 1, flags, nbytes, suffix, &nsuffix);
if (settings.use_cas) {//开启了CAS功能
ntotal += sizeof(uint64_t);
}
//根据大小判断从属于哪个slab
unsigned int id = slabs_clsid(ntotal);
if (id == 0)//0表示不属于任何一个slab
return 0;
...
it = slabs_alloc(ntotal, id);//从slab分配器中申请内存
it->refcount = 1;
it->it_flags = settings.use_cas ? ITEM_CAS : 0;
it->nkey = nkey;
it->nbytes = nbytes;
memcpy(ITEM_key(it), key, nkey);//这里只拷贝nkey个字节,最后一个字节空着
it->exptime = exptime;
memcpy(ITEM_suffix(it), suffix, (size_t)nsuffix);
it->nsuffix = nsuffix;
return it;
}

实践出真知

图2查询key=emp4900001的value字节长度,key占用10字节,value占用93字节。从上面的公式计算item.length = 48 + 8 + 10 + 1 + (” 1 93\r\n”).length + 93 + 2 = 169 Bytes。

《[Memcached] Slab Allocation的MC项占用空间分析及实践》 图2 查询key的value的字节长度

通过图3的mem_requested和used_chunks计算item.length=59066176/349504=169 Bytes,证明从源码分析item长度正确。

《[Memcached] Slab Allocation的MC项占用空间分析及实践》 图 3 stats slabs命令结果


推荐阅读
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文介绍了一种在PHP中对二维数组根据某个字段进行排序的方法,以年龄字段为例,按照倒序的方式进行排序,并给出了具体的代码实现。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 电话号码的字母组合解题思路和代码示例
    本文介绍了力扣题目《电话号码的字母组合》的解题思路和代码示例。通过使用哈希表和递归求解的方法,可以将给定的电话号码转换为对应的字母组合。详细的解题思路和代码示例可以帮助读者更好地理解和实现该题目。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了如何清除Eclipse中SVN用户的设置。首先需要查看使用的SVN接口,然后根据接口类型找到相应的目录并删除相关文件。最后使用SVN更新或提交来应用更改。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • 云原生边缘计算之KubeEdge简介及功能特点
    本文介绍了云原生边缘计算中的KubeEdge系统,该系统是一个开源系统,用于将容器化应用程序编排功能扩展到Edge的主机。它基于Kubernetes构建,并为网络应用程序提供基础架构支持。同时,KubeEdge具有离线模式、基于Kubernetes的节点、群集、应用程序和设备管理、资源优化等特点。此外,KubeEdge还支持跨平台工作,在私有、公共和混合云中都可以运行。同时,KubeEdge还提供数据管理和数据分析管道引擎的支持。最后,本文还介绍了KubeEdge系统生成证书的方法。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
author-avatar
mobiledu2502857427
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有