#10349 Metad Leader Changed 问题复议

帖子链接: meta服务心跳失败以及leader changed
现场快照:

问题: 应用程序运行一段时间后,依旧出现以上异常.
如有需要其他信息,请提出.

SessionPool 代码案例:

public class AlephNebulaSessionPool {
    private final int borrowWaitTime;
    private final NebulaPool nebulaPool;
    private final ArrayBlockingQueue<Session> sessionArrayBlockingQueue;

    public AlephNebulaSessionPool(NebulaPool nebulaPool, int maxConnSize, int borrowWaitTime) {
        this.nebulaPool = nebulaPool;
        this.borrowWaitTime = borrowWaitTime;
        this.sessionArrayBlockingQueue = new ArrayBlockingQueue<>(maxConnSize);
    }

    public Session borrow(String userName, String password, boolean reconnect) {
        Session session;
        // if not supported reconnect, skip borrow session from queue.
        if (!reconnect) return newSession(userName, password, reconnect);
        if (sessionArrayBlockingQueue.isEmpty()) return newSession(userName, password, reconnect);

        try {
            session = sessionArrayBlockingQueue.poll(borrowWaitTime, TimeUnit.MILLISECONDS);
            // if session exists, then inspect the session whether it has been released by idle timeout.
            // if not then return the session, otherwise release the unused session, and create a new session or not polling from queue.
            if (session != null) {
                if (session.ping()) return session;
                session.release();
            }
            return newSession(userName, password, reconnect);
        } catch (InterruptedException e) {
            return newSession(userName, password, reconnect);
        }
    }

    public void release(Session session) {
        if (session == null) return;
        // inspect the session valid in stern.
        if (!session.ping()) return;
        boolean offered = sessionArrayBlockingQueue.offer(session);
        // if overflow the session queue capacity, deprecated it.
        if (!offered) session.release();
    }

    Session newSession(String userName, String password, boolean reconnect) {
        try {
            return nebulaPool.getSession(userName, password, reconnect);
        } catch (NotValidConnectionException | AuthFailedException | ClientServerIncompatibleException | IOErrorException e) {
            throw new AlephSessionException("Error opening session. Cause: " + e.getMessage(), e);
        }
    }
}
1 个赞

SessionPool的实现,借鉴以下案例
nebula-java Add persistence connection by DoubleBabylol · Pull Request #460 · vesoft-inc/nebula-java · GitHub
ngbatis ngbatis/IntervalCheckSessionDispatcher.java at master · nebula-contrib/ngbatis · GitHub

可以一个线程就只使用一个 session 试试?

业务应用执行程序逻辑(使用Session) 不会出现线程安全问题
从SessionPool 获取Session对象到释放期间,没有并行的逻辑,不存在session于线程间传递的行为.

你给出的这个方案实际上是在解决什么问题?

目前metad服务控制为单节点部署,没再出现过问题.
单节点都能cover住这个场景,为什么部署多个metad节点会存在以上问题?

对于方案部署的推荐,metad服务部署为单节点会有什么隐患?

1 个赞

@SuperYoko 求助,帮忙看看 bofa 同学的问题哈,也是一直 meta leader changed。

@bofa1ex 可以贴一下 metad 的 log 么?

metad 具体什么日志?DEBUG还是INFO, 还需要其他信息么?

INFO及以上就好, 主要是nebula-metad.INFO这里面的(当然也可能归档成带时间的了

单节点meta数据可靠性更容易出问题,比如硬盘损坏
再就是一个meta的话,节点挂了,服务很快就不可用了。3节点还能有节点来支持meta服务。

这个能理解,因为leader changed没有解决方案,所以被迫先采取metad单节点的部署方案, 这并不是最佳的部署方案.

目前线上环境不方便提供,近期会在测试环境复现后,后续会提供信息哈…

2 个赞

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