使用Java API的OrientDB 2.0.0批量加载是CPU绑定的

Pat*_*fel 6 bulkinsert orientdb gdelt

我正在使用OrientDB 2.0.0来测试其对批量数据加载的处理.对于样本数据,我使用的是谷歌GDELT项目的GDELT数据集(免费下载).我正在使用Java API将总共~80M的顶点(每个具有8个属性)加载到空白图数据库的V类中.

数据在一个制表符分隔的文本文件(US-ASCII)中,所以我只是从上到下阅读文本文件.我使用配置数据库OIntentMassiveInsert(),并将事务大小设置为每次提交25,000条记录.

我使用的是带有32G RAM和SSD的8核机器,所以硬件不应该是一个因素.我正在使用Java 8r31运行Windows 7 Pro.

前20M(左右)记录很快进入,每批25,000个记录不到2秒.我很受鼓舞.

然而,随着该过程继续运行,插入速率显着减慢.减速似乎非常线性.以下是输出日志中的一些示例行:

Committed 25000 GDELT Event records to OrientDB in 4.09989189 seconds at a rate of 6097 records per second. Total = 31350000
Committed 25000 GDELT Event records to OrientDB in 9.42005182 seconds at a rate of 2653 records per second. Total = 40000000
Committed 25000 GDELT Event records to OrientDB in 15.883908716 seconds at a rate of 1573 records per second. Total = 45000000
Committed 25000 GDELT Event records to OrientDB in 45.814514946 seconds at a rate of 545 records per second. Total = 50000000
Run Code Online (Sandbox Code Playgroud)

随着操作的进展,内存使用率一直保持不变,但OrientDB的CPU使用率却越来越高,与持续时间保持一致.最初,OrientDB Java进程使用了​​大约5%的CPU.它现在高达约90%,利用率很好地分布在所有8个核心上.

我应该将加载操作分解为几个连续的连接,还是它实际上是如何在内部管理顶点数据的功能,如果我停止进程并继续插入我离开的位置并不重要?

谢谢.

[更新]该进程最终因错误而死亡:java.lang.OutOfMemoryError:超出了GC开销限制

所有提交都已成功处理,最终我的记录超过了5100万.我将研究重构加载器以将1个巨型文件分解为许多较小的文件(例如,每个文件为1m记录),并将每个文件视为单独的加载.

完成后,我将尝试获取平顶点列表并添加一些边.有关如何在批量插入的上下文中执行此操作的任何建议,其中尚未分配顶点ID?谢谢.

[更新2]我正在使用Graph API.这是代码:

// Open the OrientDB database instance
OrientGraphFactory factory = new OrientGraphFactory("remote:localhost/gdelt", "admin", "admin");
factory.declareIntent(new OIntentMassiveInsert());
OrientGraph txGraph = factory.getTx();

// Iterate row by row over the file.
while ((line = reader.readLine()) != null) {
    fields = line.split("\t");
    try {
        Vertex v = txGraph.addVertex(null); // 1st OPERATION: IMPLICITLY BEGIN A TRANSACTION
        for (i = 0; i < headerFieldsReduced.length && i < fields.length; i++) {
            v.setProperty(headerFieldsReduced[i], fields[i]);
        }

        // Commit every so often to balance performance and transaction size
        if (++counter % commitPoint == 0) {
            txGraph.commit();
        }

    } catch( Exception e ) {
        txGraph.rollback();
    }
}
Run Code Online (Sandbox Code Playgroud)

[更新3 - 2015-02-08]问题解决了!

如果我更仔细地阅读文档,我会看到在批量加载中使用事务是错误的策略.我转而使用"NoTx"图并批量添加顶点属性,它可以像一个冠军一样,不会随着时间的推移而减速或者盯住CPU.

我从数据库中的52m顶点开始,在22分钟内以每秒超过14,000个顶点的速度增加了19m,每个顶点有16个属性.

Map<String,Object> props = new HashMap<String,Object>();
// Open the OrientDB database instance
OrientGraphFactory factory = new OrientGraphFactory("remote:localhost/gdelt", "admin", "admin");
factory.declareIntent(new OIntentMassiveInsert());
graph = factory.getNoTx();
OrientVertex v = graph.addVertex(null); 
for (i = 0; i < headerFieldsReduced.length && i < fields.length; i++) {
    props.put(headerFieldsReduced[i], fields[i]);
}
v.setProperties(props);
Run Code Online (Sandbox Code Playgroud)