Mongodb 请求处理流程

Mongodb多存储引擎支持机制介绍了Mongodb存储层创建数据库、创建集合、插入文档等数据库操作接口,本文将介绍mongodb处理客户端请求的模型。




Mongod在启动时会调用createServer创建一个PortMessageServer对象,其继承MessageServer和Listener两个类,并依赖MyMessageHandler来处理请求。

class PortMessageServer: public MessageServer, public Listener
{
    public:
    void accepted(boost::shared_ptr psocket, long long connectionId );
    void setupSockets();
    void run();
    private:
    MessageHandler * _handler;
};

PortMessageServer

调用setupSockets为mongod配置的每个地址创建一个socket,并调用bind绑定地址。

调用initAndListen监听所有的地址,调用select等待监听fd上发生连接事件,调用accept系统调用接受新的连接请求,并为每个新连接创建一个线程,该线程执行handleIncomingMsg方法,不断处理该连接上的客户端请求。

handleIncomingMsg

连接建立时,调用MyMessageHander::connected方法,初始化一个新的Client对象,Client对象包含DB操作的上下文。

不断调用recv从连接上读取请求,当读取到一个完整请求时,其将请求反序列化为一个Message对象,并调用MyMessageHandler::process方法处理请求,处理完后给客户端发送应答。

连接断开时,调用MyMessageHander::disconnected方法停止该连接对应的线程,释放Client对象。

MyMessageHandler::process

调用assembleResponse方法,从Message对象里获取请求类型(参考Mongdb协议),根据请求类型进行响应的处理。

如果为请求dbQuery,调用receivedQuery处理
如果为请求dbInsert,调用receivedInsert处理
如果为请求dbUpdate,调用receivedUpdate处理
如果为请求dbDelete,调用receivedDelete处理
……

上述各种请求最终会调用Database类的接口来处理。比如receivedInsert,会先根据Database回去对应的Collection对象,最后调用insertDocument往集合中插入文档。请求处理完后,给客户端发送应答消息。

问题分析

select的使用

mongod调用select时,fdset里只会加入监听fd,而监听的地址通常很少,故不存在效率问题。

thread per client模型

mongod为每个连接创建一个线程,创建时做了一定优化,将栈空间设置为1M,减少了线程的内存开销。当线程太多时,线程切换的开销也会变大,但因为mongdb后端是持久化的存储,切换开销相比IO的开销还是要小得多。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值