英文:
Concurrent queries to MongoDB using mgo ends in closed sockets
问题
我一直在Stack Overflow上查看一些问题,以及一些人们在mgo golang lib中展示如何管理会话的帖子。
问题是,我看到的所有示例都不能同时运行太多并发查询。增加并发操作的数量会导致套接字关闭。在这里,您可以找到我运行的代码,以重现此行为。
请注意,我只运行了200个并发查询,为每个查询打开一个新的套接字。200并不是一个很大的数字。
我看到的错误是:
read tcp 127.0.0.1:59583->127.0.0.1:27018: read: connection reset by peer
Closed explicitly
我应该如何处理这个问题?我希望保持这个并发级别,甚至在某个时候增加它。
英文:
I have been checking several questions here in stackoverflow + some posts where people exposes examples of of how to manage sessions with mgo golang lib .
The point is that all the examples I've seen doesn't run too much concurrent queries at the same time. Increasing the number of concurrent operations ends in closed sockets. Here you can find the code I ran in order to reproduce this behaviour.
Concurrent queries to MongoDB using mgo ends in closed sockets.
Note that I'm just running 200 of concurrent queries, opening a new socket for each one. 200 is not a big number.
The errors I see are:
read tcp 127.0.0.1:59583->127.0.0.1:27018: read: connection reset by peer
Closed explicitly
How should I deal with this? I want to keep this concurrency level, even increase it at some point.
答案1
得分: 2
结果与不在Docker容器中的Mongo数据库相同,如果我将插入数量增加到5000以上。没有会话副本的插入工作正常,而带有会话副本的插入会出现Mongo错误"显式关闭"。
根据William Kennedy的博客,推荐的方法确实是进行会话副本。否则,操作将与同一套接字中的其他Go例程串行化。
如果你计算打开的MongoDB套接字数量:
while true ; do lsof -i | grep 27017 | wc -l ; sleep 0.5 ; done
你会发现当没有会话副本时,我们只有一个打开的套接字。
当使用会话副本时,套接字的数量可能会增加到很高的数量。
我认为在Mongo或系统中达到了打开套接字的限制。ulimit
可以用来检查shell环境的限制。
请注意,根据设计,mgo不允许对会话数量设置任何限制。这样做的目的是避免在数据库访问方面设置限制,并推动开发人员在代码的入口点引入限制:例如,限制同时处理的HTTP请求的数量。
英文:
The result is the same with a Mongo database which is not in a docker container if I raise the number of insert to more than 5 000.
The inserts with no session copy work ok and the inserts with session copy end up with mongo errors "Closed explicitly".
According to William Kennedy blog, the recommended way is indeed to make session copy. Otherwise, the operations are serialized with other go routines in the same socket.
If you count the number of sockets opened with mongoldb :
while true ; do lsof -i | grep 27017 | wc -l ; sleep 0.5 ; done
you will see that we have one socket open when we have no session copy.
When session copy is used, the number of sockets can raise high number.
I think that an open socket limit is reached in mongo or in the system. ulimit
can be used to check the limits of the shell environment.
Note that, by design, mgo doesn't allow any limit on session number. The idea is avoid having limits on the db access side and push the developer to introduce limitations at the entry point of his code: limit the number of http requests treated simultaneously, for instance.
答案2
得分: 0
我相信你在这里遇到的错误不是因为你的代码,而是因为你正在运行的 Docker 镜像。
你可以在这里看到相同的问题。一个解决方案是搜索另一个 Linux 镜像或尝试重新安装它。
关于你的代码,有一些注意事项:
clear(masterSession)
这个代码在第一次运行时会出现错误,因为没有集合和数据。请查看你的代码第26行。
我在我的本地机器上使用 docker-compose
运行了你的代码,只运行了 MongoDB 镜像,一切正常。所以我可以假设问题出在你的 Docker Linux 镜像上。
希望对你有帮助。
英文:
I believe the error you're getting here is not because your code but the image docker you're running.
You can see the same issue right here. One solution is to search another linux image or try to reinstall it.
And Some notice on your code :
clear(masterSession)
this will panic for the first time since there are no collection and data at the first run. see at your code line 26.
I have tried your code in my local machine using docker-compose
only running the mongodb image All works fine. so I can assume the problem is within your docker linux image.
Hope it helps
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论