2014-10-27 36 views
2

在我们的系统中有一个(很常见)的情况,用户的行为可以触发操作,涉及将标签设置/从节点之间的关系总计数十万个实体的关系。 (从100K节点中删除标签A,将标签B设置为80K标签,将属性[x,y,z]设置为20K节点等等)。当然,我不能在一次交易中把它们全部挤走,并且,由于这些节点可以很容易地分成大量的子集,因此我在一些单独的事务中执行这些操作,当然这些事务当然会中断所有的ACIDity,但在性能方面令我们满意。但是,如果我试图将这些交易嵌套到一个大型交易中以将它们全部统一为,则该顶级交易会尝试跟踪所有内部交易对数据库的更新,这当然会导致极差的性能。处理大型交易:任何时间/内存权衡?

你们可以推荐我解决这个问题吗?

我的配置(当然,它的相关部分):

"org.neo4j.server.database.mode" : "HA", 
"use_memory_mapped_buffers" : "true", 
"neostore.nodestore.db.mapped_memory" : "450M", 
"neostore.relationshipstore.db.mapped_memory" : "450M", 
"neostore.propertystore.db.mapped_memory" : "450M", 
"neostore.propertystore.db.strings.mapped_memory" : "300M", 
"neostore.propertystore.db.arrays.mapped_memory" : "50M", 
"cache_type" : "hpc", 
"dense_node_threshold" : "15", 
"query_cache_size" : "150" 

任何提示和线索,我们非常感激:)

+0

你提供了多少堆?如果你有合理的堆大小(例如4到16GB,你应该可以将1M操作合并到一个巨大的Tx中)。 – 2014-10-30 02:59:06

+0

您当然不需要450M节点存储,请阅读mmio缓存配置部分,或者查看您的存储文件以找到适合mmio配置的明智值。 – 2014-10-30 03:00:09

+0

我读了这部分并做了数学计算,实际上它比我现在需要的要多一点,但还有其他一些操作,比如选择(可能大约100K)具有特定标签的节点并从中读取一些属性,并且可能会有> 1同时要求这样的性质,所以我决定在那里放一些(不)相当大的数字。 – tkroman 2014-10-30 10:16:48

回答

3

你是正确的,修改成千上万的实体作为用户的结果在同一个交易中的行为不会被执行。正如您正确指出的那样,Neo4j中的嵌套事务只是“安慰剂”事务。

我会先考虑替代策略来实现您的目标(我一无所知),而无需更新太多的实体。

如果不可行,我会问是否可以在用户操作后的短时间内发生更新。如果答案是肯定的,那么我会将一个关于用户操作的消息存储在一个持久队列中,这将会异步处理。这样,用户调用会很快返回,最终发生更新。

最后,如果在用户操作和大型更新之间的时间花费更长的时间是可以接受的,我会考虑和“代理”不断爬取图并更新它遇到的实体的标签,如反对交易驱动的更新。看看GraphAware NodeRank的灵感。