Memcached全面剖析–2.理解memcached的内存存储
下面是《memcached全面剖析》的第二部分。 发表日:2008/7/9 作者:前坂徹(Toru Maesaka) http://gihyo.jp/dev/feature/01/memcached/0002 我是mixi株式会社研究开发组的前坂徹。上次的文章介绍了memcached是分布式的高速缓存服务器。 本次将介绍memcached的
下面是《memcached全面剖析》的第二部分。
发表日:2008/7/9
作者:前坂徹(Toru Maesaka)
http://gihyo.jp/dev/feature/01/memcached/0002
我是mixi株式会社研究开发组的前坂徹。 上次的文章介绍了memcached是分布式的高速缓存服务器。 本次将介绍memcached的内部构造的实现方式,以及内存的管理方式。 另外,memcached的内部构造导致的弱点也将加以说明。
Slab Allocation机制:整理内存以便重复使用
最近的memcached默认情况下采用了名为Slab Allocator的机制分配、管理内存。 在该机制出现以前,内存的分配是通过对所有记录简单地进行malloc和free来进行的。 但是,这种方式会导致内存碎片,加重操作系统内存管理器的负担,最坏的情况下, 会导致操作系统比memcached进程本身还慢。Slab Allocator就是为解决该问题而诞生的。
下面来看看Slab Allocator的原理。下面是memcached文档中的slab allocator的目标:
the primary goal of the slabs subsystem in memcached was to eliminate memory fragmentation issues totally by using fixed-size memory chunks coming from a few predetermined size classes.
也就是说,Slab Allocator的基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块, 以完全解决内存碎片问题。
Slab Allocation的原理相当简单。 将分配的内存分割成各种尺寸的块(chunk), 并把尺寸相同的块分成组(chunk的集合)(图1)。
图1 Slab Allocation的构造图
而且,slab allocator还有重复使用已分配的内存的目的。 也就是说,分配到的内存不会释放,而是重复利用。
Slab Allocation的主要术语
Page
分配给Slab的内存空间,默认是1MB。分配给Slab之后根据slab的大小切分成chunk。
Chunk
用于缓存记录的内存空间。
Slab Class
特定大小的chunk的组。
在Slab中缓存记录的原理
下面说明memcached如何针对客户端发送的数据选择slab并缓存到chunk中。
memcached根据收到的数据的大小,选择最适合数据大小的slab(图2)。 memcached中保存着slab内空闲chunk的列表,根据该列表选择chunk, 然后将数据缓存于其中。
图2 选择存储记录的组的方法
实际上,Slab Allocator也是有利也有弊。下面介绍一下它的缺点。
Slab Allocator的缺点
Slab Allocator解决了当初的内存碎片问题,但新的机制也给memcached带来了新的问题。
这个问题就是,由于分配的是特定长度的内存,因此无法有效利用分配的内存。 例如,将100字节的数据缓存到128字节的chunk中,剩余的28字节就浪费了(图3)。
图3 chunk空间的使用
对于该问题目前还没有完美的解决方案,但在文档中记载了比较有效的解决方案。
The most efficient way to reduce the waste is to use a list of size classes that closely matches (if that's at all possible) common sizes of objects that the clients of this particular installation of memcached are likely to store.
就是说,如果预先知道客户端发送的数据的公用大小,或者仅缓存大小相同的数据的情况下, 只要使用适合数据大小的组的列表,就可以减少浪费。
但是很遗憾,现在还不能进行任何调优,只能期待以后的版本了。 但是,我们可以调节slab class的大小的差别。 接下来说明growth factor选项。
使用Growth Factor进行调优
memcached在启动时指定 Growth Factor因子(通过-f选项), 就可以在某种程度上控制slab之间的差异。默认值为1.25。 但是,在该选项出现之前,这个因子曾经固定为2,称为“powers of 2”策略。
让我们用以前的设置,以verbose模式启动memcached试试看:
$ memcached -f 2 -vv
下面是启动后的verbose输出:
slab class 1: chunk size 128 perslab 8192<br>slab class 2: chunk size 256 perslab 4096<br>slab class 3: chunk size 512 perslab 2048<br>slab class 4: chunk size 1024 perslab 1024<br>slab class 5: chunk size 2048 perslab 512<br>slab class 6: chunk size 4096 perslab 256<br>slab class 7: chunk size 8192 perslab 128<br>slab class 8: chunk size 16384 perslab 64<br>slab class 9: chunk size 32768 perslab 32<br>slab class 10: chunk size 65536 perslab 16<br>slab class 11: chunk size 131072 perslab 8<br>slab class 12: chunk size 262144 perslab 4<br>slab class 13: chunk size 524288 perslab 2
可见,从128字节的组开始,组的大小依次增大为原来的2倍。 这样设置的问题是,slab之间的差别比较大,有些情况下就相当浪费内存。 因此,为尽量减少内存浪费,两年前追加了growth factor这个选项。
来看看现在的默认设置(f=1.25)时的输出(篇幅所限,这里只写到第10组):
slab class 1: chunk size 88 perslab 11915<br>slab class 2: chunk size 112 perslab 9362<br>slab class 3: chunk size 144 perslab 7281<br>slab class 4: chunk size 184 perslab 5698<br>slab class 5: chunk size 232 perslab 4519<br>slab class 6: chunk size 296 perslab 3542<br>slab class 7: chunk size 376 perslab 2788<br>slab class 8: chunk size 472 perslab 2221<br>slab class 9: chunk size 592 perslab 1771<br>slab class 10: chunk size 744 perslab 1409
可见,组间差距比因子为2时小得多,更适合缓存几百字节的记录。 从上面的输出结果来看,可能会觉得有些计算误差, 这些误差是为了保持字节数的对齐而故意设置的。
将memcached引入产品,或是直接使用默认值进行部署时, 最好是重新计算一下数据的预期平均长度,调整growth factor, 以获得最恰当的设置。内存是珍贵的资源,浪费就太可惜了。
接下来介绍一下如何使用memcached的stats命令查看slabs的利用率等各种各样的信息。
查看memcached的内部状态
memcached有个名为stats的命令,使用它可以获得各种各样的信息。 执行命令的方法很多,用telnet最为简单:
$ telnet 主机名 端口号
连接到memcached之后,输入stats再按回车,即可获得包括资源利用率在内的各种信息。 此外,输入"stats slabs"或"stats items"还可以获得关于缓存记录的信息。 结束程序请输入quit。
这些命令的详细信息可以参考memcached软件包内的protocol.txt文档。
$ telnet localhost 11211<br>Trying ::1...<br>Connected to localhost.<br>Escape character is '^]'.<br>stats<br>STAT pid 481<br>STAT uptime 16574<br>STAT time 1213687612<br>STAT version 1.2.5<br>STAT pointer_size 32<br>STAT rusage_user 0.102297<br>STAT rusage_system 0.214317<br>STAT curr_items 0<br>STAT total_items 0<br>STAT bytes 0<br>STAT curr_connections 6<br>STAT total_connections 8<br>STAT connection_structures 7<br>STAT cmd_get 0<br>STAT cmd_set 0<br>STAT get_hits 0<br>STAT get_misses 0<br>STAT evictions 0<br>STAT bytes_read 20<br>STAT bytes_written 465<br>STAT limit_maxbytes 67108864<br>STAT threads 4<br>END<br>quit
另外,如果安装了libmemcached这个面向C/C++语言的客户端库,就会安装 memstat 这个命令。 使用方法很简单,可以用更少的步骤获得与telnet相同的信息,还能一次性从多台服务器获得信息。
$ memstat --servers=server1,server2,server3,...
libmemcached可以从下面的地址获得:
- http://tangent.org/552/libmemcached.html
查看slabs的使用状况
使用memcached的创造着Brad写的名为memcached-tool的Perl脚本,可以方便地获得slab的使用情况 (它将memcached的返回值整理成容易阅读的格式)。可以从下面的地址获得脚本:
- http://code.sixapart.com/svn/memcached/trunk/server/scripts/memcached-tool
使用方法也极其简单:
$ memcached-tool 主机名:端口 选项
查看slabs使用状况时无需指定选项,因此用下面的命令即可:
$ memcached-tool 主机名:端口
获得的信息如下所示:
# Item_Size Max_age 1MB_pages Count Full?<br> 1 104 B 1394292 s 1215 12249628 yes<br> 2 136 B 1456795 s 52 400919 yes<br> 3 176 B 1339587 s 33 196567 yes<br> 4 224 B 1360926 s 109 510221 yes<br> 5 280 B 1570071 s 49 183452 yes<br> 6 352 B 1592051 s 77 229197 yes<br> 7 440 B 1517732 s 66 157183 yes<br> 8 552 B 1460821 s 62 117697 yes<br> 9 696 B 1521917 s 143 215308 yes<br>10 872 B 1695035 s 205 246162 yes<br>11 1.1 kB 1681650 s 233 221968 yes<br>12 1.3 kB 1603363 s 241 183621 yes<br>13 1.7 kB 1634218 s 94 57197 yes<br>14 2.1 kB 1695038 s 75 36488 yes<br>15 2.6 kB 1747075 s 65 25203 yes<br>16 3.3 kB 1760661 s 78 24167 yes
各列的含义为:
列 | 含义 |
# | slab class编号 |
Item_Size | Chunk大小 |
Max_age | LRU内最旧的记录的生存时间 |
1MB_pages | 分配给Slab的页数 |
Count | Slab内的记录数 |
Full? | Slab内是否含有空闲chunk |
从这个脚本获得的信息对于调优非常方便,强烈推荐使用。
内存存储的总结
本次简单说明了memcached的缓存机制和调优方法。 希望读者能理解memcached的内存管理原理及其优缺点。
下次将继续说明LRU和Expire等原理,以及memcached的最新发展方向—— 可扩充体系(pluggable architecher))。
原文:http://kb.cnblogs.com/page/42732/;

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

Memcached是一种常用的缓存技术,它可以使Web应用程序的性能得到很大的提升。在PHP中,常用的Session处理方式是将Session文件存放在服务器的硬盘上。但是,这种方式并不是最优的,因为服务器的硬盘会成为性能瓶颈之一。而使用Memcached缓存技术可以对PHP中的Session处理进行优化,提高Web应用程序的性能。PHP中的Session处

随着互联网的发展,PHP应用程序在互联网应用领域中变得越来越常见。但是,PHP应用程序的高并发访问会导致服务器的CPU使用率高,从而影响应用程序的性能。为了优化PHP应用程序的性能,Memcached缓存技术成为了一种很好的选择。本文将介绍如何使用Memcached缓存技术优化PHP应用程序CPU的使用率。Memcached缓存技术简介Memcached是一

随着互联网的快速发展,大规模MySQL数据库备份和恢复成为各大企业和网站必备的技能之一。而随着Memcached的广泛应用,如何备份和恢复Memcached也成为了一个重要的问题。PHP作为Web开发的主力语言之一,在处理备份和恢复MySQL和Memcached上拥有独特的优势和技巧。本文将详细介绍PHP处理MySQL和Memcached备份与恢复的实现方法

近日,努比亚Z70Ultra在IMEI数据库中现身,型号为NX731J。该手机搭载了新一代屏下摄像头技术,将成为全球首款搭载骁龙8Gen4处理器的真全面屏旗舰手机,该手机最大的亮点是采用了1.5K分辨率的屏下摄像头方案,这是目前行业内分辨率最高的UDC(屏下摄像头)技术。此前努比亚已量产第六代屏下摄像技术(屏幕分辨率为2480×1116,介于FHD和1.5K分辨率之间),而Z70Ultra的屏幕分辨率提升至1.5K,实现了无刘海、无挖孔的真全面屏设计。1.Z70Ultra搭载一英寸超大底主摄传感

随着互联网的发展,MySQL作为一种开源的关系型数据库管理系统,在各类应用中都有广泛应用。其中一个重要的安全问题就是MySQL用户密码的加密和存储。那么,MySQL密码加密的方法都有哪些呢?本文将为大家深入剖析。MySQL密码的存储方式在了解MySQL密码加密方法之前,先来了解一下MySQL密码的存储方式。MySQL在版本5.7以前,采用的是单向哈希算法(S

随着现代互联网应用的快速发展,用户体验对于一个应用的成功至关重要。如何保证应用的高性能和高可用性,成为了开发人员需要解决的重要问题之一。PHP作为一种广泛应用的编程语言之一,它的性能监控和优化也是非常重要的。Memcached是一个高性能、分布式的内存对象缓存系统,可以帮助应用提高性能和扩展性。本文将介绍如何使用PHP和Memcached实现性能监控的方法。

深入剖析pip协议的意义,需要具体代码示例引言:在Python的世界里,pip(即pipinstall)是我们安装和管理第三方库的首选方式。它是Python包管理工具,以其简洁高效、易用便捷的特点,在开发过程中得到了广泛的应用。本文将深入剖析pip协议的意义,通过具体的代码示例,展示pip的重要作用和使用方法,帮助读者更好地理解和运用pip。一、pip协议

随着网络应用的不断增加和数据量的不断膨胀,数据的读写效率成为影响应用性能的重要因素之一。而缓存技术的应用则可以很好地解决这个问题。在PHP应用中,Memcached是最常用的缓存服务器。Memcached是一个高性能的分布式内存对象缓存系统,可以将常用的数据存储在内存中,提高数据检索的效率。本文将介绍如何使用PHP和Memcached进行缓存管理,以及如何优
