memcached是一款开源的高性能的缓存服务器,目前已经被广泛的用于互联网产品中,缓存各种数据。在web game的开发中,我们也可以使用memcached来缓存热点数据,通过定期落地机制提高数据的读写性能,防止数据访问成为性能瓶颈。
那么本专题将主要分析一下memcached的源代码。
memcached的源码比较少,只有27个源代码文件。
对于网络IO事件的管理,采用libevent进行连接IO事件的管理。
对于网络连接的管理,是采用状态机来对连接进行管理的。
对于缓存的内存管理,是采用slab内存分配器来进行缓存的内存管理。
在线程管理方面,采用的是多线程的架构。主线程主要负责accept进来的连接,同时负责服务的状态监控和服务的管理。对于accept进来的连接,主线程会轮询工作线程,将连接的信息写入到相应工作线程的new_conn_queue当中,同时写入一个字节通知工作线程处理进来的连接,这个处理方式可以参照libevent对于信号的处理方式。
本章主要分析main()函数,该函数在memcahed.c文件中。其主要处理流程为:
1).sanitycheck()函数: 调用该函数主要检查安装的libevent版本是否满足要求;
2).settings_init()函数: 该函数主要负责读取和初始化配置;
3).处理命令行参数、设置最大的打开文件句柄数;
4).设置组id和uid,同时damonize进程为后台进程;
5).执行各种初始化: 包括event初始化、内存池初始化、监控初始化、连接池初始化和slab初始化等;
6).初始线程线程: thread_init()函数,其中主要初始化主线程和工作线程的struct LIBEVENT_THREAD结构;
7).启动slab管理线程和assoc管理线程;
8).初始化时间相关,并添加主线程的定时器: clock_handler()函数;该函数中会增加一个1s钟的定时器,用于每秒中刷新current_time变量,即代码中使用的当前时间;
9).server_sockets()函数,根据选择的是UDP还是TCP协议,初始化服务器的连接;
10).打开服务器的进程ID文件,并写入当前进程ID,防止单个服务器实例重复打开;
11).调用event_base_loop(),主线程进入主循环,开始事件接受处理;
12).如果event_base_loop()正常退出,则表明服务器正常退出,停止相关的线程,删除PID文件,退出程序;
在上面的main()函数中,我们主要需要关注的是内存、连接、slab相关和线程相关的初始化,将在后续的分析中详细讲解。