Mongo C驱动程序,尽可能快地更新文档

时间:2012-08-16 02:18:28

标签: mongodb mongodb-c nosql

很简单,我需要将时间序列数据存储在文档中。我已经决定让一份负责30分钟数据的文件是合理的。该文件可能如下所示:

但这只是每秒钟更新的几百个/千个文档中的一个。

{
    _id: "APAC.tky001.cpu.2011.12.04:10:00",
    field1: XX,
    field2: YY,
    1322971800: 22,
    1322971801: 23,
    1322971802: 21,

    // and so on
 }

这意味着每30分钟,我会使用_idfield1field2创建文档。然后,每隔一秒我想添加一个时间戳/值组合。

我正在使用mongo c库,我认为它会超快,但我这样做的方式需要mongo_update,这不能大量完成。我认为没有办法使用mongo_insert_batch

不幸的是,这是超级慢 - 糟糕的表现。我完全错误地这样做了吗?可怕的是,我的意思是通过做一些粗略的工作,我得到600 /秒,在另一个数据库(不命名)我得到27,000 /秒。

代码大约是:

for (i=0;i<N;i++) {
    if (mongo_update(c,n,a,b,MONGO_UPDATE_UPSERT,write_concern) != MONGO_OK)
        // stuff
}

关闭或打开写入关注没有任何区别。

2 个答案:

答案 0 :(得分:2)

您的更新可能会使文档每次都超出范围。这意味着更新不再便宜,因为mongo必须将文档复制到新位置。 您可以通过在创建文档时插入一些大的虚拟值并稍后将其删除来手动填充文档,以便您的更新就地发生。我不确定你是否可以直接操作集合级paddingFactor。

在另一个未命名的数据库中,您可能每个条目都插入一行,这与您在此处的操作完全不同。

答案 1 :(得分:0)

Mongo最新的c-driver确实支持批量插入:

http://api.mongodb.org/c/current/bulk.html#bulk-insert

#include <assert.h>
#include <bcon.h>
#include <mongoc.h>
#include <stdio.h>

static void
bulk1 (mongoc_collection_t *collection)
{
   mongoc_bulk_operation_t *bulk;
   bson_error_t error;
   bson_t *doc;
   bson_t reply;
   char *str;
   bool ret;
   int i;

   bulk = mongoc_collection_create_bulk_operation (collection, true, NULL);

   for (i = 0; i < 10000; i++) {
      doc = BCON_NEW ("i", BCON_INT32 (i));
      mongoc_bulk_operation_insert (bulk, doc);
      bson_destroy (doc);
   }

   ret = mongoc_bulk_operation_execute (bulk, &reply, &error);

   str = bson_as_json (&reply, NULL);
   printf ("%s\n", str);
   bson_free (str);

   if (!ret) {
      fprintf (stderr, "Error: %s\n", error.message);
   }

   bson_destroy (&reply);
   mongoc_bulk_operation_destroy (bulk);
}

int
main (int argc,
      char *argv[])
{
   mongoc_client_t *client;
   mongoc_collection_t *collection;

   mongoc_init ();

   client = mongoc_client_new ("mongodb://localhost/");
   collection = mongoc_client_get_collection (client, "test", "test");

   bulk1 (collection);

   mongoc_collection_destroy (collection);
   mongoc_client_destroy (client);

   mongoc_cleanup ();

   return 0;
}