【问题标题】:In PyMongo, The default value of MongoClient's maxPoolSize=100 has no effect?PyMongo中,MongoClient的maxPoolSize=100的默认值没有影响?
【发布时间】:2018-03-24 14:34:50
【问题描述】:

下面是 PyMongo 连接的简单测试 sn-p:

from pymongo import MongoClient

clients = [] 
for i in range(0,1000):
    con = MongoClient('mongodb://localhost:27017/')
    clients.append(con)
    print(i)

这是输出:

... ... 998 999

这是 MongoDB 控制台中的输出:

2018-03-24T20:00:55.746+0530 I NETWORK [listener] 连接 公认 从 127.0.0.1:51272 #1500 (现在打开 1000 个连接) 2018-03-24T20:00:55.747+0530 I NETWORK [conn1500] 收到客户端 元数据来自 127.0.0.1:51272 conn: { driver: { name: "PyMongo", 版本:“3.6.1”},操作系统:{类型:“达尔文”,名称:“达尔文”, 架构:“x86_64”,版本:“10.10.1”},平台:“CPython 3.6.0.final.0" } 2018-03-24T20:00:55.773+0530 I NETWORK [conn1486] 结束连接 127.0.0.1:51286(现在打开 999 个连接) 2018-03-24T20:00:55.773+0530 I NETWORK [conn1485] 结束连接 127.0.0.1:51285(现在打开 998 个连接)2018-03-24T20:00:55.773+0530 I NETWORK [conn1484] 结束连接 127.0.0.1:51284(现在打开 997 个连接) . . . . . .

我看到 MongoClient 有一个关键字参数maxPoolSize。它的默认值只有 100。

但是上面的代码是如何工作的呢?

【问题讨论】:

    标签: python mongodb pymongo


    【解决方案1】:

    MongoClient 有一个关键字参数 maxPoolSize。它的默认值只有 100。

    没错。 PyMongo(自 v3.6 起)MongoClient 中 maxPoolSize 的默认值为 100。但是,maxPoolSize 参数控制 MongoClient 实例的每个 MongoDB 服务器的最大内置连接池。

    您的示例 sn-p 创建了 1000 个 MongoClient 实例。请注意,每个进程只需要一个 MongoClient,并在所有操作中重复使用它。为每个请求创建一个新客户端是一个常见的错误,效率非常低。

    但是上面的代码是如何工作的呢?

    如果你想检查限制是否有效,你可以利用Python threading module创建线程来测试MongoClient连接的限制。

    您可以使用其他两个参数:

    • waitQueueMultiple:此参数设置在从池中获取连接之前可以在队列中等待的线程数的限制。通过设置低 maxPoolSize 和低 waitQueueMultiple 您的代码将收到 ExceededMaxWaiters 异常。

    • waitQueueTimeoutMS:此参数设置线程在从池中获取连接之前应在队列中等待多长时间。通过设置低 maxPoolSize 和低 waitQueueTimeoutMS 您的代码将收到 ConnectionFailure 异常。

    例子:

    def worker(num, db): 
        print("Thread number %s" % num)
        try:
            print(db.test.insert({"a":num, "b":num*2}))
        except Exception as e: 
            print("Exception: %s" % e)
        return 
    
    client = MongoClient("mongodb://localhost:27017/", 
                         maxPoolSize=1, 
                         waitQueueTimeoutMS=1, 
                         waitQueueMultiple=1)
    database = client.test
    threads = []
    
    for i in range(100): 
        t = threading.Thread(target=worker, args=(i, database))
        threads.append(t) 
        # Start thread.
        t.start()
    
    # Wait for all threads to complete. 
    for t in threads: 
        t.join() 
    

    有关详细信息,请参阅How does connection pooling work in PyMongo?。请使用提供的默认值,除非您有需要更改上述值的特定用例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-16
      • 2019-07-13
      • 2020-01-14
      • 2013-07-25
      • 2014-12-21
      • 1970-01-01
      • 1970-01-01
      • 2020-12-04
      相关资源
      最近更新 更多