五、Memcached深入分析及内存调优
来源:互联网 发布:电脑蓝牙软件下载 编辑:程序博客网 时间:2024/06/05 18:49
到这里memcached的初步使用我们已经没问题了,但是了解一些它内部的机制还是十分必要的,这直接涉及到你能否把memcached给真正“用好”。
Memcached的守护进程机制使用的是Unix下的daemon,Socket则使用了非阻塞(non-blocked)高性能的NIO,事件处理上大家都已经知道了,是基于libevent,支持异步的事件处理。
最主要的是要知道它的内存管理机制,使用如下命令启动memcached:
# /usr/local/memcached/bin/memcached -d -u root -p 11211 -vv
这里我们分配了默认的内存64M的内存给memcached,那么memcached又是怎么样来分配内存的呢?先看下图:
Memcached在分配内存时是以Page为单位的,默认情况下一个Page是1M,内部是一个个chunk,当chunk的大小等于Page大小时也就是Memcached所能存储的最大数据大小了,可以在启动时通过-l来指定它。
Memcached并不是将所有大小的数据都存放在一起的,而是将内存空间划分为一个个的slab,每个slab只负责一定范围内的数据。上图中,slab1只负责96bytes的数据,slab2负责120bytes的数据。
在存储数据时,如果这个item对应的slab还没有创建则申请一个page的内存,将这个page按照所在slab中chunk的大小进行分割,然后将item存入。
如果已经创建存在了,判断对应的slab是否用完,没用完直接存储。
如果对应的slab已经用完了,看内存是否用完,没用完会申请一个新的page进行分割存储,用完了则直接进行LRU。
那么我们怎么样来查看各个slab的状况及里面的chunk大小呢?
在前面的启动参数中我们发现有-v –vv -vvv三个选项,一般我们用的最多的是-vv:
[root@iZ25bep053pZ ~]# /usr/local/memcached/bin/memcached -d -u root -p 11211 -vv[root@iZ25bep053pZ ~]# slab class 1: chunk size 104 perslab 10082slab class 2: chunk size 136 perslab 7710slab class 3: chunk size 176 perslab 5957slab class 4: chunk size 224 perslab 4681slab class 5: chunk size 280 perslab 3744slab class 6: chunk size 352 perslab 2978slab class 7: chunk size 440 perslab 2383slab class 8: chunk size 552 perslab 1899slab class 9: chunk size 696 perslab 1506slab class 10: chunk size 872 perslab 1202slab class 11: chunk size 1096 perslab 956slab class 12: chunk size 1376 perslab 762slab class 13: chunk size 1720 perslab 609slab class 14: chunk size 2152 perslab 487slab class 15: chunk size 2696 perslab 388slab class 16: chunk size 3376 perslab 310slab class 17: chunk size 4224 perslab 248slab class 18: chunk size 5280 perslab 198slab class 19: chunk size 6600 perslab 158slab class 20: chunk size 8256 perslab 127slab class 21: chunk size 10320 perslab 101slab class 22: chunk size 12904 perslab 81slab class 23: chunk size 16136 perslab 64slab class 24: chunk size 20176 perslab 51slab class 25: chunk size 25224 perslab 41slab class 26: chunk size 31536 perslab 33slab class 27: chunk size 39424 perslab 26slab class 28: chunk size 49280 perslab 21slab class 29: chunk size 61600 perslab 17slab class 30: chunk size 77000 perslab 13slab class 31: chunk size 96256 perslab 10slab class 32: chunk size 120320 perslab 8slab class 33: chunk size 150400 perslab 6slab class 34: chunk size 188000 perslab 5slab class 35: chunk size 235000 perslab 4slab class 36: chunk size 293752 perslab 3slab class 37: chunk size 367192 perslab 2slab class 38: chunk size 458992 perslab 2<6 server listening (replication)replication: listen<7 server listening<8 server listening<9 send buffer was 212992, now 268435456<9 server listening (udp)<10 send buffer was 212992, now 268435456<10 server listening (udp)
我们看到,一共有38个slab,第一个slab中chunk大小为104bytes,第二个为136bytes,第三个为176bytes,每个slab中chunk的大小都不一样,这个chunk就是memcached具体存储数据的地方。
Memcached通过指定的成长因子(-f指定,默认1.25倍)来决定每个slab中chunk增长的范围,第一个slab的大小可以通过-n来设定。
当数据进来时Memcached会选择一个大于等于最接近的slab来进行存储。例如当item大小为100时将存储到chunk为104bytes的slab1,item大小为110时则会存储到chunk大小为136的slab2.
这样分配的好处是速度快,避免大量重复的初始化和清理操作,有效的避免了内存碎片的问题,但内存利用率上会有所浪费。典型的拿空间换效率,如图所示:
另外Memcached是懒检测机制,当存储在内存中的对象过期甚至是flush_all时,它并不会做检查或删除操作,只有在get时才检查数据对象是否应该删除。
删除数据时,Memcached同样是懒删除机制,只在对应的数据对象上做删除标识并不回收内存,在下次分配时直接覆盖使用。
了解了Memcached的内存分配机制,如何进行调优是不是自然而然的就明白了?
应该尽量的根据实际情况来设定slab的chunk的初始大小和增长因子,尽量减少内存的浪费。在某些情况下数据的长度都会集中在一个区域,如session。甚至会有定长的情况,如数据统计等。
还有一个重要调优的地方就是提高缓存命中率了,这个没有固定的方法,还得具体场景做具体业务分析,需要注意的就是,Memcached中LRU的操作是基于slab而非全局,分析时最好考虑这一点,这也就是有时候内存还没用完但数据却被回收了的原因。
现在我们再回过头去看Memcached的stats命令,是不是就很有用了?这里贴上常用的一些参数说明。
stats统计项:
STAT pid 22438 memcache服务器的进程ID STAT uptime 2642 服务器已经运行的秒数 STAT time 1488435021 服务器当前的unix时间戳 STAT version 1.2.8 memcache版本 STAT pointer_size 64 当前操作系统的指针大小(32位系统一般是32bit,64就是64位操作系统) STAT rusage_user 0.033049 进程的累计用户时间 STAT rusage_system 0.066099 进程的累计系统时间 STAT curr_items 0 当前存储的数据总数 STAT total_items 0 启动以来存储的数据总数 STAT bytes 0 当前存储占用的字节数 STAT curr_connections 5 当前打开着的连接数 STAT total_connections 8 从服务器启动以后曾经打开过的连接数 STAT connection_structures 6 服务器分配的连接构造数 STAT cmd_flush 0 flush命令请求次数 STAT cmd_get 0 get命令(获取)总请求次数 STAT cmd_set 0 set命令(保存)总请求次数 STAT get_hits 0 总命中次数 STAT get_misses 0 总未命中次数 STAT evictions 0 为获取空闲内存而删除的items数(分配给memcache的空间用满后需要删除旧的items来得到空间分配给新的items) STAT bytes_read 30 总读取字节数(请求字节数) STAT bytes_written 1240 总发送字节数(结果字节数) STAT limit_maxbytes 67108864 分配给memcache的内存大小(字节) STAT threads 2 当前线程数 STAT accepting_conns 1 服务器是否达到过最大连接 STAT listen_disabled_num 0 失效的监听数 STAT replication MASTER STAT repcached_version 2.2 STAT repcached_qi_free 8192 END
stats slabs区块统计:
chunk_size chunk大小,bytechunks_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数free_chunks_end 分完page浪费chunk数mem_requested 请求存储的字节数active_slabs slab数量total_malloced 总内存数量
被浪费内存数=(total_chunks * chunk_size) - mem_requested,如果太大,则需要调整factor
stats items数据项统计:
number 该slab中对象数,不包含过期对象age LRU队列中最老对象的过期时间evicted LRU释放对象数evicted_nonzero 设置了非0时间的LRU释放对象数evicted_time 最后一次LRU秒数,监控频率outofmemory 不能存储对象次数,使用-M会报错tailrepairs 修复slabs次数reclaimed 使用过期对象空间存储对象次数
- 五、Memcached深入分析及内存调优
- memcached源码分析(五):数据保存及内存管理
- 五.memcached内存管理机制
- memcached 内存管理 分析
- Memcached内存池分析
- Memcached内存管理分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached server LRU 深入分析
- memcached 内存管理 分析(转)
- 深入Memcached内部 --- slab内存分配
- 深入Memcached内部----item内存分配
- C++内存分析(五)
- jvm之GC算法
- Servlet文件上传
- (转载)机器学习知识点(十四)EM算法原理
- 11.会话分析-模块介绍
- Ruby 中的BEGIN和begin
- 五、Memcached深入分析及内存调优
- 彩色显示svn diff
- 关于导入项目报错相关问题
- Android音频捕获(录音)
- JDK中的包和他们的基本功能
- 协方差矩阵概念及其计算
- 调试WebService接口的小工具-storm
- FZU 2109 Mountain Number (数位DP)
- python核心数据类型 -- 概览