【发布时间】:2014-01-09 02:40:29
【问题描述】:
我们目前正在探索 MongoDB 中的 Capped Collections 和 Tailable Cursors,以创建一个用于通知的排队系统。然而,在创建了一个简单的 LinqPad 测试(下面的代码)之后,我们注意到在运行时,即使我们没有插入任何记录,Mongo 也会不断地分配内存,直到没有更多可用资源。这种分配一直持续到所有系统 RAM 都用完,此时 Mongo 会停止响应。
由于我们是 Capped Collections 和 Tailable Cursors 的新手,我想确保在提交错误之前我们没有遗漏一些明显的东西。
注意:我们尝试了下面的代码,打开和关闭日志,结果相同。
- 平台:Windows Server 2012 64bit
- MongoDB:版本 2.4.8 64 位
- 驱动:官方C# 10gen v1.8.3.9
Linqpad 脚本
var conn = new MongoClient("mongodb://the.server.url").GetServer().GetDatabase("TestDB");
if(!conn.CollectionExists("Queue")) {
conn.CreateCollection("Queue", CollectionOptions
.SetCapped(true)
.SetMaxSize(100000)
.SetMaxDocuments(100)
);
//Insert an empty document as without this 'cursor.IsDead' is always true
var coll = conn.GetCollection("Queue");
coll.Insert(
new BsonDocument(new Dictionary<string, object> {
{ "PROCESSED", true },
}), WriteConcern.Unacknowledged
);
}
var coll = conn.GetCollection("Queue");
var query = coll.Find(Query.EQ("PROCESSED", false))
.SetFlags(QueryFlags.AwaitData | QueryFlags.NoCursorTimeout | QueryFlags.TailableCursor);
var cursor = new MongoCursorEnumerator<BsonDocument>(query);
while(true) {
if(cursor.MoveNext()) {
string.Format(
"{0:yyyy-MM-dd HH:mm:ss} - {1}",
cursor.Current["Date"].ToUniversalTime(),
cursor.Current["X"].AsString
).Dump();
coll.Update(
Query.EQ("_id", cursor.Current["_id"]),
Update.Set("PROCESSED", true),
WriteConcern.Unacknowledged
);
} else if(cursor.IsDead) {
"DONE".Dump();
break;
}
}
【问题讨论】:
-
你能运行 db.currentOp() 吗?您还可以发布涵盖运行的 mongod 日志文件吗?
-
我遇到了同样的问题...看来,mongoDB 在运行时将整个 oplog 保存在 RAM 中。对于信息,我使用单台机器,仅为此功能添加复制。这是我的当前操作和日志:dl.dropboxusercontent.com/u/853035/currentOp.txtdl.dropboxusercontent.com/u/853035/log.txt
-
现在我发现第一次进入MoveNext时内存使用量约为2.4GB。返回第一个文档后,它下降到 1.2GB,第二个文档后它又回到了原始值???看这里的图片:dl.dropboxusercontent.com/u/853035/memory_usage.png
-
@Needleski,当你说“MongoDB”消耗所有内存时,你指的是服务器还是驱动程序?
-
@CraigWilson 服务器进程(Windows 上的 mongod.exe)
标签: c# windows mongodb capped-collections