Star

关于graphd和storage的线程模型

我们发现当查询大量数据时, (比如一个请求返回200万数据), 会使写入性能大大降低, 虽然我们部署了3台机器, 3个graphd, 读取时控制了最多8个并发, 写入128, 但是写入时仍然会被卡住很久, 这时候如果把读取并发关掉, 写入性能马上就提上来了

请问, graphd 执行的线程模型是什么样的? 一个graphd 核心最多能支持多少并发工作? 和storage 通讯是单线程还是多线程? storage 的读写最多支持多少并发? 当写入时, 有锁吗? 这个锁的粒度与什么有关?

另外, 按照官方的推荐配置, 我们是否可以通过在一台机器上部署多个graphd(比如部署3个graphd) 来提高吞吐量?

谢谢!

你看过dstat IO CPU 和NETWORK吗?graphd 和storaged CPU分别是多少
— 你确定是定位到 bound 在 graphd的CPU上?

你要多加几个graphd是可以的,这也是分离设计的初衷

如果你觉得是graphd 的问题的话,可以多启动几个graphd进程。 graphd是无状态的,相互之间也没有通信(记得检查下它的配置文件,连接到正确的meta和storage就行)。
然后,不同类型的应用向不同的GraphD进程发请求。 也可以这样对比看看。

graphd 的线程模型可以理解成一个大的线程池,所有 query 的任务都是丢入这个线程池,通过异步的方式来执行并返回结果。

graphd 最大能支持的并发数取决于你为其配置的最大线程数,即上述线程池的大小,如果不设置(默认0)则使用 cpu 核心数。

graphd 和 storaged 的通信是通过 thrift 的 RPC 来实现,是使用的单线程还是多线程取决于当前 query touch 到的 partition 数量,如果是涉及到多个 partition,那么 graphd 在向 storaged 请求数据时,会同时向对应 partition 的 leader 发送请求,并汇总结果给前端。

storaged 的并发度也是可以通过 gflags 配置的,但是一般不建议直接修改该值。现在每个 partition 的数据只能通过 leader 读取和写入,所以在 storaged 这边没有加锁,而是通过排队的方式来处理所有的请求。

上面你的一个 query 的返回结果很大,怀疑是当前的查询阻塞了后面的写入的请求,因为query请求时间较长,多个相同 query 同时请求就将 storaged 的 worker 线程耗尽,阻塞了后面的所有请求。

现在 storaged 还没有完成资源隔离的实现,后面会提供更好的优化策略,感谢您的反馈。

1赞

谢谢

浙ICP备20010487号