• twemproxy代理主干流程——剖析twemproxy代码正编


    在twemproxy的发送和接收流程剖析中,我们已经完全弄清楚twemproxy如何将客户端以及服务端发来的包切分成msg,获得一个独立的msg后twemproxy应该如何处理?这是本文这次需要重点介绍的内容。

    twemproxy的主干流程

    图1 twemproxy的主干流程

    如图1所示,twemproxy主要通过3个队列进行模块间的数据交互:客户端连接conn的发送队列conn->omsg_q,服务端连接s_conn的输入队列s_conn->imsg_q,服务端连接s_conn的发送队列s_conn->omsg_q以及conn->omsg_q里的msg的对应回复peer。

    • 客户层接收模块将所有需要回复的msg处理后分别写入到客户端conn连接的发送队列conn->omsg_q以及服务端连接s_conn的输入队列s_conn->imsg_q。
    • 服务层发送模块从服务端连接s_conn的输入队列s_conn->imsg_q取出,将其发送后写入服务端连接s_conn的发送队列s_conn->omsg_q。
    • 服务层接收模块将接到服务端的响应通过s_conn->omsg_q的提供顺序将回复的msg写入到conn->omsg_q里的msg的对应回复peer。
    • 客户层发送模块通过客户端连接conn的发送队列conn->omsg_q的顺序获得请求msg的对应的peer中的回复msg,然后发送个客户端。

    由于twemproxy的队列里的元素是msg对象的指针,同样peer也是msg对象的指针,为此在twemproxy在接到请求直至发送回复的那段时间里没有进行内存拷贝,仅有在接收的时候申请内存。twemproxy通过这种精巧的设计使得内存零拷贝,同时配合空闲msg池的使用,大幅减少了系统申请和释放内存的次数,大幅提高了twemproxy性能,大幅减轻了twemproxycpu的压力。

    twemproxy的客户层接收模块

     

    图2 twemproxy的客户层接收

    如图2,当客户层接收模块接收到客户端请求后:

    • twemproxy会从空闲msg池和系统内存中请求空的msg,通过我们提到过的接收流程接收并解析客户端请求生成msg。
    • 解析后发现如果类型是mset,mget或者del的多key操作,根据key值进行分片操作将一个msg分成多个msg。
    • 将这些msg按顺序放入客户端连接conn的发送队列conn->omsg_q中(其中被分片的msg不放入服务端连接s_conn的输入队列s_conn->imsg_q中)。
    • 根据key值经过哈希建立对应的服务端连接,每个服务端在twemproxy中对应一个key值。
    • 在建立连接后,将msg插入服务端连接s_conn的输入队列s_conn->imsg_q中,并通知服务端层发送模块发送。

     twemproxy的服务层发送模块

     

    图3 twemproxy的服务层发送 

    如图3所示,当服务层接收模块接收到客户层接收模块的通知后:

    • twemproxy从服务端连接s_conn的输入队列s_conn->imsg_q中取出msg。
    • 在相应的s_conn发送msg,从服务端连接s_conn的输入队列s_conn->imsg_q中删除。
    • 发送后,将发送过的msg插入到服务端连接s_conn的发送队列s_conn->omsg_q中。

     twemproxy的服务层接收模块

     

    图4 twemproxy的服务层接收

    如图4所示,当服务层接收模块接收到服务端回复后:

    • twemproxy会从空闲msg池和系统内存中请求空的msg,通过我们提到过的接收流程接收并解析服务端回复生成msg。
    • 从服务端连接s_conn的发送队列s_conn->omsg_q中取出对应的客户端请求pmsg。
    • 查看客户端请求pmsg和客户端msg是否对应,msg可能需要被丢弃(因为在此时客户端连接断开,msg不能被发送),并将丢弃的msg放入空闲msg池中。
    • 将msg写入pmsg->peer中,然后从服务端连接s_conn的发送队列s_conn->omsg_q中删除pmsg。
    • 如果存在分片,那么在所有已经分片的msg收到请求回复后,将这些已经分片的msg并入被分片的msg中。
    • 将所有已经分片的msg置空,并将该消息通知给服务层接收模块。

    twemproxy的客户层发送模块

     

    图5 twemproxy的客户层发送

    如图5所示,当客户层接收模块接收到服务层接收模块的通知后:

    • twemproxy从客户端连接conn的发送队列conn->omsg_q取出msg。
    • 将msg->peek中取出对应的回复pmsg并发送。
    • 从客户端连接conn的发送队列conn->omsg_q删除msg。
    • 将msg释放后放入空闲msg池。

    总结

    twemproxy通过客户端连接conn的发送队列conn->omsg_q,服务端连接s_conn的输入队列s_conn->imsg_q,服务端连接s_conn的发送队列s_conn->omsg_q以及conn->omsg_q里的msg的对应回复peer来完成twemproxy的代理服务,利用队列和peer指针特性实现了内存零拷贝。

  • 相关阅读:
    m113
    无题
    m102 SE赛
    m101 真*sb($huge 全场最瞎$)
    m100 的坑
    m99 然而并没有想出来标题!
    m98 lsc rp-- 赛
    csps2019AFO祭
    csps考前的一些总结(然而可能并没有用)
    低错总结
  • 原文地址:https://www.cnblogs.com/onlyac/p/7079441.html
Copyright © 2020-2023  润新知