我对一个api调用了超过10万次,使用了两个函数,第一个函数是访问api并获取每个主机的sysinfo(dict),第二个函数是访问sysinfo并获取IP地址。我正在寻找一种加速的方法,但以前从未使用过多处理/线程(目前大约需要3个小时)。你知道吗
from multiprocessing import Pool
from multiprocessing.dummy import Pool as ThreadPool
#pool = ThreadPool(4)
p = Pool(5)
#obviously I removed a lot of the code that generates some of these
#variables, but this is the part that slooooows everything down.
def get_sys_info(self, host_id, appliance):
sysinfo = self.hx_request("https://{}:3000//hx/api/v3/hosts/{}/sysinfo"
return sysinfo
def get_ips_from_sysinfo(self, sysinfo):
sysinfo = sysinfo["data"]
network_array = sysinfo.get("networkArray", {})
network_info = network_array.get("networkInfo", [])
ips = []
for ni in network_info:
ip_array = ni.get("ipArray", {})
ip_info = ip_array.get("ipInfo", [])
for i in ip_info:
ips.append(i)
return ips
if __name__ == "__main__":
for i in ids:
sysinfo = rr.get_sys_info(i, appliance)
hostname = sysinfo.get("data", {}).get("hostname")
try:
ips = p.map(rr.get_ips_from_sysinfo(sysinfo))
except Exception as e:
rr.logger.error("Exception on {} -- {}".format(hostname, e))
continue
#Tried calling it here
ips = p.map(rr.get_ips_from_sysinfo(sysinfo))
我必须经历超过100000次这样的api调用,而这确实是减慢一切的部分。你知道吗
我想我已经试过了所有的方法,并且得到了每一个可能的错误。你知道吗
我真的很感激任何形式的帮助。谢谢您!你知道吗
您可以使用线程和队列进行通信,首先将
get_ips_from_sysinfo
作为单个线程启动,以监视和处理将输出存储在output_list
中的任何已完成的sysinfo
,然后启动所有get_sys_info
线程,注意不要用100k线程耗尽内存正如@wwii所评论的,
concurrent.futures
提供了一些便利,您可以帮助您,特别是因为这看起来像一个批处理作业。你知道吗您的性能影响似乎最有可能来自网络调用,因此多线程可能更适合您的用例(here是多处理的比较)。如果没有,您可以在使用相同的api时将池从线程切换到进程。你知道吗
如果方法确实没有像代码中那样使用状态,那么可以通过将方法重构为函数来简化这个示例。你知道吗
如果提取
sysinfo
数据的成本很高,您可以将结果排队,然后将结果反馈给在排队的dict上调用get_ips_from_sysinfo
的ProcessPoolExecutor
。你知道吗不管出于什么原因,我对在多个线程中调用实例方法略知一二,但它似乎是可行的。我用concurrent.futures做了这个玩具的例子-希望它能很好地模拟你的实际情况。这会将4000个实例方法调用提交到一个线程池(最多)500个工作线程。在玩
max_workers
值的时候,我发现执行时间的改进是非常线性的,大约有1000个工人,然后改进率开始下降。你知道吗我没有说明方法调用期间可能抛出的异常,但是文档中的示例非常清楚如何处理。你知道吗
相关问题 更多 >
编程相关推荐