本文介绍使用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
该类问题,根据业务调整该值大小便可解决该问题。maxSize
与minSize
:客户端具有链接池,一个客户端支持多线程并发访问,需要把这两个参数设置成一样,且大于等于您的客户端线程访问数,这样也能避免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);
}
});