nebula-java和nebula-jdbc获取session的问题

提问参考模版:

  • nebula 版本:2.5.1
  • nebula-java版本 :2.5.0
  • 部署方式:分布式
  • 安装方式:RPM
  • 是否为线上版本: N
  • 硬件信息
    • 磁盘:200G SSD
    • CPU、内存信息:8核16G
  • 问题的具体描述:
    目前基于java语言使用nebula-jdbc开发后端服务系统,遇到了如下几个问题:
    1、在nebula-java客户端代码中,java代码获取nsid(即sessionId),只能通过SyncConnection吗?NebulaDriver和Connection都获取不到sessionId。获取sessionId的示例:
    SyncConnection connection = new SyncConnection();
    connection.open(new HostAddress(“127.0.0.1”,“9669”), 1000);
    AuthResult authResult = connection.authenticate(req.getUsername(), req.getPassword());
    String nsid = String.valueOf(authResult.getSessionId());

2、做java服务端开发,首次获取到nsid(sessionId)后,需要自己保存维护吧?后续调用其它接口(如gql查询execute接口)需要带上nsid查询,避免每次都重新获取数据库连接。但是目前看client源码,只有SyncConnection的执行方法有通过sessionID查询的方案,其它像Connection查询方法没有通过sessionID查询方法,都是每次要重新获取数据库连接。

3、是否有java语言使用nebula-jdbc(或nebula-java)开发的系统平台demo,可供参考学习?

PS:目前nebula-jdbc只支持nebula-java的2.5.0版本,没有开发client对应的升级版本。希望jdbc能尽快开发出对应新版本,谢谢!

因为 nebula-jdbc 是 @Flash 贡献维护的,他最近有点忙碌。早上和他沟通了版本升级的问题,他会空了升级下 nebula-jdbc 的。

开源之夏项目分享:图数据库 Nebula Graph 支持 JDBC 协议 这篇文章你也找到了,不知道是否解决了你的问题呢?可以留言和 Flash 交流下~

针对第1个和第2个问题:
你是希望在自己服务端始终维护着这个session 不释放么, 你可以不用使用Session 内部的sessionId的,它是用来和服务端进行session 对应的。
你可以自己获取session后通过一个uuid来唯一标识该session,通过uuid获取已经创建好的session对象,这种使用方式类似 studio 的后端服务 ,可以参考代码: https://github.com/vesoft-inc/nebula-http-gateway/blob/f7f5b4c63e6a0ab73a539378ca838b5172e8d25b/ccore/nebula/gateway/pool/pool.go#L210

1 个赞

我需要获取的sessionId是这里面首次与nebula建立连接口响应的nsid的意思,在获取数据库连接connect的时候得到数据库的一个会话连接,后面每次操作执行gql不用重新获取连接了,断开的时候调用接口将sessionId失效。studio中代码如下:
获取连接connect:
info, err := dao.Connect(params.Address, params.Port, params.Username, params.Password)
nsid := info.ClientID

执行查询execute:
result, msg, err := dao.Execute(nsid.(string), params.Gql, params.ParamList)
断开连接disconnect:
dao.Disconnect(nsid.(string))

你直接用NebulaPool 去getSession获取session后,只要不release 该session 就可以满足你的“得到数据库的一个会话连接,后面每次操作执行gql不用重新获取连接”的需求呀。

等你需要断开该session时,直接session.release就好了。

谢谢老师指点,获取维护Session(com.vesoft.nebula.client.graph.net.Session)的方法理论上是通的,但是在保存Session对象的时候有问题,目前client中Session没有实现Serializable,里面有多个对象(SyncConnection、NebulaPool)也没有,所以无法保存序列化下来(临时存到内存redis或数据库中)供下次查找使用。麻烦老师再帮忙看下~

保存维护的SessionBo字段信息:

public class SessionBo implements Serializable {
    @ApiModelProperty(value = "IP地址")
    private String address;
    @ApiModelProperty(value = "数据库端口")
    private Integer port = 9669;
    @ApiModelProperty(value = "数据库用户名")
    private String username;
    @ApiModelProperty(value = "自己生成维护的sessionId")
    private String nsid;
    @ApiModelProperty(value = "graph获取的session")
    private Session session;
}

保存成功后,读取会报错:

org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `com.vesoft.nebula.client.graph.net.Session` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
 at [Source: (byte[])"{"@class":"com.graph.common.param.resp.SessionBo","address":"172.21.18.181","port":9669,"username":"root","nsid":"ve_3de4ecf53cff4f3fb255ee9dffdc5d85","session":{"@class":"com.vesoft.nebula.client.graph.net.Session","graphHost":{"@class":"com.vesoft.nebula.client.graph.data.HostAddress","host":"172.21.18.181","port":9669}}}"; line: 1, column: 225] (through reference chain: com.graph.common.param.resp.SessionBo["session"]); nested exception is com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.vesoft.nebula.client.graph.net.Session` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

是的,客户端的Session是没有序列化,所以在分布式系统中使用起来时就存在无法序列化的问题。像目前spark connector和flink connector 在使用pool时也是在每个worker节点上单独初始化连接池单独获取Session的。

我提一个issue 看下在后续版本中处理一下。

谢谢老师,麻烦尽快升级下吧。目前有什么解决方案建议吗?

方案就是上面提到的connector中的使用方式,但这个只能做到在每个worker内部复用session。

请教一下,studio中Cookie的这个nsid跟nebula-java中对应的应该是sessionId吧?就是java-client直接提交到graph数据库中的标识:

public ExecutionResponse execute(long sessionId, byte[] stmt)

不是,这是自己生成的uuid,在studio的后端服务中用来标识session的

请问下java-client中是否有类似gateway中获取ValueWrapper的值的通用方法(不知道value类型)?
函数代码如下(func getBasicValue(valWarp *nebula.ValueWrapper) (common.Any, error)):
https://github.com/vesoft-inc/nebula-http-gateway/blob/993ec26095cb7212e2d0a4fbc5d7e2d837aeeb0f/ccore/nebula/gateway/dao/dao.go#L41

有的 https://github.com/vesoft-inc/nebula-java/blob/453064dc22161ee47a14b2e30868dc2121eb3a27/client/src/main/java/com/vesoft/nebula/client/graph/data/ResultSet.java

1 个赞

这个文章有介绍一点 wrapper value的部份 Nebula Graph 的 Java 数据解析实践与指导 - siwei.io

1 个赞

此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。