加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – MongoDB 2.4.8上限集合和tailable游标消耗所有内存

发布时间:2020-12-15 08:00:06 所属栏目:百科 来源:网络整理
导读:我们目前正在探索MongoDB中的Capped Collections和Tailable Cursors来创建一个通知排队系统.但是,在创建一个简单的 LinqPad测试(下面的代码)后,我们注意到在运行时,Mongo不断分配内存,直到没有更多可用资源,即使我们没有插入任何记录.这种分配一直??持续到使
我们目前正在探索MongoDB中的Capped Collections和Tailable Cursors来创建一个通知排队系统.但是,在创建一个简单的 LinqPad测试(下面的代码)后,我们注意到在运行时,Mongo不断分配内存,直到没有更多可用资源,即使我们没有插入任何记录.这种分配一直??持续到使用所有系统RAM为止,此时Mongo只是停止响应.

由于我们是Capped Collections和Tailable Cursors的新手,我想确保在提交错误之前我们没有错过任何明显的东西.

注意:我们尝试使用以下代码打开和关闭日记,但结果相同.

>平台:Windows Server 2012 64位
> 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;
    }
}

解决方法

看来我找到了问题的解决方案!!

上述代码中的问题围绕查询:

Query.EQ("PROCESSED",false)

当我删除它并用基于文档ID的查询替换它时,内存消耗问题消失了.在进一步思考时,查询中不需要这个“PROCESSED”属性作为cursor.MoveNext()将始终返回下一个新文档(如果有的话).下面是基于以上代码重构的LinqPad脚本….

var conn = new MongoClient("mongodb://the.server.url").GetServer().GetDatabase("TestDB");

if(conn.CollectionExists("Queue")) {
    conn.DropCollection("Queue");
}

conn.CreateCollection("Queue",CollectionOptions
    .SetCapped(true)
    .SetMaxSize(100000)
    .SetMaxDocuments(100)
    .SetAutoIndexId(true)
);

//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",{ "Date",DateTime.UtcNow },{ "X","test" }
    }),WriteConcern.Unacknowledged
);

//Create query based on latest document id
BsonValue lastId = BsonMinKey.Value;
var query = coll.Find(Query.GT("_id",lastId))
    .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["X"].AsString
        ).Dump();
    } else if(cursor.IsDead) {
        "DONE".Dump();
        break;
    }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读