美文网首页
JanusGraph 查询步骤简要分析

JanusGraph 查询步骤简要分析

作者: ni_d58f | 来源:发表于2019-09-21 05:23 被阅读0次

1. 客户端连接

Java 客户端连接在org.apache.tinkerpop.gremlin.driver.Connection中, 触发逻辑在
Clinet.submitAsync 这个是异步提交逻辑的入口, 该方法中有一个init()方法会出发Connection逻辑

仔细查看Connection的逻辑可以知道这个 其实是是Netty客户端

需要注意两个地方:
private ConcurrentMap<UUID, ResultQueue> pending;
这保存请求与对应查询/操作结果, 客户端最后根据UUID 从这里拿查询结果
Netty读从服务器端的逻辑在GremlinResponseHandlerchannelRead逻辑中

关于具体内容,有空可以详细查看

2. 客户端查询与插入调用路径如下:

GraphTraversal.next() --> DefaultTraversal.next() --> AbstractStep.next() --> RemoteStep.processNextStart() --> RemoteStep.promise() --> DriverRemoteConnection.submitAsync() --> Client.submitAsync --> Client.submitAsync --> Connection.write() --> channel.writeAndFlush

举例来说:
对于 graph.traversal().V().has('id',1) 来说发给服务器端的请求为:

RequestMessage{, requestId=e733e602-757f-45dc-93fc-672c5171d23b, op='bytecode', processor='traversal', args={gremlin=[[], [V(), has(id, 1)]], aliases={g=g}}}

image.png

仔细观察可知,Gremlin java api将对应每一步操作拆成一个算子并封装成对应的stepInstruction,然后依次执行stepInstruction。

3. 服务器端

3.1 服务器端初始化

服务器端总的入口为GremlinServer, 总的来说是一个NettyServer, 处理逻辑在WebSocketChannelizerOpExecutorHandler中.

3.2 处理请求

处理入口在 OpExecutorHandlerchannelRead0()中, 见下

OpExecutorHandler

查询时候会将Gremlin的算子通过反射翻译成java相应的方法,比如说上面的V()方法会翻译成
org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource.V(java.lang.Object[]) 方法, 具体参可以见:

Gremlin V()算子

完整调用连路为:

GremlinServer--> WebSocketChannelizer --> AbstractChannelizer --> OpExecutorHandler --> op.accept() --> iterateBytecodeTraversal() --> handleIterator() --> itty.hasNext() --> TraverserIterator.hasNext() --> TraverserIterator.fillBulker() --> DefaultTraversal.hasNext() --> AbstractStep.hasNext() --> GraphStep.processNextStart() --> new JanusGraphStep()

V(): JanusGraphStep.executeGraphCentryQuery() --> QueryProcessor.iterator() --> new ResultSetIterator() --> LimitAdjustingIterator.hasNext() --> StandardJanusGraphTx.execute() --> getVertex().iterator() --> ResultSetIterator.nextInterneal()--> LimitAdjustingIterator.hasNext() --> AbstractIterator.hasNext() --> AbstractIterator.computeNext()

has('id', 1): JanusGraphStep.executeGraphCentryQuery() --> GraphCentricQueryBuilder.constructQuery() --> GraphCentricQueryBuilder.constructQueryWithoutProfile() --> ConditionUtil.traversal()

其中constructQueryWithoutProfile返回的结果为:

constructQueryWithoutProfile 返回结果

最后会调用
QueryProcessor.iterator() --> QueryProcessor.getUnfoldedIterator()--> QueryProcessor.getFilterIterator() --> GraphCentricQuery.matches()

has算子
这个就是对has('id', 1) 的查询解析

初步看: JanusGraph通过多次调用stepInstruction来计算相应的结果,中间多次用到Iterator, CompletableFuture等结构,需要格外注意。

其中关于查询存储部分跳过去了,后面有时间会进一步对以上及查询存储进行说明。

相关文章

网友评论

      本文标题:JanusGraph 查询步骤简要分析

      本文链接:https://www.haomeiwen.com/subject/cfscuctx.html