MongoDB + C中存在不同写入问题的奇怪性能测试结果#

时间:2013-09-28 12:53:39

标签: mongodb mongodb-.net-driver

我试图在实际使用它之前测试 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的不同值的结果:

  1. 当我将w设置为1时,可以获得最快的结果!
  2. 设置w=0慢于w=1 28次!
  3. w=-1将导致抛出错误消息W value must be greater than or equal to zero
  4. 有没有人对这些结果有任何解释?我做错了吗?

    [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 Concernsw=-1w=0w=1w=1&j=true分别运行了此代码10k。虽然w=-1会抛出异常并且没有给出任何结果,但其余部分的结果如下:

    enter image description here

    由于这个数字有点难以阅读,因此数字结果相同:

                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=0w=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);
    }
    

    它对任何结果都没有显着影响,无论如何。

1 个答案:

答案 0 :(得分:0)

要解决w=-1错误,您可能需要直接使用WriteConcern.Unacknowledged property

您的测试代码可能会遇到一致性问题。查看RequestStart/RequestDone以将查询置于同一连接上。根据文件:

  

这可能是必要的一个示例是当一个插入符号以快速连续的方式调用,并且写入W = 0的WriteConcern,并且您希望此后立即以一致的方式查询数据(使用W的WriteConcern) = 0,写入可以在服务器上排队,可能不会立即对其他连接可见

Aphyr对a good blog post关于MongoDB写入的各种设置如何影响其一致性的近似做了build.ps1。它可以帮助您解决此问题。

最后,您可以在{{3}}

中找到您的驱动程序版本