本文介绍使用SDK时,在指定场景下可以使用的解决方法,帮助您实现符合您期望的操作结果。

脚本参数化

相同的请求,仅仅是传递的参数不同,这时推荐使用模板化的方式访问实例。具体内容,请参见参数模板化,一个请求语句中模板化参数的个数不要超过128个。

请求设置超时

图数据库GDB的默认超时时间为30s, 如果您有耗时请求,需要设置较高的超时时间,请参见超时时间设置

SDK参数配置指南

hosts: [ ${gdbHost} ]
port: 8182
username: ${username}
password: ${password}
connectionPool: {  
  maxSize: 16,  
  minSize: 16,  
  maxInProcessPerConnection: 4,  
  maxContentLength: ${yourExpectedSize}
}
serializer: {  
  className: org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1,
  config: { serializeResultToString: false }
}
说明
  • ${gdbHost}:GDB的连接地址,例如gds-bp*******************.graphdb.rds.aliyuncs.com

  • ${username}:实例账号。

  • ${password}:实例密码。

  • ${yourExpectedSize}: 默认为65536,如果您的结果集过大,有可能会遇到Max frame length of 65536 has been exceeded 该类问题,根据业务调整该值大小便可解决该问题。

  • maxSizeminSize:客户端具有链接池,一个客户端支持多线程并发访问,需要把这两个参数设置成一样,且大于等于您的客户端线程访问数,这样也能避免Timed out while waiting for an available host 错误。

  • 序列化协议(尽量使用GraphBinaryMessageSerializerV1序列化协议):

    • GraphBinaryMessageSerializerV1序列化协议:返回的Vertex、Edge为ReferenceVertex,ReferenceEdge,序列化时不会返回properties。性能好。

    • GraphSONMessageSerializerV3d0序列化协议:返回的 Vertex、Edge为DetachedVertex,DetachedEdge,序列化时会返回所有的properties,因此在Vertex可能存在大量properties时,会增加很多额外的序列化开销。

仅获取您需要的结果

根据业务进行判断,在查询时仅获取您需要的结果,不要获取多余结果,以获取更高的性能。

  • 建议请求:

    g.V('id').valueMap('name') // 该dsl仅获取name属性
  • 普通请求:

    g.V('id').valueMap() // 该dsl会获取该点的所有属性

请求后务必主动拿结果

在客户端提交请求后,服务端会将处理结果放在队列中,需要客户端主动拿结果。

ResultSet results = client.submit(dsl,parameters); //执行该步骤后,务必主动拿结果
List<Result> result = results.all().join(); //主动获取结果

属性长度限制

图数据库GDB支持简单的Java基础类型,即使为String类型的最大长度限制为64k, 且建议您存在GDB中的属性不应过长。

批量获取结果

如果您需要获取大量数据,您可以限制每次返回的包大小,避免出错。

示例如下:

ResultSet results = client[Integer.parseInt(threadIndex) % num].submitAsync(dsl, options.create()).get(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
List<Result> list = new LinkedList<>();

while (true) {
    CompletableFuture<List<Result>> batch = results.some(1024);
    List<Result> tmpList = batch.get(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
    if (tmpList == null || tmpList.isEmpty()) {
        break;
    }
    /* 分批取回需要的数据 */
    list.addAll(tmpList);
}

结果集转换

如果您需要将图数据库GDB的返回结果转化为SDK可以使用的对象,您可以转换结果集。

示例如下:

 List<Result> results = client.submitAsync("userTest", dsl, parameters);

            System.out.println("before-output-detail -  " + dsl + " list size - " + results.size() + " useTimeMillis - " + String.valueOf(System.currentTimeMillis() - start));
            results.forEach(result -> {
                if (result.getObject() instanceof ReferenceVertex) {
                    ReferenceVertex vertex = (ReferenceVertex) result.getObject();
                    System.out.println("ReferenceVertex id - " + vertex.id() + " label - " + vertex.label() + " properties - ");
                    vertex.properties().forEachRemaining(p -> System.out.println(p));
                } else if (result.getObject() instanceof DetachedVertex) {
                    System.out.println("DetachedVertex id - " + result.getVertex().id() + " label - " + result.getVertex().label() + " properties - ");
                    result.getVertex().properties().forEachRemaining(p -> System.out.println(p));
                } else {
                    System.out.println("DefaultResult - " + result);
                }
            });