В настоящее время мы изучаем Capped Collections и Tailable Cursors в MongoDB для создания системы массового обслуживания для уведомлений. Однако после создания простого теста LinqPad (код ниже), который мы заметили при запуске, Mongo постоянно выделяет память, пока не будет доступных ресурсов, даже если мы не вставляем никаких записей. Это распределение продолжается до тех пор, пока не будет использовано все системное ОЗУ, после чего Mongo просто перестает отвечать на запросы.MongoDB 2.4.8 capped collection и tailable курсор, потребляющий всю память
Поскольку мы новичок в Capped Collections и Tailable Cursors, я хотел, чтобы мы не пропустили что-то очевидное, прежде чем отправлять ошибку.
Примечание. Мы пробовали код ниже с ведением журнала вкл./Выкл. С теми же результатами.
- Платформа: Windows Server 2012 64bit
- MongoDB: Версия 2.4.8 64bit
- Driver: Официальный 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 , пока он работает. Для информации, я использую одну машину, добавляя репликацию только для этой функции. Вот мой currentOp и войти: https://dl.dropboxusercontent.com/u/853035/currentOp.txt https://dl.dropboxusercontent.com/u/853035/log.txt –
Теперь я обнаружил, что использование памяти составляет около 2,4 ГБ, вводя MoveNext в первый раз. После того, как первый документ будет возвращен, он упадет до 1,2 ГБ, после второго документа он вернется к исходному значению ??? Смотрите изображение здесь: https://dl.dropboxusercontent.com/u/853035/memory_usage.png –