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选项。
stats相关命令
stats
stats settings
stats items
stats slabs
stats sizes
stats cachedump 1 100
使用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
slab class 2: chunk size 256 perslab 4096
slab class 3: chunk size 512 perslab 2048
slab class 4: chunk size 1024 perslab 1024
slab class 5: chunk size 2048 perslab 512
slab class 6: chunk size 4096 perslab 256
slab class 7: chunk size 8192 perslab 128
slab class 8: chunk size 16384 perslab 64
slab class 9: chunk size 32768 perslab 32
slab class 10: chunk size 65536 perslab 16
slab class 11: chunk size 131072 perslab 8
slab class 12: chunk size 262144 perslab 4
slab class 13: chunk size 524288 perslab 2
可见,从128字节的组开始,组的大小依次增大为原来的2倍。 这样设置的问题是,slab之间的差别比较大,有些情况下就相当浪费内存。 因此,为尽量减少内存浪费,两年前追加了growth factor这个选项。
memcached提供一系列的命令进行优化的查看,方便我们调整我们的存储策略,查看我们的使用率,内存的使用率以及浪费情况。常用的命令有stats、stats settings、stats items、stats slabs
1.1.1. memcached stats命令
memcached stats命令主要是查询服务器的运行状态和其他内部数据,包含如下这些:
1:pid :服务器进程ID
2:uptime :服务器运行时间,单位秒
3:time:服务器当前的UNIX 时间
4:version :服务器的版本号
5:libevent:libevent的版本
6:pointer_size :服务器操作系统位数
7:rusage_user:该进程累计的用户时间
8:rusage_system:该进程累计的系统时间
9:curr_connections :当前连接数
10:total_connections :服务器启动后总连接数
11:connection_structures :服务器分配的连接结构的数量
12:reserved_fds:内部使用的misc fds 数量
13:cmd_get :获取请求数量
14:get_hits :获取成功的总次数,命中次数
15:get_misses :获取失败的总次数
16:cmd_set :存储请求数量
17:cmd_flush :flush请求的数量
18:cmd_touch:touch请求的数量
19:delete_misses :删除失败次数
20:delete_hits :删除命中
21:incr_misses :递增失败次数
22:incr_hits :递增命中次数
23:decr_misses :递减命中次数
24:decr_hits :递减失败次数
25:cas_misses :Cas 原子设置操作失败次数
26:cas_hits :Cas 命中次数
27:cas_badval :Cas 操作找到key, 但是版本过期,没有设置成功
28:touch_hits:touch命中次数
29:touch_misses:touch失败次数
30:auth_cmds :认证次数(包括成功和失败)
31:auth_errors :认证失败次数
32:bytes :已用缓存空间
33:bytes_read :总共获取的数据量
34:bytes_written :总写入数量数
35:limit_maxbytes :总允许写入的数据量,和分配的内存有关
36:accepting_conns:允许的总连接数
37:listen_disabled_num :监听失败的次数
38:threads:需要的工作线程数
39:hash_bytes:当前使用的Hash table容量大小
40:hash_is_expanding:指定Hash table是否自动增长
41:malloc_fails:malloc内存分配失败的次数
42:curr_items :当前缓存item 数量
43:total_items :从服务启动后,总的存储缓存item 数量
44:evictions :通过删除item 释放内存的次数
这些数据隐含的几个基本关系:
rusage_user、rusage_system:这两个命令可以分析cpu是否过高。
curr_connections 、total_connections :分析连接是否过多
cmd_get 、get_hits 、get_misses :命中率
bytes 、bytes_read 、bytes_written :分析字节数流量
curr_items 、total_items 、evictions :分析对象LRU频率
1:缓存命中率= get_hits/cmd_get * 100%
2:get_misses的数字加上get_hits应该等于cmd_get
stats sizes命令:输出所有Item的大小和个数,注意:会锁定服务,暂停处理请求(建议不要使用)
flush_all命令:使内存中所有的item失效。加入参数则表示在N秒后失效。这个操作并不
会真的释放内存空间,而是标志所有的item为失效
version命令:查看版本
1.1.2. memcached stats settings命令
maxbytes:最大字节数限制,0无限制
maxconns:允许最大连接数
tcpport:TCP端口
udpport:UDP端口
verbosity:日志0=none,1=som,2=lots
oldest:最老对象过期时间
evictions:on/off,是否禁用LRU
domain_socket:socket的domain
umask:创建Socket时的umask
growth_factor:增长因子
chunk_size:key+value+flags大小
num_threads:线程数,可以通过-t设置,默认4
stat_key_prefix:stats分隔符
detail_enabled:yes/no,显示stats细节信息
reqs_per_event:最大IO吞吐量(每event)
cas_enabled:yes/no,是否启用CAS,-C禁用
tcp_backlog:TCP监控日志
auth_enabled_sasl:yes/no,是否启用SASL验证
stats settings 如下图所示:
1.1.3. memcached stats items数据项统计
number:该slab中对象数,不包含过期对象
age:LRU队列中最老对象的过期时间
evicted:LRU释放对象数
evicted_nonzero:设置了非0时间的LRU释放对象数
evicted_time:最后一次LRU秒数,监控频率
outofmemory:不能存储对象次数,使用-M会报错
tailrepairs:修复slabs次数
reclaimed:使用过期对象空间存储对象次数
stats items如下图所示:
1.1.4. stats slabs区块统计
chunk_size:chunk大小,byte
chunks_per_page:每个page的chunk数量
total_pages:page数量
total_chunks:chunk数量*page数量
get_hits:get命中数
cmd_set:set数
delete_hits:delete命中数
incr_hits:incr命中数
decr_hits:decr命中数
cas_hits:cas命中数
cas_badval:cas数据类型错误数
used_chunks:已被分配的chunk数
free_chunks: 过期数据空出的chunk里还没有被使用的chunk数
free_chunks_end:新分配的但是还没有被使用的chunk数
mem_requested:请求存储的字节数
active_slabs:slab数量
total_malloced:总内存数量
被浪费内存数=((total_chunks或者used_chunks) * chunk_size) - mem_requested,如
果太大,需要调整factor
演示:
stats items命令如下:看以参考之前的命令文章看具体的使用。效果如下:
这个命令告诉我们有三个key在这个卡槽里面。
继续输入命令如下:
stats cachedump 1 100
参数的含义:第一个参数1 表示需要查看item的值 我们这里查看的是1,下图第一个标记就是。item的含义我们下一个章节讲解memcached存储原理和方式。
第二个参数表示需要查看多少个key的值,你可以输入你需要查看的具体值,我们这里查询的是100个。
执行效果如下图所示:
参考
memcached实战系列(四)memcached stats命令 memcached优化
相关推荐
### Memcached总结 #### 概述 ##### 1.1 Memcached简介 Memcached是一款高性能的分布式内存对象缓存系统,被广泛应用于减轻数据库负载、提高动态网站响应速度的场景中。通过在内存中缓存数据和对象,Memcached...
memcached 共享内存解决方案,memcached安装,使用
### Memcached学习总结 #### 一、Memcached简介 ##### 1.1 什么是Memcached? Memcached是一款由Danga Interactive公司(LiveJournal的技术团队)所研发的分布式内存对象缓存系统,它最初是为了减轻数据库负载和...
总结,memcached的安装和配置涉及libevent的安装,用于提供事件驱动功能;magent的安装用于管理和监控memcached服务;而memcached自身则负责缓存数据,提升Web应用性能。正确安装和配置这三个组件,可以确保...
总结,Memcached 是一个高效的分布式缓存系统,结合 libevent 可进一步提升性能。在Java环境中,可以使用 Spymemcached 客户端进行交互,通过 Commons Pool 管理连接池,利用 SLF4J 进行日志记录。在实际应用中,...
标题“memcached完全剖析ehcache memcached redis 缓存技术总结”表明,这篇内容将深入探讨三种流行的缓存技术——Memcached、Ehcache和Redis。缓存是IT行业中用于提高系统性能的关键技术,尤其是在大数据量和高并发...
总结来说,这个主题涉及了Windows环境下Memcached的安装、配置和使用,以及与PHP的集成。通过安装和配置Memcached,可以显著提升基于PHP的Web应用程序的性能,减少对数据库的直接访问,提高响应速度。
Memcached 使用点滴总结分享 Memcached 是一种高性能的缓存系统,可以用来存储数据,以减少数据库的查询次数和提高应用程序的性能。本文总结了作者对 Memcached 的使用经验和实践,包括封装 Memcached Java 客户端...
**Memcached:高性能分布式...总结来说,Memcached是一个高效、轻量级的内存缓存解决方案,广泛应用于需要快速数据访问的场景。正确配置和使用memcached.exe和memcached.dll,可以为你的应用程序带来显著的性能提升。
总结,`memcached-1.5.4`是实现高效缓存的关键组件,其源码的阅读与编译有助于深入理解内存缓存的工作原理,优化Web应用性能。通过熟悉`memcached`的配置、运行以及与其他技术的集成,开发者可以更好地利用此工具来...
总结来说,这个组合提供了从服务器端到客户端的完整memcached解决方案,适用于那些希望在PHP项目中使用memcached缓存以提升性能的开发者。然而,由于这些组件都是较老的版本,使用时需要注意可能的安全问题和兼容性...
总结,Memcached 1.5.11版作为一款轻量级的缓存系统,以其高效、易用的特点在众多项目中得到了广泛应用。通过深入理解其工作机制和优化策略,开发者能够更好地利用这一工具提升系统的性能。同时,根据实际业务需求,...
#### 六、总结 通过上述方法,我们可以有效地监控Memcached的运行状态,及时发现问题并进行调整,以保证系统的稳定性和性能。无论是简单的Telnet命令还是更高级的监控工具,都是管理和优化Memcached不可或缺的重要...
总结而言,memcached凭借其高性能、简单协议、易于扩展和部署的特性,成为Web应用中不可或缺的缓存解决方案。理解和掌握memcached的原理与应用对于开发高性能的Web应用至关重要。随着新特性的不断加入,memcached正...
#### 六、总结 Memcached作为一款成熟的缓存解决方案,其源代码分析不仅有助于理解其内部机制,还能启发开发者如何构建高效、可靠的分布式系统。通过对Memcached源代码的深入剖析,我们可以学习到其在内存管理、...
总结来说,从 memcached 迁移到 redis 是为了利用 redis 更强大的功能和更全面的数据管理能力。在迁移过程中,需要注意数据一致性、性能优化以及对现有应用程序的影响。通过合理的规划和测试,可以顺利完成这个转换...
**总结** 在PHP开发中,Memcached是一个强大的工具,能够显著提升Web应用的性能。通过`memcached-client.php`这样的客户端脚本,我们可以轻松地实现与Memcached服务器的通信,利用其高效缓存机制来优化数据库操作。...
**总结** "memcached-win32-bin"是一个32位Windows版的Memcached服务端安装包,提供了在Windows环境中部署和运行Memcached的基础。配合客户端库(如dll文件),可以方便地在各种编程语言中与Memcached服务端进行...