Java 将许多语句加载到Jena数据集中最有效的方法是什么?

Java 将许多语句加载到Jena数据集中最有效的方法是什么?,java,transactions,rdf,jena,bigdata,Java,Transactions,Rdf,Jena,Bigdata,我用它来维护各种软件项目的调用依赖结构。在静态分析大型项目之后,我可能需要在TDB支持的数据集中向一个专用的Jena模型添加100k条语句,在极端情况下甚至可能需要数百万条语句 问题 添加30万条语句大约需要11分钟。想象一下,增加3米需要多长时间。我想知道是否有另一种方法来添加这么多语句,或者是另一种技术 我试过的 使用model.addList stmts添加了所有语句-抛出java.lang.OutOfMemoryError并由于获取的写锁而占用数据集。 在提交和释放中间的锁时,以块(例如

我用它来维护各种软件项目的调用依赖结构。在静态分析大型项目之后,我可能需要在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的建议,我尝试在单个事务中添加所有语句,如下所示:

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,只有图形数据库;就我的目的而言,它更加有用,并且具有极大的可扩展性。不过,谢谢你的见解,我不妨把这一点作为正确答案。