使用mgo进行并发查询MongoDB时,会导致套接字关闭。

huangapple go评论93阅读模式
英文:

Concurrent queries to MongoDB using mgo ends in closed sockets

问题

我一直在Stack Overflow上查看一些问题,以及一些人们在mgo golang lib中展示如何管理会话的帖子。

问题是,我看到的所有示例都不能同时运行太多并发查询。增加并发操作的数量会导致套接字关闭。在这里,您可以找到我运行的代码,以重现此行为。

使用mgo进行并发查询到MongoDB会导致套接字关闭。

请注意,我只运行了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

huangapple
  • 本文由 发表于 2017年3月11日 21:04:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/42735535.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定