上文分析了memcached的autoconf过程以及configure, make过程,可以看到,memcached可执行文件是由memcached-memcached.o以及其他文件连接后编译出来的。其main函数在memcached.c中定义。

找到main,在其函数中可以得到他做了一下几件事情:

  1. 变量声明

  2. settings_init();使用默认值初始化settings

  3. while (-1 != (c = getopt(argc, argv, … 获取传入的变量并做相应的操作。如使用-h调用usage并退出;-m则覆盖settings.maxbytes的值,-p指定端口;及最大的内存使用量;-d则设置daemon模式,并在下方继续处理等等。

  4. if (settings.sasl) 检查settings.sasl是否启用。 当加了-S且系统支持sasl的情况下将启用。 SASL全称Simple Authentication and Security Layer,是一种用来扩充C/S模式验证能力的机制。在Postfix可以利用SASL来判断用户是否有权使用转发服务,或是辨认谁在使用你的服务器。

  5. if (tcp_specified && !udp_specified) 检查端口及协议启动选项,设定settings.udpport, settings.port

  6. if (maxcore != 0) 检查时候使用maxcore,如果是,则做相应的core file设置。 core file 是一种特殊的文件,当程序发生异常退出时,他的整个内存将被镜像到文件中。在debug比较管用。参考 core file

  7. getrlimit(RLIMIT_NOFILE, &rlim) 检查RLIMIT_NOFILE和max_conn, RLIMIT_NOFILE决定了系统能够同时打开的文件(包括网络链接)数量, 默认值是1024。即访问并发数无法超过这个数字。显然,对于负载量稍大的服务器而言,这个值会偏低。memcached可设定max_conn,默认1024, 可通过-c设定。如果设定值超过了RLIMIT_NOFILE,memcached将尝试提升系统的RLIMIT_NOFILE。

  8. if (getuid() == 0 || geteuid() == 0) 权限检查。 memcached不允许使用root运行,如果是root操作,必须通过-u指定其运行用户

  9. if (settings.sasl) 如果开启sasl,则初始化sasl

  10. if (do_daemonize) 如果以daemon模式运行,调用daemonize. 该参数有-d指定。 此时父进程退出,fork一个子进程,并重定向其标准输出,错误输出到/dev/null, 并继续工作。

  11. if (lock_memory) 检查lock_memory。该值由-k设定。 若开启,则将memcached的内存固定在物理内存中,不容许交换到swap中去。(另还需系统支持,可检查config.h中是否有HAVE_MLOCKALL定义)

  12. main_base = event_init(); 初始化event_init

  13. stats_init 初始化状态信息。

  14. assoc_init 初始化hash表。建立64K个void指针

  15. conn_init 初始化连接池。 这里可以看出来,memcached的连接池数freetotal=200. 这是memcached的最大并发。

  16. slabs_init(settings.maxbytes, settings.factor, preallocate); 初始化slab。 这里传入了三个参数,maxbytes是通过-m指定的,memcached的最大内存使用量, 最大不得超过2G. factor是递增因子,可通过-f参数设置。默认是1.25. 最大slab数量为1024 * 1024,最大值可通过-I修改,但不建议超过1024 * 1024。

  17. sigignore(SIGPIPE) 忽略SIGPIPE信号。 在Linux下写socket的程序的时候,如果尝试send到一个disconnected socket上,底层将抛出一个SIGPIPE信号。如果程序没有处理或没有忽略,这个信号将导致程序退出。这不是我们需要的。

  18. thread_init(settings.num_threads, main_base); 初始化线程。线程数量可有-t设定。在这里会建立四个互斥锁, 其中两个锁比较重要: cache_lock将在新分配slab等影响全局结构操作时用到。cache_lock锁在新建立客户连接等时用到。

  19. start_assoc_maintenance_thread() 建立主线程

  20. clock_handler

  21. 根据启动模式,建立socket服务或者tcp/utp服务

  • socket模式 server_socket_unix(settings.socketpath,settings.access)

  • tcp/udp模式 server_sockets(settings.port, tcp_transport, portnumber_file)

drop_privileges();资源释放event_base_loop(main_base, 0);进入event无限循环。程序将不再继续往下一行执行了。除非收到终端结束信号stop_assoc_maintenance_thread(); 关闭主线程remove_pidfile(pid_file); 移除pid文件其他资源释放

再分析一下settings的定义,这可以瞥见影响memcached运行状态的设定。

[c] view plaincopy

  1. /**

  2. * Globally accessible settings as derived from the commandline.

  3. */

  4. struct settings {

  5. size_t maxbytes;  //最大内存, 默认64M,最大2G。通过-m 设定

  6. int maxconns;    //最大连接数,默认1024 通过-c设定

  7. int port;  //tcp 端口号,通过-p 设置

  8. int udpport;   //ucp 端口号,通过-U 设置

  9. char *inter;  //监听IP或SOCKET地址 ,通过-l设定

  10. int verbose; //是否输出debug信息。由-v,-vvv参数设定

  11. rel_time_t oldest_live; /* ignore existing items older than this */ //时间设定,当使用flsuh时,只需要修改本值,当取出的值时间小于本值时,将被忽略。

  12. int evict_to_free;  //当内存存满时,是否淘汰老数据。默认是是。可用-M修改为否。此时内容耗尽时,新插入数据时将返回失败。

  13. char *socketpath;   /* path to unix socket if using local socket */ //socket模式,使用-s设定。

  14. int access;  /* access mask (a la chmod) for unix domain socket */ //socket文件的文件权限,使用-a设定

  15. double factor;          /* chunk size growth factor */  //slab分配增量因子,默认围1.25, 可通过-f设定

  16. int chunk_size;  //给一个key+value+flags 分配的最小字节数。 默认值为48. 可通过-n修改。

  17. int num_threads;        /* number of worker (without dispatcher) libevent threads to run */ //工作线程数。默认围4, 可通过-t设定

  18. char prefix_delimiter;  /* character that marks a key prefix (for stats) */ //状态详情的key前缀

  19. int detail_enabled;     /* nonzero if we're collecting detailed stats */ //开启状态详情记录

  20. int reqs_per_event;     /* Maximum number of io to process on each  io-event. */ //每个event处理的请求数

  21. bool use_cas;  //开启cas,"cas"是一个存储检查操作。用来检查脏数据的存操作。在取出数据后,如果没有其他人修改此数据时,本进程才能够存储数据。默认为开启。这里是新发现的亮点函数<a href="http://php.net/manual/en/memcached.cas.php" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; vertical-align: baseline; outline-style: none; outline-width: initial; outline-color: initial; font-size: 14px; background-p_w_picpath: initial; background-p_w_upload: initial; background-origin: initial; background-clip: initial; background-color: transparent; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; border-width: initial; border-color: initial; text-decoration: none; cursor: pointer; color: rgb(4, 100, 141); background-position: initial initial; background-repeat: initial initial; ">php使用参考: memcached_cas</a>

  22. enum protocol binding_protocol;  //使用协议, 试过-B参数设定。 可能值为:ascii, binary, or auto

  23. int backlog;

  24. int item_size_max;        /* Maximum item size, and upper end for slabs */ //单个item最大字计数。默认1M。可通过-I参数修改。纠正一个过期的观点,这个值实际上可以大于1M,必须小于128M。但nencached会抛出警告,大于1M将导致整体运行内存的增加和内存性能的降低。

  25. bool sasl;              /* SASL on/off */   //是否开启sasl

  26. };

本文代码基于memcache 1.4.5_14_gaf48b10 版本分析

memcached.c 源码分析的更多相关文章

  1. memcached学习笔记——存储命令源码分析下篇

    上一篇回顾:<memcached学习笔记——存储命令源码分析上篇>通过分析memcached的存储命令源码的过程,了解了memcached如何解析文本命令和mencached的内存管理机制 ...

  2. memcached学习笔记——存储命令源码分析上篇

    原创文章,转载请标明,谢谢. 上一篇分析过memcached的连接模型,了解memcached是如何高效处理客户端连接,这一篇分析memcached源码中的process_update_command ...

  3. Memcached源码分析之请求处理(状态机)

    作者:Calix 一)上文 在上一篇线程模型的分析中,我们知道,worker线程和主线程都调用了同一个函数,conn_new进行事件监听,并返回conn结构体对象.最终有事件到达时,调用同一个函数ev ...

  4. Memcached源码分析之线程模型

    作者:Calix 一)模型分析 memcached到底是如何处理我们的网络连接的? memcached通过epoll(使用libevent,下面具体再讲)实现异步的服务器,但仍然使用多线程,主要有两种 ...

  5. Memcached源码分析之从SET命令开始说起

    作者:Calix 如果直接把memcached的源码从main函数开始说,恐怕会有点头大,所以这里以一句经典的“SET”命令简单地开个头,算是回忆一下memcached的作用,后面的结构篇中关于命令解 ...

  6. Memcached源码分析

    作者:Calix,转载请注明出处:http://calixwu.com 最近研究了一下memcached的源码,在这里系统总结了一下笔记和理解,写了几 篇源码分析和大家分享,整个系列分为“结构篇”和“ ...

  7. Memcached源码分析之内存管理

    先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到). 一)模型分析在开始解剖memcached关于内存管 ...

  8. memcached源码分析-----item过期失效处理以及LRU爬虫

    memcached源码分析-----item过期失效处理以及LRU爬虫,memcached-----item 转载请注明出处:http://blog.csdn.net/luotuo44/article ...

  9. HashMap实现原理及源码分析

    哈希表(hash table)也叫散列表,是一种非常重要的数据结构,应用场景及其丰富,许多缓存技术(比如memcached)的核心其实就是在内存中维护一张大的哈希表,而HashMap的实现原理也常常出 ...

随机推荐

  1. Java8新特性——lambda表达式.(案例:词频统计)

    需求:读入一个文本文件,确定所有单词的使用频率并从高到低排序,打印出所有单词及其频率的排序列表 先用传统方法解: package cn._1.wordfrequency; import java.ut ...

  2. 如何正确选择挑选适合的VPS服务器

    就来讲讲,如何挑选适合你的VPS.基本过程就是:1.你使用VPS的用途:2.你需要的线路:3.你要选择的操作系统:4.你购买VPS的大概预算是多少. 一.用途方法,其实买VPS就是:建站.VPN使用. ...

  3. asp.net core 2.2 生产环境直接更新View页面并立即生效

    有的时候我们会直接在生产环境上更新页面文件,比如更改了JS代码,CSS代码或页面的文案,布局等.这种没有改到后台代码的情况一般就是直接发布页面文件了,在asp.net core 2.2以前的版本(没有 ...

  4. Linux文件查看及重定向

    Linux文件查看及重定向   实验目标: 通过本实验掌握head.tail.cat.more.less等文件查看命令的使用,理解重定向的概念,掌握两种重定向方法的使用. 实验步骤: 1.通过head ...

  5. [apue] 多进程管道读写的一些疑问

    对于一对一的pipe: 1) 写进程关闭写管道后,读进程继续读管道会导致read返回0: 2) 读进程关闭读管道后,写进程继续写管道会激发SIGPIPE信号,若捕获,则write返回-1: 而对于多对 ...

  6. Effective Java - 静态方法与构造器

    目录 用静态工厂方法替代构造器? 静态工厂有名称 静态工厂不必重新创建一个对象 静态工厂可以返回任何子类型对象 静态工厂返回的类可以动态变化 静态工厂返回的类可以不存在 静态工厂方法的缺点 静态工厂方 ...

  7. 嗨,你真的懂this吗?

    this关键字是JavaScript中最复杂的机制之一,是一个特别的关键字,被自动定义在所有函数的作用域中,但是相信很多JvaScript开发者并不是非常清楚它究竟指向的是什么.听说你很懂this,是 ...

  8. BZOJ 2039人员雇佣

    这道题教会我们一个道理靠谁也不如靠自己. 当时学长已经讲了,然而一脸懵逼,好吧,上网搜题解,二脸懵逼,于是自己动手,丰衣足食.自己推! 首先就是建模了,这道题谁与谁之间建模已经十分明了,超级源点,超级 ...

  9. re模块:模式匹配与正则表达式

    一.用正则表达式查找文本模式 正则表达式,简称regex,是文本模式的描述方法.比如\d是一个正则表达式,用于表示一位0~9的数字.在一个模式后面加上花括号包围的数字n(如{n}),表示匹配这个模式n ...

  10. Python入门基础(9)__面向对象编程_1

    定义一个只包含方法的类 class 类名: def 方法1(self,参数列表): pass def 方法2(self,参数列表): pass 当一个类定义之后,要使用这个类来创键对象.语法如下: 对 ...