Mongodb 源码分析--链接池(ConnPool)

    在之前的 一篇文章 中,介绍了mongos的balaner的 执行流程,其中在源码中的Balancer::run()方法里简单说明了为了连接到configserver,balancer通过构造 ScopedDbConnection实现来链接并执行相应操作,因为当时篇幅所限,只是该链接使用池化的方式一带而过,今天就专门介绍一下 mongodb中使用池化方式来管理链接对象以提升链接效率的原理。
    
    好了,开始今天的正文吧!

    首先看一下balancer类的run()方法,相关代码如下:   
   

    上面方法中从ScopedDbConnection声明到该实现执行done()方法结束,系统会从链接池中获取一个链接对象,如无链接则直接创建。如 果是创建的链接,则会将该链接添加到池中。下面我们就看一下其类图:
 

    图中的红框所圈的类均为connpool.h头文件中所包含定义的类信息,而这些类中(比如ScopedDbConnection,上面代码提到过)会 包含一个DBClientBase属性指针,而DBClientBase的定义位于dbclient.h头文件中,其主要是定义了客户端连接到 mongodb服务端时所经常进行的操作(CRUD等)。

    图中的类比较多,主要的几个包括:

    ScopedDbConnection: 池中的数据库链接类,其通过持有的DBClientBase指出针来施加crud操作
    DBConnectionPool:数据库链接池 类,定义链接的创建,获取,flush,以及维护等操作。
    PoolForHost:该对象提供以栈式(stack)方式管理pool链接 对象。

    
    下面就先看一下ScopedDbConnection的构造方法,其执行流程如下:

  



    其中的_host( shard.getConnString() )只是将要链接的mongo服务地址绑定到ScopedDbConnection的_host属性上。重要的是_conn( pool.get(_host))这一行代码,它会从池中(pool类型为DBConnectionPool)获取一个链接,如池中没有则会创建一个链接 并返回,如下(详情见注释):

 



    上面方法中_get( url.toString() ) 这一行代码主要是用于执行从池中获取对象的操作,它的实现代码如下:




    其中_pools类型定义如下,用于实现从“服务器名称”到“相应链接池”的映射,因为不同的服务器会对应不同的链接池:



    
    找到了相应的链接池之后,返回该池所对应的PoolForHost对象的引用,该对象提供以栈式(stack)方式管理pool链接对象。其get() 方法定义如下:




    现在我们再将注意力放回到主流程DBClientBase* DBConnectionPool::get(const ConnectionString& url)方法的下面一行代码,即:




    该方法一个hook方法的调用,它的实现方式有些复杂,很像设置模式中的Observer (观察者)模式,我们先看一下该模式的类图:

   

    有关该模式的具体讲解可以参见相关资料或在google上搜一下,这里暂不做解释了。
    
    这里我们先看一下该方法的具体实现(onCreate与onHandedOut方式类似,这里仅对onHandedOut进行说明):



    可以看出,它进而面使用了for的方式,依次对conn进行onHandedOut()方法处理,而_hooks的定义如下:




    看到这里,我们有必要了解一下_hooks是如何添加相关hook对象的。还记得我在这篇文章 中介绍在mongos的main()中有如下代码 吗?

 


    
    对了,就是上面的addHook()方法,添加了对shardingConnectionHook的引用,而 shardingConnectionHook则是对shard链接hook的具体实现,如下:

 


    
    当然这里不是对addShard及相应command命令进行分析的时候,因为mongodb有一个架构设计非常清晰的指令(command)体系,有 关该方面内容我也会专门接时间来加以说明。

    还是回到程序主流程上,在onHandedOut处理完之后,就可以将获取到的链接实例返回了。但如果没有可能的链接信息,那么就要创建一个链接 (cs.connect( errmsg ))并将其入库,如下:

   



    在完成了这一步,链接池的就会多一个connect对象,并使用该对象来链接configServer. 而当balancer执行并相应均衡chunk操作后,会执行如下代码:

  



    下面就是done()函数代码:

 


    好了,今天的内容就先到这里了。按照惯例,最后用一张时序图来对今天的流程做一下回顾。
 


    原文链接:http://www.cnblogs.com/daizhj/archive/2011/06/07/mongos_connpool_source_code.html
    作者: daizhj, 代震军   
    微博: http://t.sina.com.cn/daizhj
    Tags: mongodb,c++,connpoll,connection,source code

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页