memcached源码阅读

memcached简介:

memcached是一套分布式的快取系统,当初是Danga Interactive为了LiveJournal所发展的,但目前被许多软件(如MediaWiki)所使用。这是一套开放源代码软件,以BSD license授权释出。

 

作者:

 

Anatoly Vorobey <mellon@pobox.com>                                                                                                                          

Brad Fitzpatrick <brad@danga.com>

 

 

源码地址:

http://github.com/memcached/memcached

 


模块分解:

个人感觉memcached的源码可以分为三个部分:

1. 协议,即通信模块,包括如何监听socket,创建连接,解析命令等等;

2. 内存管理,主要负责内存分配,回收

3. 散列管理,负责对存储的内容进行散列,维护散列表

接下来从每个模块来分析memcached的源码:

 

协议模块:

主要代码逻辑位于memcached.c文件中。主要的逻辑就是监听某个端口,发起的连接有多个线程进行处理(round-robin),每个线程处理的连接会去解析socket流中的数据,从中剥离命令类型、数据等等内容。这块主要会用到libevent这个框架进行事件的监听并回调自己定义好的函数。

 

之后就是解析socket流中的数据,这块代码很庞大,但是没有仔细阅读的必要,大体的函数调用顺序如下(以get操作为例):

event_handler --> drive_machine --> try_read_command --> process_command --> process_get_command -->item_get

在取得item数据后写回socket。

 

内存管理:

memcached的内存分配策略会把内存分成一页一页的内容,然后每个页里面会放置很多个slab,而存储单元item就是放入这些slab中,主要的源码文件在slabs.c和item.c。可以先看看slabclass的数据结构:

 

 

slabclass主要用来描述slab的信息,每个slabclass里面有一个slablist的指针数组,用来记录当前已经分配的该大小的slab,还会有个slots的指针数组,用来记录存储的item的列表。

 

item的数据结构:

 

很显然item是一个双向链表的节点,会包括自己的一个时间戳、过期时间以及数据。

 

那么内存是如何进行分配的呢?首先可以看看初始化时候的代码:

 

如果没有设置prealloc的话,memcached会根据用户的配置:页大小、增长因子等等来初始化slabclass,这里只需初始化slabclass,至于如何分配一个slab,再看看这段代码:

 

如果slots中的freelist中有空余内存或者当前页中还有空余内存,直接返回这块内存地址即可,否则就分配一个新的内存页。

 

对于一个set请求,会创建一个新的item,然后根据item的大小,找到一个最小的可以放下item的slab,然后将这个item放入这个slab里面,如果找不到这样的slab,则需要根据LRU策略回收掉一部分的内存。

 

散列管理:

assoc.c主要维护了两个散列表,当一个散列表的item个数超过一定范围后,会用一个线程在后台重建一个新的更大的散列表。主要的代码:

 

扩大散列表的后台线程代码:

 

主要就是将旧的散列表中的item通过新的散列mask重新散列后放入新的散列表中。这种做法是为了保证开散列过程中,一个散列值的链表长度不至于太长,否则会影响性能。

 

总结:

给我印象最为深刻的还是内存管理及散列管理这块,体现了一定的数据结构和算法知识,实现的页非常漂亮。从读代码中还发现了很多自己以前不了解的东西,比如页大小可以设置成很大,但是官方推荐不要超过1M,否则性能会很差。

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值