讨论关于metad服务的存储做成多分片的可行性

现在nebula-metad服务是1space1分片的存储,在session的读写上操作上是有一个读写锁阻塞着的。有时候业务场景上可能会有高并发的瞬时session读写操作,因为写锁的持有,请求时延会变得非常高。

可能不止session的读写操作,我理解meta service的读写是单part的,对于所有元信息的并发读写操作在高并发场景下应该都会有时延上涨的现象。

所以我在想是否可以把metad的存储服务做成和nebula-storaged一样的多分片?但是考虑到现在的存储架构,不知道做成多分片会有哪些风险?之前做成单独一个分片的存储是有什么原因吗?

绝大多数的延时问题都是出在session上的。有一个黑科技,把SessionManager里面的相关锁全部删掉,这样基本就可以解决session导致meta慢、假死等等(目前版本session可能会导致meta出现各种问题,但已经积重难返)。

meta只有单分片的核心原因就是nebula目前只能保证一个分片内的读写是原子的,如果做成多分片,数据一致性难以保证,不建议修改。

1 个赞

把SessionManager里面的相关锁全部删掉,应该也只是在graph层解决锁的问题,但是在metad服务层依然还是会有同样问题。

做成多个分片,数据一致性不能通过raft协议来保证吗?不过我想到另外一个问题就是如何去hash到不同分片上,比如同一个用户在同一个ip同一个graphd客户端发起多个create session的请求,确实没法hash到不同分片上,做成多分片也无济于事

sorry 我表述有误 src/meta/processors/session/SessionManagerProcessor.cpp 里面所有Processor的锁删掉

嗯,看了下这个问题里都是LockUtils::sessionLock(),这个类型的锁,不过我还是有点疑问,都去掉的话会有线程安全问题吗?如果可以都去掉为什么现在的代码不去掉呢?出于线程安全的原因还是其他原因考虑

我试了将SessionManager里的锁都去掉后,确实没什么问题,时延也正常。所以为什么社区代码不把这部分的锁去掉呢?包括metad service里面其他算子的处理函数里用的LockUtils的其他锁,应该也都是可以去掉的,因为最终的读写还是要交给NebulaStorae来处理,由NebulaStorae来保证线程安全就可以?

我记不太清session的设计上有什么问题了,最终实现就变成了在meta保存一份session(进而导致各种问题)。加锁可能是因为session id就是一个时间戳的缘故,容易冲突,但从我理解来说加锁意义并不大,因为我们对session的线程安全要求并不高。

啊 我看到你PR了 还没来得及看(理论上 就算不换成AtomicOp问题也不大 只用把锁删了)。Session部分删掉锁之前简单测试过,但是没有完整测,所以就一直没有管。

昨天和我们的SE讨论了下你们之前的session 锁存在的意义,我们分析了下这个锁的逻辑应该还是有存在的必要,不过可以换成AtomicOp。理由是,像create session中有用到读userExist,也就是依赖读操作,这整个函数中的读写操作应该是原子的,才能确接口保逻辑上严谨性,也就是用户存在才能创建session。同理其他函数里也是有依赖读的操作