谈谈mongo driver的连接池

enjolras1205

前言

对服务器来说, 在单条链接到达吞吐上限之前. 更少的链接意味着更少的上下文切换, 更少的内存消耗(tcp协议栈内存消耗, 应用层的buffer). 所以, 在常规的索引, 分片, 读写分离之外, 连接池的设计, 对数据库性能也有很重要的影响.
我们使用的语言没有官方driver, 连接池的实现采用了固定大小. 在节点不多的情况下问题不大, 当节点数量越来越多时, 问题变得不容忽视. 于是, 参考一下官方driver的实现.

mongo offical driver

offical drivers

c driver

source

https://github.com/mongodb/mo...
commit c99f53b9bcdf5b3756f6c70d8148fbb86015b6f4

document

http://mongoc.org/libmongoc/current/connection-pooling.html
c driver 有 single mode / pooled mode, 显然, 调用线程和链接不会是一对一的关系. 更推荐使用 pooled mode.
参考连接池选项
http://mongoc.org/libmongoc/current/mongoc_uri_t.html#connection-pool-options
c driver废弃了min_pool_size, 从 mongoc-client-pool.c:333 代码中可以看到

void
mongoc_client_pool_push (mongoc_client_pool_t *pool, mongoc_client_t *client)
{
   ENTRY;

   BSON_ASSERT (pool);
   BSON_ASSERT (client);

   bson_mutex_lock (&pool->mutex);
   _mongoc_queue_push_head (&pool->queue, client);

   if (pool->min_pool_size &&
       _mongoc_queue_get_length (&pool->queue) > pool->min_pool_size) {
      mongoc_client_t *old_client;
      old_client = (mongoc_client_t *) _mongoc_queue_pop_tail (&pool->queue);
      if (old_client) {
         mongoc_client_destroy (old_client);
         pool->size--;
      }
   }

   mongoc_cond_signal (&pool->cond);
   bson_mutex_unlock (&pool->mutex);

   EXIT;
}

min_pool_size实际含义是, max_pool_size决定了最大链接数, min_pool_size决定了同时维持的最小链接数. 显然, 这个在较大的工作负载时, 会导致频繁的链接创建, 断开, 反而让性能下降. 故不推荐使用.

c++ driver

source

https://github.com/mongodb/mo...
commit dfe361bf672809beba0f6164fafad9b088d55fef

document

http://mongocxx.org/mongocxx-v3/connection-pools/
可以看到minPoolSize 的默认值是0, 既然创建链接的时间足够短, 用时再创建是很合理的.

maxPoolSizeThe maximum number of clients created by a mongocxx::pool (both in the pool and checked out). The default value is 100. Once it is reached, mongocxx::pool::acquire blocks until another thread returns a client to the pool.
minPoolSizeSets a target size for the pool when idle. Once this many clients have been created, there will never be fewer than this many clients in the pool. If additional clients above minPoolSize are created, they will be destroyed when returned to the pool. The default value is “0”, which disables this feature. When disabled, clients are never destroyed.

没发现c++有实现空闲断开. 注意c++ driver重用了c driver的连接池代码, 只是用智能指针做了RAII. 所以关于min_pool_size可以参考c driver的文档.

java driver

source

https://github.com/mongodb/mo...
6d20b9128bd6966b31c23f7aab681c056aaefc72

document

https://mongodb.github.io/mongo-java-driver/3.4/javadoc/com/mongodb/MongoClientOptions.html
java driver写得很罗嗦. 从api来看, 连接池选项相对较丰富:

  1. 没有minPoolSize只有maxPoolSize
  2. 有idle time设计.
  3. MaxConnectionLifeTime SocketTimeout, HeartbeatFrequency等.

elixir DBCollection

https://hexdocs.pm/db_connection/DBConnection.html
elixir的db连接池为固定大小. 不可用.

总结

  • 建议使用共享式的连接池.
  • 通过踢掉空闲链接, 尽量减少链接数量. 不使用时, pool size可以是0.
阅读 199

41 声望
3 粉丝
0 条评论
41 声望
3 粉丝
宣传栏