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

简单理解memcached的内存分配

在写完《使用Memcached实现抽奖活动》这篇文章后,发现自己虽然很早就使用过Memcached,但已经很久没有关注它的进展了,所以就全面看了下它的官方Wiki,打算写几篇文章去

在写完《使用Memcached实现抽奖活动》这篇文章后,发现自己虽然很早就使用过 Memcached,但已经很久没有关注它的进展了,所以就全面看了下它的官方 Wiki,打算写几篇文章去理解它,今天就简单聊聊它的内存分配。

Memcached 所有的操作都是在内存中进行的,这也是它高性能和延迟低的原因之一,如果使用 malloc() 机制动态的分配内存,会产生很多的内存碎片,所以 Memcached 是自己管理内存的,在启动的时候就开启了一大块内存,然后根据规则进行分配使用,这种机制也称为 Slab allocation。

在启动的时候可以通过 -m 参数分配内存,这些内存都用于存储 item,Memcached 自身还需要一些内存(比如 Hash 表,网络连接),所以实际上 Memcached 使用的所有内存是超过 -m 参数分配的内存。

现在简单理解下 Slab allocation,在 Memcached 中,内存首先被分配给一个个 pages,每个 page 默认大小都是 1MB,假设 -m 启动参数是 64 M(后面都以 64 M 说明),那么系统就存在 64 个 page。

每个 page 被指定为 slab-class,slab-class 相当于每个 page 的属性,未被指定 slab-class 的 page 就是未分配的内存。

slab-class 决定了每个 page 存储 item 的大小,称之为 chunk,chunnk 就是用来存储 item 的,在同一个 page 中,所有的 chunk 大小是一致的。

不同的 slab-class 其 chunk 大小是不一致的,基本上是递增关系,默认是 1.25 比例的增长方式。

为了理解 page,slab-class,chunk 的关系,可以运行下列命令:

$ memcached -vv
slab class 1: chunk size 96 perslab 10922
slab class 2: chunk size 120 perslab 8738
slab class 3: chunk size 152 perslab 6898
slab class 4: chunk size 192 perslab 5461
slab class 5: chunk size 240 perslab 4369
slab class 6: chunk size 304 perslab 3449
slab class 7: chunk size 384 perslab 2730
slab class 8: chunk size 480 perslab 2184
slab class 9: chunk size 600 perslab 1747
...

slab class 1 其 chunk 大小是 96 字节,那么对应的 page 最多可以存储 10922 个 chunk。slab class 2 根据 slab class 1 * 1.25 的公示,chunk 大小是 120 个字节,对应的 page 最多可以存储 8738 个 chunk,依次类推。

需要注意的是:

  • 假设 -m 是 64 M,不代表 64 个 page 全部被分配了,因为如果存储的 item 很少,很多 page 是未分配的。
  • 不同的 page,其 slab-class 可能是一样的,比如所有的 item 都小于 80 字节,一旦第一个 page 存储满了,那么 Memcached 启用第二个 page 的时候,其仍然被指定为 slab-class 2。
  • 如果有个 item 是 1M,那么这个 slab-class 只能存储 1 个 chunk。

每个 slab-class 都是独立的,有独立的 LRU 算法(后面介绍),统计数据也是独立的。

如果想了解下 slab-class 的使用情况,可以输入以下命令:

$ stats slabs
STAT 1:chunk_size 96
STAT 1:chunks_per_page 10922
STAT 1:total_pages 1
STAT 1:total_chunks 10922
STAT 1:used_chunks 109
STAT 1:free_chunks 10813
STAT 1:get_hits 36
STAT 1:cmd_set 109
STAT 2:chunk_size 120
STAT 2:chunks_per_page 17476
STAT 2:total_pages 2
STAT 2:total_chunks 17476

可以看出目前 Memcached 分配了 3 个 page,对应 slab-class1 和 slab-class2。第一个 page 用了 109 个 chunk,gets 请求有 36 个,很可惜没有 gets_miss 的统计数据,无法统计 slab-class 的命中率。

如果想了解 item 的详细使用情况,可以输入下列命令:

$ stats items
STAT items:1:number 108
STAT items:1:number_hot 20
STAT items:1:number_warm 0
STAT items:1:number_cold 88
STAT items:1:age_hot 251
STAT items:1:age_warm 0
STAT items:1:age 67139
STAT items:1:evicted 0
STAT items:1:evicted_nonzero 0

其中涉及了很多 LRU 的统计数据,以及命中率数据,这个后续会讲。

那么 chunk size 如果等于 96 个字节(slab-class1),代表可以存储 96 个字节的 item?并不是,每个 item 包含固定数据结构大小、item 的 key,item 对应的 data,如果要了解每个 item 数据结构的大小,可以下载 Memcached 源文件,然后进入根目录,输入如下命令:

$ ./sizes
Settings 248
Item (no cas) 48
Item (cas) 56

如果 Memcached 要支持 CAS 操作(如果不了解 CAS,参考《使用Memcached实现抽奖活动》),每个 item 的数据结构是 56 字节,也就是对于 slab-class1 来说,实际可以存储的 item 是 40 个字节,slab-class2 可以存储的 item 是 64 个字节。

如果存储的 item(包含数据结构)是 80 字节,那么存储在 slab-class1,但浪费了 16 个字节,如果存储的 item 是 140 个字节,只能存储在 slab-class2 中,浪费的字节更多,这就是它的内存分配规则。

如果对你存储的 item 大小比较了解(比如大部分处于 60-140个字节之间),为了节省内存,可以调整 slab-class 的递增因子,启动的时候输入下列命令:

$ memcached -f 1.1

推荐阅读
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • GreenDAO快速入门
    前言之前在自己做项目的时候,用到了GreenDAO数据库,其实对于数据库辅助工具库从OrmLite,到litePal再到GreenDAO,总是在不停的切换,但是没有真正去了解他们的 ... [详细]
  • 本文介绍了Python语言程序设计中文件和数据格式化的操作,包括使用np.savetext保存文本文件,对文本文件和二进制文件进行统一的操作步骤,以及使用Numpy模块进行数据可视化编程的指南。同时还提供了一些关于Python的测试题。 ... [详细]
  • 本文介绍了Windows Vista操作系统中的用户账户保护功能,该功能是为了增强系统的安全性而设计的。通过对Vista测试版的体验,可以看到系统在安全性方面的进步。该功能的引入,为用户的账户安全提供了更好的保障。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了源码分析--ConcurrentHashMap与HashTable(JDK1.8)相关的知识,希望对你有一定的参考价值。  Concu ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • Hibernate延迟加载深入分析-集合属性的延迟加载策略
    本文深入分析了Hibernate延迟加载的机制,特别是集合属性的延迟加载策略。通过延迟加载,可以降低系统的内存开销,提高Hibernate的运行性能。对于集合属性,推荐使用延迟加载策略,即在系统需要使用集合属性时才从数据库装载关联的数据,避免一次加载所有集合属性导致性能下降。 ... [详细]
  • Ihaveaworkfolderdirectory.我有一个工作文件夹目录。holderDir.glob(*)>holder[ProjectOne, ... [详细]
  • VSCode快速查看函数定义和代码追踪方法详解
    本文详细介绍了在VSCode中快速查看函数定义和代码追踪的方法,包括跳转到定义位置的三种方式和返回跳转前的位置的快捷键。同时,还介绍了代码追踪插件的使用以及对符号跳转的不足之处。文章指出,直接跳转到定义和实现的位置对于程序员来说非常重要,但需要语言本身的支持。以TypeScript为例,按下F12即可跳转到函数的定义处。 ... [详细]
  • springboot启动不了_Spring Boot + MyBatis 多模块搭建教程
    作者:枫本非凡来源:www.cnblogs.comorzlinp9717399.html一、前言1、创建父工程最近公司项目准备开始重构,框 ... [详细]
  • 本文介绍了一种求解最小权匹配问题的方法,使用了拆点和KM算法。通过将机器拆成多个点,表示加工的顺序,然后使用KM算法求解最小权匹配,得到最优解。文章给出了具体的代码实现,并提供了一篇题解作为参考。 ... [详细]
  • 1Lock与ReadWriteLock1.1LockpublicinterfaceLock{voidlock();voidlockInterruptibl ... [详细]
  • 本文介绍了如何使用MATLAB调用摄像头进行人脸检测和识别。首先需要安装扩展工具,并下载安装OS Generic Video Interface。然后使用MATLAB的机器视觉工具箱中的VJ算法进行人脸检测,可以直接调用CascadeObjectDetector函数进行检测。同时还介绍了如何调用摄像头进行人脸识别,并对每一帧图像进行识别。最后,给出了一些相关的参考资料和实例。 ... [详细]
  • Mono为何能跨平台
    概念JIT编译(JITcompilation),运行时需要代码时,将Microsoft中间语言(MSIL)转换为机器码的编译。CLR(CommonLa ... [详细]
author-avatar
曾经沧海难为水文杰59552066
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有