Пн go java драйвер медленный по сравнению с оболочкой (15 раз) - PullRequest
0 голосов
/ 28 марта 2020

Попытка вывести только столбец _id. С оболочкой mon go он заканчивается примерно за 2 минуты:

time mongoexport -h localhost -d db1 -c collec1 -f _id -o u.text --csv
connected to: localhost
exported 68675826 records
real    2m20.970s

С java это занимает около 30 минут: java -cp mongo-test-assembly-0.1.jar com.poshmark.Test

class Test {
public static void main(String[] args) {


    MongoClient mongoClient = new MongoClient("localhost");
    MongoDatabase database = mongoClient.getDatabase("db1");
    MongoCollection<Document> collection = database.getCollection("collec1");

    MongoCursor<Document> iterator = collection.find().projection(new Document("_id", 1)).iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next().toString());
    }
}

}

Загрузка ЦП на коробке низкая, проблем с задержкой в ​​сети не наблюдается, поскольку оба теста выполняются из одного блока

Обновление:

Используется Files.newBufferedWriter из System.out.println, но с такой же производительностью.

Посмотрев на db.currentOp (), я думаю, что mon go поражает диск, так как на нем слишком много numYields

{
"inprog" : [
    {
        "desc" : "conn8636699",
        "threadId" : "0x79a70c0",
        "connectionId" : 8636699,
        "opid" : 1625079940,
        "active" : true,
        "secs_running" : 12,
        "microsecs_running" : NumberLong(12008522),
        "op" : "getmore",
        "ns" : "users.users",
        "query" : {
            "_id" : {
                "$exists" : true
            }
        },
        "client" : "10.1.166.219:60324",
        "numYields" : 10848,
        "locks" : {

        },
        "waitingForLock" : false,
        "lockStats" : {
            "Global" : {
                "acquireCount" : {
                    "r" : NumberLong(21696)
                },
                "acquireWaitCount" : {
                    "r" : NumberLong(26)
                },
                "timeAcquiringMicros" : {
                    "r" : NumberLong(28783)
                }
            },
            "MMAPV1Journal" : {
                "acquireCount" : {
                    "r" : NumberLong(10848)
                },
                "acquireWaitCount" : {
                    "r" : NumberLong(5)
                },
                "timeAcquiringMicros" : {
                    "r" : NumberLong(40870)
                }
            },
            "Database" : {
                "acquireCount" : {
                    "r" : NumberLong(10848)
                }
            },
            "Collection" : {
                "acquireCount" : {
                    "R" : NumberLong(10848)
                }
            }
        }
    }
  ]
}

1 Ответ

2 голосов
/ 28 марта 2020

Проблема заключается в STDOUT.

Печать на стандартный вывод не является медленной по своей природе. Это терминал, с которым вы работаете is slow.

{ ссылка }

Диск выглядит быстрее, потому что он очень с буферизацией.

Терминал, с другой стороны, практически не выполняет буферизацию: каждая отдельная функция печати / записи (строка) ожидает завершения полной записи (т.е. отображения на устройстве вывода).

{ ссылка }

Я воспроизвел ваш пример использования с достаточно похожим набором данных.

mongoexport до FILE

$ time "C:\Program Files\MongoDB\Server\4.2\bin\mongoexport.exe" -h localhost -d test -c collec1 -f _id -o u.text --csv
2020-03-28T13:03:01.550+0100    csv flag is deprecated; please use --type=csv instead
2020-03-28T13:03:02.433+0100    connected to: mongodb://localhost/
2020-03-28T13:03:03.479+0100    [........................]  test.collec1  0/21028330  (0.0%)
2020-03-28T13:05:02.934+0100    [########################]  test.collec1  21028330/21028330  (100.0%)
2020-03-28T13:05:02.934+0100    exported 21028330 records

real    2m1,936s
user    0m0,000s
sys     0m0,000s

mongoexport к STDOUT

$ time "C:\Program Files\MongoDB\Server\4.2\bin\mongoexport.exe" -h localhost -d test -c collec1 -f _id --csv
2020-03-28T14:43:16.479+0100    connected to: mongodb://localhost/
2020-03-28T14:43:16.545+0100    [........................]  test.collec1  0/21028330  (0.0%)
2020-03-28T14:53:02.361+0100    [########################]  test.collec1  21028330/21028330  (100.0%)
2020-03-28T14:53:02.361+0100    exported 21028330 records

real    9m45,962s
user    0m0,015s
sys     0m0,000s

JAVA к FILE

$ time "C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" -jar mongo-test-assembly-0.1.jar FILE
Wasted time for [FILE] -  271,57 sec

real    4m32,174s
user    0m0,015s
sys     0m0,000s

JAVA к STDOUT к FILE

$ time "C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" -jar mongo-test-assembly-0.1.jar SYSOUT > u.text

real    6m50,962s
user    0m0,015s
sys     0m0,000s

JAVA в STDOUT

$ time "C:\Program Files\Java\jdk1.8.0_211\bin\java.exe" -jar mongo-test-assembly-0.1.jar SYSOUT > u.text

Wasted time for [SYSOUT] -  709,33 sec

real    11m51,276s
user    0m0,000s
sys     0m0,015s

Java код

long init = System.currentTimeMillis();
try (MongoClient mongoClient = new MongoClient("localhost");
    BufferedWriter writer = Files.newBufferedWriter(Files.createTempFile("benchmarking", ".tmp"))) {

    MongoDatabase database = mongoClient.getDatabase("test");
    MongoCollection<Document> collection = database.getCollection("collec1");

    MongoCursor<Document> iterator = collection.find().projection(new Document("_id", 1)).iterator();
    while (iterator.hasNext()) {
        if ("SYSOUT".equals(args[0])) {
            System.out.println(iterator.next().get("_id"));

        } else {
            writer.write(iterator.next().get("_id") + "\n");
        }
    }
} catch (Exception e) {
    e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println(String.format("Wasted time for [%s] -  %.2f sec", args[0], (end - init) / 1_000.));
...