我试图在实际使用它之前测试 MongoDB 的性能。我正在尝试查看每秒可以更新多少文档。我正在使用C#(Mono + Ubuntu)MongoDB驱动程序v1.9和MongoDB v2.4.6。
我认为写性能最有效的MongoDB参数之一是Write Concern
。正如documentation中所述,写作关注的最宽松值是-1
,然后是0
,最后1
是最慢的。
搜索后我发现我可以在连接字符串中嵌入C#中设置写问题,如下所示:
var client = new MongoClient("mongodb://localhost/?w=-1");
以下是我使用w
的不同值的结果:
w
设置为1
时,可以获得最快的结果!w=0
慢于w=1
28次!w=-1
将导致抛出错误消息W value must be greater than or equal to zero
!有没有人对这些结果有任何解释?我做错了吗?
[UPDATE]
我认为有必要设置测试程序,也许隐藏在其中的东西。所以这就是:
我在一个集合中有一个包含100M文档的数据库。使用mongo shell创建每个文档:
{ "counter" : 0, "last_update" : new Date() }
以下是db.collection.stats();
的输出:
{
"ns" : "test.collection",
"count" : 100000100,
"size" : 6400006560,
"avgObjSize" : 64.0000015999984,
"storageSize" : 8683839472,
"numExtents" : 27,
"nindexes" : 2,
"lastExtentSize" : 2146426864,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 5769582448,
"indexSizes" : {
"_id_" : 3251652432,
"last_update_1" : 2517930016
},
"ok" : 1
}
在 Ubuntu 12.04 中使用 Mono 3.2.1 我编写了 C#项目,该项目连接到 MongoDB 并尝试更新这样的文档:
FindAndModifyArgs args = new FindAndModifyArgs();
args.SortBy = SortBy.Ascending("last_update");
args.Update = Update<Entity>.Set(e => e.last_update, DateTime.Now);
args.Fields = Fields.Include(new string[] { "counter", "_id" });
var m = collection.FindAndModify(args);
Entity ent = m.GetModifiedDocumentAs<Entity>();
var query = Query<Entity>.EQ(e => e.Id, ent.Id);
var update = Update<Entity>.Set(e => e.counter, ent.counter+1);
collection.Update(query, update);
总结这段代码的作用;它选择最早的last_update
并在将last_update
设置为当前日期时,它也会增加其计数器(更新分两步进行)。
我为四种不同类型的Write Concerns
,w=-1
,w=0
,w=1
和w=1&j=true
分别运行了此代码10k。虽然w=-1
会抛出异常并且没有给出任何结果,但其余部分的结果如下:
由于这个数字有点难以阅读,因此数字结果相同:
w=-1 w=0 w=1 w=1&j=true
Average N/A 244.0948611492 7064.5143923477 238.1846428156
STDEV N/A 1.7787457992 511.892765742 21.0230097306
问题是:有没有人解释为什么w=0
比w=1
慢得多,为什么w=-1
不受支持?
[UPDATE]
我还在我的代码中测试了RequestStart
,如下所示:
using (server.RequestStart(database)) {
FindAndModifyArgs args = new FindAndModifyArgs();
args.SortBy = SortBy.Ascending("last_update");
args.Update = Update<Entity>.Set(e => e.last_update, DateTime.Now);
args.Fields = Fields.Include(new string[] { "counter", "_id" });
var m = collection.FindAndModify(args);
Entity ent = m.GetModifiedDocumentAs<Entity>();
var query = Query<Entity>.EQ(e => e.Id, ent.Id);
var update = Update<Entity>.Set(e => e.counter, ent.counter+1);
collection.Update(query, update);
}
它对任何结果都没有显着影响,无论如何。
答案 0 :(得分:0)
要解决w=-1
错误,您可能需要直接使用WriteConcern.Unacknowledged
property。
您的测试代码可能会遇到一致性问题。查看RequestStart/RequestDone以将查询置于同一连接上。根据文件:
这可能是必要的一个示例是当一个插入符号以快速连续的方式调用,并且写入W = 0的WriteConcern,并且您希望此后立即以一致的方式查询数据(使用W的WriteConcern) = 0,写入可以在服务器上排队,可能不会立即对其他连接可见
Aphyr对a good blog post关于MongoDB写入的各种设置如何影响其一致性的近似做了build.ps1。它可以帮助您解决此问题。
最后,您可以在{{3}}
中找到您的驱动程序版本