MongoDB:奇怪的写入性能

JDa*_*Day 5 java mongodb

我在使用 MongoDB 3.0.5 和 mongo java 驱动程序 2.13.1 时遇到了奇怪的写入性能。如果应用程序空闲了给定的时间,下一次写入大约需要 17 秒,然后任何进一步的写入都会立即进行。之前的读取只是毫秒。记录只有几十条,而且都很小。使用默认的 Write Concern,即 ACKNOWLEDGE。因此,正如所观察到的,具有完全相同的记录计数和大小:

闲置的。读取~10ms。写 17 秒。读取~10ms。写入~25ms。

代码示例很简单,上面的结果有一个基本的计时器:

Long timer = System.currentTimeMillis();
Stack<BasicDBObject> stack = new Stack<>();
DBCursor cloneCursor = cloneMongo.getCollection("ourCollection").find();
while (cloneCursor.hasNext())
{
    BasicDBObject cloneRec = (BasicDBObject) cloneCursor.next();
    if (cloneRec.containsField("name"))
    {
    if (cloneRec.getString("name").equals("project"))
    {
        cloneRec.put("default", destProject.getID());
    }
    }
    stack.add(cloneRec);
}
Util.print("Clone - Clone Read:"+(System.currentTimeMillis() - timer), 1);
DBCollection collection = cloneMongo.getCollection("collection2");
BulkWriteOperation bulkOp = collection.initializeUnorderedBulkOperation();
Util.print("Clone - Clone DestConnect:"+(System.currentTimeMillis() - timer), 1);
while (!stack.isEmpty())
{
    bulkOp.insert(stack.pop());
}
bulkOp.execute();
Util.print("Clone - Clone Write:"+(System.currentTimeMillis() - timer), 1);
Run Code Online (Sandbox Code Playgroud)

我们已经在 Platter Disks、FusionIO 驱动器和 15kRPM SAS 驱动器上观察到这种确切的模式,所以我怀疑它是 IO 性能。如果我们将写关注设置为 JOURNLED,我们始终会在所有尝试中获得 17 秒的写入。

我发现可行的临时解决方案是定期(约 10 秒)将垃圾(甚至增加现有记录中的值)写入垃圾集合。这似乎愚弄了系统,避免了导致它“入睡”的任何事情。

MongoDB 中的哪些设置或对我们逻辑的更改可以避免这些极其缓慢的初始写入?