使用Python多线程在Nebula中查询

  • nebula 版本:2.0.1
  • 部署方式:分布式
  • 安装方式:RPM
  • 硬件信息
    • 硬盘 1T x 3
    • CPU 16C x 3
    • 内存 128G x 3

我需要使用python对nebula进行多次的查询,由于单次查询速度较慢,这里准备使用多线程进行查询,不过当前所使用threadpool方式并没有比单纯的循环方法快出多少,请问有没有正确使用nebula进行多线程查询的方法?

Python代码:

from concurrent.futures import ThreadPoolExecutor
from concurrent import futures
from graph import NebulaGraph  # a class of nebula graph

class testclass:

    def nebula_lookup_func(self, attribute):
        nebula = NebulaGraph.graph
        nebula_session = nebula.start_session()
        nebula_session.execute("USE graph_space_name")

        res = nebula_session.execute("LOOKUP ON {}".format(attribute))
        nebula_session.release()
        return res

    def nebula_multithread_func(self):
        res_store = []
        attri_list = ["tag1", "tag2"]
        with ThreadPoolExecutor(200) as executor:
            jobs = []
            results = []
            for attribute in attri_list:
                jobs.append(executor.submit(self.nebula_lookup_func, testclass, attribute))
            for job in futures.as_completed(jobs):
                result_done = job.result()
                results.append(result_done)
            for result in results:
                res_store.append(result)
        return res_store

python 客户端从网络中解码是比较耗 CPU 的,如果你 lookup 的数据比较大,加上 python 里的 GIL,即便是多线程,其实也没有快很多。
你可以看一下运行过程中,是不是单核已经跑满了。
另外就是网络传输是共用的,看一下是不是因为数据量大,瓶颈在网络上。

改善的话:

  1. 看一下是什么业务,是不是可以放 nGQL 里,比如 count 或者其他。只看语句的话,这个是扫全表了。
  2. 语句上加 limit, where
  3. 多进程。(如果瓶颈在网络上,提升不明显)
3 个赞

你好,感谢回复。

这边试了一下,在运行多线程的代码时CPU的核都是没有跑满的,并且在更换为更简单的函数后也可以并发地去运行。

在运行中有一个现象让人有些疑惑,如果在nebula_lookup_func中加入一个打印当前线程一开始的代码,那么在开始运行后所有线程的代码几乎都是同时出现的,但是get_session()语句返回的信息却不是这样的,而是一段一段地出现。

我们怀疑这或许和nebula graph本身是network配置有关,着重更改了:
num_accept_threads
num_netio_threads
num_worker_threads
的参数,但是效果并没有任何区别。

这里想问一下这三个参数分别控制的是什么,更改他们对多线程或多进程是否有实质性的帮助,以及nebula中对多线程地 get_session() 是否有限制?

三个参数可以参考 num_accept_threads参数的含义 - #5,来自 dingding
nebula 客户端的连接池是线程安全的, 可以多线程调用get_session()

3 个赞

感谢回复,我在python中尝试多线程调用session后,速度并没有提升,请问nebula是否支持使用python进行多线程的查询?官方有没有类似的代码示范可以参考一下呢?

不支持多个线程使用同一个 session, 可以用多个线程, 每个线程持有一个 session 做查询, load balancer 会把请求分发到多个 graph 服务中, 增加 graph 的吞吐, 但是查询速度不会有太大变化的

我们当前的方案就是在多个线程使用不同的session进行查询,但是这样所消耗的时间和使用一个线程一个session遍历全部的query是相近的,上面所说的 “查询速度不会有太大变化” 指的是单个query还是完成全部query的速度呢?

单个query查询速度不会改变, 多个query的话要看瓶颈在哪的

我们当前就是认为瓶颈出在并发查询上,因为当我们线程内的函数不包含查询的语句时就能够做到多线程查询,一旦加上查询的语句后就慢了下来,并且按照github上给出的示例编写后也没有改进。