提高 Gremlin 服务器命令评估性能

Improving Gremlin Server Command Evaluation Performance

当将数万个节点和边缘插入到 cassandra 支持的 tinkerpop 中时,我发现除了 Gremlin 服务器之外,基本上所有服务都处于空闲状态。也就是说,客户端连接到 websocket 并发送 Gremlin 格式的命令不会消耗太多 CPU 时间,Cassandra 或 ElasticSearch 也不会。另一方面,Gremlin Server 正在消耗数 CPUs(在一台拥有数十个内核和数百 GB RAM 的相当强大的机器上)。

增加 GS 工作线程的数量不会产生积极影响。增加允许的同时 websocket 请求数(客户端设置)也无济于事。奇怪的是,无限数量的并发 websocket 请求导致数据插入失败,没有任何 HTTP 错误消息响应。

工作原理是 gremlin 服务器的瓶颈是对 Gremlin 命令(g.addV 等)的评估。有没有人有使用 websocket 插件获得高摄取率的经验,或者我是否有必要编写自己的 JVM 语言插件来处理二进制数据以避免解析和评估字符串?

编辑:脚本是最多 100 个顶点插入或 edge/vertex/edge 插入语句的批次:

顶点插入:

graph.addVertex(label, tyParam, 'ident', vertexName, param1, val1, param2, val2 ...) ;
graph.addVertex(...) ; 
...

对于边、顶点、边的三元组:

edgeNode = graph.addVertex(...) ; 
g.V().has('ident',var).next().addEdge(var2,edgeNode) ;
edgeNode.addEdge(var3, g.V().has('ident',var4).next())

'ident' 是节点索引,因此 .has 应该很快。遗憾的是,数据集包含不存在的源或目的地的边,导致 "FastNoSuchElementException" 错误。在错误情况下,我们将语句集分成两半,然后将脚本重试为两次较小的插入尝试。例如,一个包含 50 个 edge/vertex/edge 插入语句失败的脚本变成两个包含 25 个语句的脚本,并且此过程一直持续到具有单个 e/v/e 插入的脚本,其中忽略任何失败。

N.B。我正在使用 Titan 1.0.

为了在 Gremlin Server 中获得最佳性能,script parameterization 很重要。否则,服务器将无法有效地利用其脚本缓存,并且处理的每个脚本最终都必须进行编译,这通常是请求中成本较高的部分之一。请注意,要使脚本缓存起作用,脚本在其文本中的各个方面都必须相同,甚至包括变量名。换句话说:

g.V(var1)
g.V(var2)

不完全相同,因为它们具有不同的变量名,因此不会利用脚本缓存。

如果无法使脚本完全相同,那么提交此类脚本时将 #jsr223.groovy.engine.keep.globals 请求参数设置为 hard 以外的参数(即 softweakphantom),以便 Gremlin 服务器可以在更多新脚本到达时从脚本缓存中回收内存。