我们要做的第一件事是使用 ssh 从 2,000 多个服务器获取简单信息,但我希望这在 30 秒内完成。
GNU Parallel 和 Python paramiko+multiprocessing 的使用
两者都有一个随机瓶颈,速度减慢。你能解决这个问题吗?内核调优完成了吗?使用的操作系统是 CentOS 7 (Core 24)
添加Python代码
ssh=paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host,username=username,password=password)
stdin, stdout, stderr = ssh.exec_command(command)
outlines=stdout.readlines()
resp=''.join(outlines)
print(resp)
stdin.close()
ssh.close()
except Exception as err:
print(err)
if __name__ == '__main__':
start = time.time()
host = subprocess.check_output("echo 10.0.{{1..26},{51..146}}.{1..100}", shell="True", universal_newlines=True)
list = host.strip().split(" ")
print (list)
pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
pool.map(loadavg, list)
pool.close()
pool.join()
print("time :", time.time() - start)
答案1
答案2
我可以在 20 秒内处理 4000 个主机,在 10 秒内处理 2000 个主机:
killall ssh-agent
sudo sysctl -w net.ipv4.neigh.default.gc_thresh3=30000
sudo sysctl -w net.ipv4.neigh.default.gc_thresh2=20000
sudo sysctl -w net.ipv4.neigh.default.gc_thresh1=10000
cat hosts |
time parallel --lb --roundrobin --pipe -I dummy -N 50 parallel --timeout 4 --retries 10 -j50 --tag ssh -o StrictHostKeyChecking=no root@{} echo {}
这gc_thresh
是必需的,否则你的 arp 表将溢出。这会导致ssh
卡住。
如果你有很多arp -n | grep incomplete
,请尝试:
parallel 'echo 3600000 >' ::: /proc/sys/net/ipv4/neigh/*/base_reachable_time_ms
请注意,这会导致 arp 条目在刷新之前停留 1 小时。
编辑
如果满足以下条件,我可以重现超时:
- 主机直连同一局域网
- arp 缓存未预热
- 有很多并行任务
答案3
您可以考虑采用多点方法。
在两个级别上,让您的初始实例联系 40 个服务器,每个服务器联系 50 个其他服务器并转发结果:每个级别需要在 15 秒内完成。初始请求列出了每个辅助节点负责的节点。
如果您可以处理三个级别,则扇出数会降至 13 x 13 x 13,并且每个级别需要 10 秒,这听起来可行。