我需要使用 Expect 脚本在 700 个网络设备上完成一些工作。我可以按顺序完成它,但到目前为止运行时间约为 24 小时。这主要是由于建立连接所需的时间以及这些设备(旧设备)的输出延迟造成的。我能够建立两个连接并让它们并行运行,但是我能将其推进多远?
我不认为我可以同时完成所有 700 个任务,当然,“不”是有一定限制的。我的虚拟机可以管理的 telnet 连接数。
如果我确实尝试以某种循环方式启动其中的 700 个,如下所示:
for node in `ls ~/sagLogs/`; do
foo &
done
和
CPU 12 个 CPU x Intel(R) Xeon(R) CPU E5649 @ 2.53GHz
内存 47.94 GB
我的问题是:
- 所有 700 个实例是否可以同时运行?
- 在我的服务器达到极限之前我能走多远?
- 当达到该限制时,它会等待开始下一次迭代
foo
还是会崩溃?
不幸的是,我正在企业生产环境中运行,所以我不能完全尝试看看会发生什么。
答案1
所有 700 个实例是否可以同时运行?
这取决于你所说的同时是什么意思。如果我们很挑剔,那么不,他们不能,除非您的系统上有 700 个可以利用的执行线程(所以可能不会)。但实际上,是的,只要系统上有足够的 RAM 和/或交换空间,它们可能就可以。 UNIX 及其各种子系统非常擅长管理大量并发,这也是它们在大规模 HPC 使用中如此受欢迎的部分原因。
在我的服务器达到极限之前我能走多远?
如果没有更多信息,这是不可能具体回答的。差不多,你需要有足够的内存来满足:
- 一项作业的整个运行时内存需求,700倍。
- bash 管理这么多作业所需的内存(bash 在这方面并不可怕,但作业控制并不完全高效)。
- 系统上的任何其他内存要求。
假设你满足这个要求(同样,只有 50GB RAM,你仍然必须处理其他问题:
- bash 在作业控制上会浪费多少 CPU 时间?可能不多,但对于数百个工作岗位来说,这可能是很重要的。
- 这需要多少网络带宽?仅打开所有这些连接可能会淹没您的网络几分钟,具体取决于您的带宽和延迟。
- 还有很多事情我可能没有想到。
当达到该限制时,它会等待开始 foo 的下一次迭代还是会崩溃?
这取决于达到什么限制。如果是内存,系统上的某些东西将会死掉(更具体地说,在尝试释放内存时被内核杀死),或者系统本身可能会崩溃(将系统配置为在内存不足时故意崩溃并不罕见)。如果是 CPU 时间,它会继续运行而不会出现问题,只是不可能在系统上执行其他操作。如果是网络问题,你可能会崩溃其他系统或服务。
你什么真的这里需要的是不要同时运行所有作业。相反,将它们分成批次,并同时运行批次内的所有作业,让它们完成,然后开始下一个批次。 GNU 并行 (https://www.gnu.org/software/parallel/)可以用于此目的,但在生产环境中在这种规模上它不太理想(如果你使用它,不要太激进,就像我说的,你可能会淹没网络并影响你本来不会的系统接触)。我真的建议研究一个合适的网络编排工具,比如 Ansible (https://www.ansible.com/),因为这不仅会解决您的并发问题(Ansible 会自动执行我上面提到的批处理),而且还会为您提供许多其他有用的功能(例如任务的幂等执行、良好的状态报告以及与大量其他工具)。
答案2
很难具体说明有多少实例可以按照您描述的方式作为后台作业运行。但正常的服务器只要操作得当,肯定可以维持700个并发连接。网络服务器一直在这样做。
我可以建议你使用 GNU 并行(https://www.gnu.org/software/parallel/)或类似的东西来完成这个?它会给您带来后台作业方法的许多优势:
- 您可以轻松更改并发会话数。
- 它会等到会话完成后才开始新的会话。
- 这样更容易流产。
请看这里以快速开始:https://www.gnu.org/software/parallel/parallel_tutorial.html#A-single-input-source
答案3
&
当进行一些操作以及监控进度时,使用并行处理是很好的。但如果您在企业生产环境中运行,您需要一些可以让您更好控制的东西。
ls ~/sagLogs/ | parallel --delay 0.5 --memfree 1G -j0 --joblog my.log --retries 10 foo {}
这foo
将为 中的每个文件运行~/sagLogs
。它每 0.5 秒启动一个作业,只要 1 GB RAM 空闲,它就会并行运行尽可能多的作业,但会尊重系统的限制(例如文件和进程的数量)。通常,这意味着如果您没有调整允许的打开文件数,您将并行运行 250 个作业。如果你调整打开文件的数量,并行运行 32000 个应该没有问题——只要你有足够的内存。
如果作业失败(即返回错误代码),它将重试 10 次。
my.log
会告诉您作业是否成功(可能重试后)。
答案4
如果我启动太多后台作业会怎样?
系统将变得缓慢且反应迟钝,最坏的情况是反应迟钝,最好只是按下电源按钮并进行硬重启...这将以 root 身份运行某些东西,它有特权逃脱这样做。如果您的 bash 脚本在常规用户权限下运行,那么首先想到的是/etc/security/limits.conf
and/etc/systemd/system.conf
以及其中的所有变量[理想情况下]防止 用户来自超载系统。
cpu = xeon E5649,即 12-核中央处理器;因此,您有 12 个内核,可同时运行 12 个进程,每个进程都以 100% 的速度利用 12 个内核中的一个。如果您启动 24 个进程,那么每个进程都会在 12 个核心上以 50% 的利用率运行,700 个进程 = 1.7%,但它是一台计算机,只要一切都在适当的时间内正确完成,那就 = 成功;高效并不总是重要的。
所有 700 个实例是否可以同时运行? 当然,700并不是一个大数字;
maxproc
例如,我的 /etc/security/limits.conf默认值为 4,135,275在我的服务器达到极限之前我能走多远? 我确信比700远得多。
限制...如果脚本在以下情况下启动会发生什么用户帐户 [通常 root 也
limits.conf
几乎适用于所有人] 是脚本将在尝试执行foo &
700 次后退出;你会期望看到 700富每个进程都有不同的 pid,但您可能只会看到 456(随机数选择),而其他 244 个从未启动,因为它们被某些安全或 systemd 限制阻止。
百万美元问题:你应该同时运行多少个?
参与网络你说每个都会进行 telnet 连接,有根据的猜测是,在进行 cpu 和 ram 限制之前,你会遇到网络限制和开销。但我不知道你具体在做什么,可能会发生的情况是你可以一次启动所有 700 个,但事情会自动阻塞,直到之前的进程和网络连接完成并根据各种系统限制或类似的情况关闭前 500 个将启动,然后剩余的 200 个将不会启动,因为系统或内核限制阻止了它。但无论有多少个同时运行,总会有一些甜甜的尽快完成工作...最大限度地减少开销并提高效率。如果是 12 个核心(如果有 2 个 cpu,则为 24 个核心),然后立即从 12 个(或 24 个)开始,然后将并发批处理数增加 12 或 24,直到看不到运行时间改进。
暗示:谷歌最大 telnet 连接数并了解这如何适用于您的系统。另外不要忘记防火墙。还可以快速计算每个进程所需的内存 x 700;确保 < 可用 RAM(在您的情况下约为 50GB),否则系统将开始使用 SWAP 并基本上变得无响应。所以12、24的踢,氮一次处理并监控 RAM 空闲情况,然后增加氮已经对正在发生的事情有了一些了解。
默认情况下,RHEL 将单个主机的 telnet 连接数量限制为 10 个并发会话。这是一项安全功能...设置为 10,/etc/xinetd.conf,更改“per_source”值。