Java 将许多语句加载到Jena数据集中最有效的方法是什么?
我用它来维护各种软件项目的调用依赖结构。在静态分析大型项目之后,我可能需要在TDB支持的数据集中向一个专用的Jena模型添加100k条语句,在极端情况下甚至可能需要数百万条语句 问题 添加30万条语句大约需要11分钟。想象一下,增加3米需要多长时间。我想知道是否有另一种方法来添加这么多语句,或者是另一种技术 我试过的 使用model.addList stmts添加了所有语句-抛出java.lang.OutOfMemoryError并由于获取的写锁而占用数据集。 在提交和释放中间的锁时,以块(例如1000)的形式添加了所有语句。如前所述,它可以工作,但需要很长时间,我认为这是由于事务性预写日志记录的开销造成的。 以非事务方式将语句添加到临时的、新的和TDB支持的模型中,然后用新模型替换旧模型。RAM使用率急剧上升,降低了整个系统的速度。 附带问题 对于这个用例,您会推荐Jena/RDF的替代方案吗? Jena是可扩展的w.r.t.分布式文件系统/计算吗? 其他资料 我使用的事务可能是由于大量I/O导致的一个主要减速因素。但无法避免,因为它曾经是事务性的,始终是事务性的 TDB支持的数据集可以非事务性地使用,但一旦在事务中使用,之后必须以事务性方式使用 谢谢你的建议,非常感谢 代码与测试 根据@AndyS的建议,我尝试在单个事务中添加所有语句,如下所示:Java 将许多语句加载到Jena数据集中最有效的方法是什么?,java,transactions,rdf,jena,bigdata,Java,Transactions,Rdf,Jena,Bigdata,我用它来维护各种软件项目的调用依赖结构。在静态分析大型项目之后,我可能需要在TDB支持的数据集中向一个专用的Jena模型添加100k条语句,在极端情况下甚至可能需要数百万条语句 问题 添加30万条语句大约需要11分钟。想象一下,增加3米需要多长时间。我想知道是否有另一种方法来添加这么多语句,或者是另一种技术 我试过的 使用model.addList stmts添加了所有语句-抛出java.lang.OutOfMemoryError并由于获取的写锁而占用数据集。 在提交和释放中间的锁时,以块(例如
List<Statement> statements = ...;
//Print statistics
System.out.println("Statement count: " + statements.size());
//Log the start of the operation to measure its duration
Long start = System.currentTimeMillis();
//Add all statements in one transaction
workspace.beginTransaction(ReadWrite.WRITE); //forwards to dataset.begin(ReadWrite rw)
try {
model.add(statements);
} catch (Exception e) {
e.printStackTrace();
workspace.abortTransaction(); //forwards to dataset.abort()
} finally {
workspace.commitTransaction(); //forwards to dataset.commit()
}
//Check how long the operation took
double durationS = (System.currentTimeMillis() - start) / 1000.0;
System.out.println("Transaction took " + durationS + " seconds.");
此事务运行的线程崩溃,调试器中显示以下消息:
Daemon Thread [ForkJoinPool-1-worker-1] (Suspended (exception OutOfMemoryError))
将堆空间增加到4GB可以避免这个问题,但仍然占用数据集将近两分钟
Statement count: 3233481
Transaction took 108.682 seconds.
使用TDBLoader很可能与指示的方式相同,但除此之外,它不支持任何事务,我希望能够防止数据集损坏。如果使用事务,请使用一个事务来覆盖整个加载300k语句。300k通常不是非常大,3M也不是,除非它有很多非常大的文本 单个Model.addCoCollection应该可以工作 或从文件中加载:
dataset.begin(ReadWrite.WRITE) ;
try {
RDFDataMgr.read(dataset, FILENAME);
dataset.commit() ;
} finally {
dataset.end() ;
}
还有一个散装装载机用于离线装载。这是一个单独的程序tdbloader
没有Model.addCollection-存在Model.addList。将其放入事务循环中
dataset.begin(ReadWrite.WRITE) ;
try {
dataset.getDefaultModel().add(...)
dataset.commit() ;
} finally {
dataset.end() ;
}
Jena 3.1.1中有一个新的API。
如果您使用的是事务,请使用一个事务覆盖整个加载的300k语句。300k通常不是非常大,3M也不是,除非它有很多非常大的文本 单个Model.addCoCollection应该可以工作 或从文件中加载:
dataset.begin(ReadWrite.WRITE) ;
try {
RDFDataMgr.read(dataset, FILENAME);
dataset.commit() ;
} finally {
dataset.end() ;
}
还有一个散装装载机用于离线装载。这是一个单独的程序tdbloader
没有Model.addCollection-存在Model.addList。将其放入事务循环中
dataset.begin(ReadWrite.WRITE) ;
try {
dataset.getDefaultModel().add(...)
dataset.commit() ;
} finally {
dataset.end() ;
}
Jena 3.1.1中有一个新的API。
Jena TDB插入代价高昂,因为它或多或少地创建了大量索引,包括图形、主语、谓语和宾语的所有组合。重点是快速访问数据,而不是快速插入数据 我最终使用了SSD以获得可接受的插入时间 至于其他选择,我可以指出: RDF4J以前称为SESAME,它允许在数据库中选择所需的索引。 它是基于Berkeley DB作为NoSQL数据库后端的,并且似乎插入速度相当快。
Jena TDB插入代价很高,因为它或多或少地创建了许多索引,包括图形、主语、谓语和宾语的所有组合。重点是快速访问数据,而不是快速插入数据 我最终使用了SSD以获得可接受的插入时间 至于其他选择,我可以指出: RDF4J以前称为SESAME,它允许在数据库中选择所需的索引。 它是基于Berkeley DB作为NoSQL数据库后端的,并且似乎插入速度相当快。
远程Jena TDB和Fuseki也有同样的问题。我所做的是将HTTP post整个数据作为文件发布到远程Jena数据端点,该端点是
远程Jena TDB和Fuseki也有同样的问题。我所做的是将HTTP post整个数据作为文件发布到远程Jena数据端点,该端点是
JDWP退出错误与平台系统错误无关-与Jena无关。对于这个问题,谷歌有很多热议。JDWP退出错误与平台系统错误无关,与Jena无关。有相当多的谷歌热对此。非常感谢你的建议;在增加堆大小后,我再次尝试了您的方法,请参见更新的问题,但对于单个事务来说,仍然需要很长的时间,其他事务在此期间被阻止。
是的,这是列表而不是收藏,我的错。非常感谢你的建议;在增加堆大小后,我再次尝试了您的方法,请参见更新的问题,但对于单个事务来说,仍然需要很长的时间,其他事务在此期间被阻止。是的,它是列表而不是集合,我的坏。RDF4J是一个很好的提示,非常感谢。您是否知道多个应用程序实例是否可以访问同一个数据存储,例如同时使用Cumulus RDF?我可以看到:Cumulus SRDF包含一个SesameSail实现,请参见CodeExamples wiki页面。这就是连接到RDF4J四元存储所需的。积云RDF似乎很有趣,我将进一步研究它。在那里,完成了。它肯定比Jena好,因为它允许像ApacheCassandra这样的分布式存储后端,但由于缺乏资金,它已经有一段时间没有得到维护了。我目前正在切换到Titan,它的DynamoDB后端也支持Cassandra。没有RDF,只有图形数据库;就我的目的而言,它更加有用,并且具有极大的可扩展性。不过,感谢您的见解,我不妨将此作为正确答案。RDF4J是一个极好的提示,非常感谢。您是否知道多个应用程序实例是否可以访问同一个数据存储,例如同时使用Cumulus RDF?我可以看到:Cumulus SRDF包含一个SesameSail实现,请参见CodeExamples wiki页面。这就是连接到RDF4J四元存储所需的。积云RDF似乎很有趣,我将进一步研究它。在那里,完成了。它肯定比Jena好,因为它允许像ApacheCassandra这样的分布式存储后端,但由于缺乏资金,它已经有一段时间没有得到维护了。我目前正在切换到Titan,它的DynamoDB后端也支持Cassandra。没有RDF,只有图形数据库;就我的目的而言,它更加有用,并且具有极大的可扩展性。不过,谢谢你的见解,我不妨把这一点作为正确答案。