设为首页 收藏本站
查看: 801|回复: 0

[经验分享] Memcached源码分析——连接状态变化分析(drive_machine)

[复制链接]

尚未签到

发表于 2015-9-2 09:01:31 | 显示全部楼层 |阅读模式
这篇文章主要介绍Memcached中,基于libevent构造的主线程和worker线程所处理连接的状态互相转换的过程(不涉数据的存取等操作),也就是drive_machine的主要业务逻辑了。状态转换过程没有涉及所有状态,同时,由于自己能力问题,一些状态转换还可能有错,还请各位前辈指正。转换条件限定:TCP,ASCII协议。(状态不包括conn_swallow,二进制协议才会用到此状态)


1 总揽
  首先介绍连接,连接是Memcached自己定义的连接conn。的所有状态,drive_machine()主要就是对这些状态的转换进行操作:

enum conn_states {
conn_listening,  /**< the socket which listens for connections /主线程等待链接*/
conn_new_cmd,    /**< Prepare connection for next command /worker线程等待命令*/
conn_waiting,    /**< waiting for a readable socket /worker线程等待sdf中有可读信息*/
conn_read,       /**< reading in a command line /worker线程读命令*/
conn_parse_cmd,  /**< try to parse a command from the input buffer /woker线程*/
conn_write,      /**< writing out a simple response /worker线程*/
conn_nread,      /**< reading in a fixed number of bytes /worker线程由于命令没读完,继续读取*/
conn_swallow,    /**< swallowing unnecessary bytes w/o storing /worker线程,ASCII协议不涉及此状态*/
conn_closing,    /**< closing this connection */
conn_mwrite,     /**< writing out many items sequentially /worker线程,响应内容中写出*/
conn_max_state   /**< Max state value (used for assertion) /用于标记conn_states边界,超出说明states有错*/
};
  在Memcached.c的main()中,主线程以及worker线程完成必要初始化,绑定相应libevent事件,随后主线程监听绑定监听相应端口,正式做好循环的准备。下图是总体连接状态的总体转换图。
DSC0000.png

2 接收连接分发给worker线程

  


  • 主线程初始化后,连接便进入conn_listening状态,等待连接。
  • 当有连接连入,主线程通过dispatch_conn_new()向管道写入字符c,将连接分发给某个worker线程,worker线程收到,连接进入conn_new_cmd等待状态。

3 数据读入



  • conn_new_cmd等待新的连接,当连接写入时,如果当前请求过多,可能对其他worker线程造成饥饿,更改事件类型为EV_WRITE,退出。
  • 如果连接不多,且有未读数据,说明上一次有未处理完的命令,进入conn_parse_cmd,以便继续处理命令。
  • 如果连接不多,且是新连接,表明没有未读数据,则连接进入conn_waiting状态等待数据(命令)到来。
  • conn_waiting,线程等待连接中的后续数据,如果有数据会设置当前socket fd为读事件EV_READ,确保后续内容的读入。在conn_read中,调用try_read_network()尝试从socket fd中读东西,如果没有数据则返回conn_waiting,如果有数据则进入conn_parse_cmd,等待处理命令。

4 命令解析



  • 进入conn_parse_cmd后,收到命令,调用try_read_command()对用户命令进行解析,这里分析ASCII协议命令,其中会调用process_command()来处理用户的命令。
  • 根据用户的命令,会调用不同类型的命令。如set,replace等命令对应update_command();incr,decr对应process_arithmetic_command();gets对应process_get_command()等。
  • 如果是更新类型的命令,则还需要读入更新的内容,进入conn_nread状态。
  • 其他类型的命令已经可以等待返回结果了。

5 命令返回



  • 命令执行后会有响应,如果命令只需要反馈一个执行结果,则通过out_string()函数来输出结果,进入conn_write阶段。
  • 如果是get命令,则需要打印get的内容,则进入conn_mwrite阶段。
  • conn_write阶段的case语句没有break,所以正常打印也会进入conn_mwrite。

6 结果输出



  • conn_mwrite会中,会调用transmit()将响应结果进行输出。transmit()检查当前结果的写入状态。
  • 如果数据写完,则改变状态为conn_new_cmd等待新的命令。
  • 如果没有写完,则继续等待,直到写完。

7 小结
  以上就是整个连接状态的转换情况了,分析不到位或者有误的地方还请大家指正。总体来说,感觉Memcached对libevent的应用写的十分标准,后续使用libevent时,也可以从Memcached中学习到很多知识。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-108573-1-1.html 上篇帖子: 布式缓存系统Memcached简介与实践 下篇帖子: 使用Memcached提高.NET应用程序的性能(转)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表