一相关资源
1关于什么是
http://www.danga.com/memcached/
2关于Memcached的使用方法及协议参考:http://blog.csdn.net/heiyeshuwu/archive/2006/11/13/1380838.aspx
3比较全面分析Memcached的参考:
http://www.fulin.org/blog/2007/04/memcached/
二内存模型分析
1基本概念介绍
1)item:存储的最小单位,当每一个Key-Value值通过Memcached存储时,Memcached查找一个空闲的item存入其中.
2)slab:Memcached分配的一个内存块,默认大小为1Mb,里面存储了一定数目的item.
2分配初始化
当启动起Memcached后,程序先根据输入的各种参数进行相应的配置,配置结束后就开始对程序中的各种数据结构进行初始化,其中slabs_init,就是对slabclass的初始化,而slabclass是Memcached内存模型中比较重要的一个数据结构。它被定义成一个slabclass_t数组,大小是201(程序从1开始计数,实际使用200个),主要是对分配的内存进行管理。结构如下:
在这个结构中要注意的是每一个数组成员中size的大小是不一样的,在默认情况下是按factor^n(默认为2)在赋值,如第一个数组成员是1byte,则第二个为2byte,第三个为4……….,当大小为slab大小的一半时,停止赋值,并在停止赋值的下一个数组成员内,将大小设置成默认大小1Mb,此时这个 slab中只有一个item,大小为1Mb.代码如下:
在memcached中还支持预分配,就是说当你指定好要分配的大小时,如果启动预分配,Memcached将会把这些空间一下全部分配给你,避免以后频繁的分配操作,提高效率,默认情况下是开启这项功能的。程序如下:
当系统将预分配的内存分配好,slabclass_t初步设置之后,会将已经分配的内存的一部分以slab的形式预先与一部分slabclass_t数组的成员联系在一起(设置size大小的). 这项功能主要是由slabs_preallocate提供。
在 slabs_preallocate中通过一个遍历,对所有设置size大小的slabclass_t成员调用do_slabs_newslab,而在 do_slabs_newslab中完成内存分配的是memory_allocate函数。完成后在对slabclass_t相应成员进行设置:
在这里还要注意的是,在do_slabs_newslab中还调用了一个函数grow_slab_list,这个函数是给slabclass_t成员分配更多的slab指针数组,以便于以后分配更多的slab,默认开始的时候是16,但当出现slab不够用的时候以2倍的数目增长。程序如下:
此时就完成了slabclass_t的初始化,内存模型为:
3关于item
item是数据最终要存入的数据结构,它的大体结构如下(还有一些成员,全面了解可查看源代码):
自己一开始对item与hash表以及在slab中的存储方式有些疑惑,后来看到这个结构的时候明白了。
在 item中有一个next和prev,它们组成了一个双向链表,是存储在slab结构中的,而还有一个h_next指针,这个是用来指向在同一个hash 表项中其它的数据,当要检索数据的时候,通过hash函数找到hash项,然后通过h_next遍历这个链查询数据。在slab的储存中则使用item的大小来定位到底存储在哪一个大小的slab中,找到slabclass_t数组序号后,可以通过它指向最后一项的指针效率很高的将这个新的item插入其中,然后在通过hash值建立与hash表的联系,这样整个Memcached的内存模型就建立起来了。
我这里的图形工具不太好用(主要自己不太会),这个图就不画了,不过网上有一个可以借鉴一下:
当时看这个图的时候就是对hash表的item1与存储在slab中的item1有点困惑,其实它们都是一项,在图中item1,item2,item3是有着相同的hash值通过h_next连接在一起,而item1与item4是两个存储在同一个slab的相邻item项,其实它们是双向连接的,图中没有画出。
后记:
这是自己第一次写这样的技术性文章,而且代码也是草草看得,可能有很多地方存在疏漏甚至错误,所以还请大家谅解,有什么需要交流的地方随时联系我,很希望和喜好技术的朋友分享知识。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chinalinuxzend/archive/2009/03/10/3978222.aspx