美文网首页
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