lxyfirst

C++博客 首页 新随笔 联系 聚合 管理
  33 Posts :: 3 Stories :: 27 Comments :: 0 Trackbacks
twemproxy(nutcracker)是twitter实现的开源memcached和redis代理,主要功能是根据key分发请求到后端的memcached和redis服务器,简化memcached和redis集群服务的实现。
出于对twemproxy实现机制的好奇,简要阅读了代码,特别是网络处理部分,一般这部分是网络服务器的核心,这里记录下其代码实现逻辑和发现的问题。

twemproxy作为代理服务器,主体逻辑都围绕着数据流转,采用了单线程非阻塞模型,在linux下由epoll驱动整个程序的运行,对于事件驱动模块的封装在event目录下,event_base对象是引擎,conn对象是具体的连接,conn对象中定义一系列事件处理的回调函数,典型的reactor机制,linux下的实现文件是nc_epoll.c 。 
事件引擎模块使用了两层回调机制, event_base上有个基本的回调函数,这个回调函数进一步调用conn对象的相应回调函数  (注:一般直接使用conn的回调也就够了)。
面向客户端的conn回调:
        conn->recv = msg_recv;
        conn->recv_next = req_recv_next;
        conn->recv_done = req_recv_done;
        conn->send = msg_send;
        conn->send_next = rsp_send_next;
        conn->send_done = rsp_send_done;
        conn->close = client_close;
        conn->active = client_active;

        conn->enqueue_outq = req_client_enqueue_omsgq;
        conn->dequeue_outq = req_client_dequeue_omsgq;
面向后端memcached和redis的conn回调:
        conn->recv = msg_recv;
        conn->recv_next = rsp_recv_next;
        conn->recv_done = rsp_recv_done;
        conn->send = msg_send;
        conn->send_next = req_send_next;
        conn->send_done = req_send_done;
        conn->close = server_close;
        conn->active = server_active;
        conn->enqueue_inq = req_server_enqueue_imsgq;
        conn->dequeue_inq = req_server_dequeue_imsgq;
        conn->enqueue_outq = req_server_enqueue_omsgq;
        conn->dequeue_outq = req_server_dequeue_omsgq;
twemproxy面向客户端时,由proxy_accept接收连接,创建客户端conn对象,并将其加入到事件引擎中。
twemproxy面向后端时,由server_pool管理各个到后端的conn对象,同样会加入到事件引擎中。

在请求处理模块有2个主要的概念是 mbuf对象和msg对象,mbuf对象是数据缓冲区,发送和接收的数据都存放在mbuf中, 采用链式管理。msg对象是具体的逻辑请求,采用链式管理,形成请求/响应队列。请求和响应的处理模块分别在nc_request.c和nc_response.c中实现。

客户端连接的处理逻辑:

    core_recv 
        conn->recv        即msg_recv ,read事件处理
            conn->recv_next           即req_recv_next ,获得msg对象,没有则创建
            msg_recv_chain             创建mbuf对象,接收并处理数据
                  [create mbuf]
                  conn_recv       真正的read数据
                  msg_parse      解析 , mbuf->msg
                       msg_parsed   解析完成
                           conn->recv_done   即req_recv_done    
                               req_filter        过滤器,暂无操作
                               req_forward    分发请求
                                   server_pool_conn 根据key获得后端conn对象
                                   将s_conn加入写事件监控,将msg加入转发队列,可写事件被触发后转发队列内请求
                                   s_conn->enqueue_inq req_server_enqueue_imsgq
 
                  conn->recv_next      即req_recv_next,继续下一个

注:从代码实现看回调逻辑的层次性不强,收发数据放入mbuf列表,然后用writev处理,在遇到发送不完时还要拆分mbuf,重新组织iovec,实现上有些复杂。
另外conn对象的数据采用一次读/写完的方式处理,在高压力下可能会产生大量的mbuf对象。

未完待续。
posted on 2014-03-09 13:42 star 阅读(2157) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理