【发布时间】:2011-11-28 23:23:49
【问题描述】:
我有一个 python 脚本,它会发出许多 HTTP 和 urllib 请求到各个域。
我们有大量的域要处理,需要尽快完成。 由于 HTTP 请求很慢(即它们可能会因为域上没有网站而超时),所以我随时运行许多脚本,从数据库中的域列表中提供它们。
我看到的问题是在一段时间内(几小时到 24 小时)脚本都开始变慢,并且 ps -al 显示它们正在休眠。
服务器非常强大(8 核、72GB 内存、6TB Raid 6 等 80MB 2:1 连接)并且永远不会用尽,即Free -m 显示
-/+ buffers/cache: 61157 11337
Swap: 4510 195 4315
热门节目在 80-90% 之间闲置
sar -d 显示平均 5.3% util
更有趣的是,iptraf 开始时的速度约为 50-60MB/s,大约 4 小时后达到 8-10MB/s。
我目前在每台服务器(2 台服务器)上运行大约 500 个版本的脚本,它们都显示相同的问题。
ps -al 显示大多数 python 脚本都在休眠,我不明白为什么
例如:
0 S 0 28668 2987 0 80 0 - 71003 sk_wai pts/2 00:00:03 python
0 S 0 28669 2987 0 80 0 - 71619 inet_s pts/2 00:00:31 python
0 S 0 28670 2987 0 80 0 - 70947 sk_wai pts/2 00:00:07 python
0 S 0 28671 2987 0 80 0 - 71609 poll_s pts/2 00:00:29 python
0 S 0 28672 2987 0 80 0 - 71944 poll_s pts/2 00:00:31 python
0 S 0 28673 2987 0 80 0 - 71606 poll_s pts/2 00:00:26 python
0 S 0 28674 2987 0 80 0 - 71425 poll_s pts/2 00:00:20 python
0 S 0 28675 2987 0 80 0 - 70964 sk_wai pts/2 00:00:01 python
0 S 0 28676 2987 0 80 0 - 71205 inet_s pts/2 00:00:19 python
0 S 0 28677 2987 0 80 0 - 71610 inet_s pts/2 00:00:21 python
0 S 0 28678 2987 0 80 0 - 71491 inet_s pts/2 00:00:22 python
执行的脚本中没有睡眠状态,所以我不明白为什么 ps -al 显示它们中的大多数都处于睡眠状态,以及为什么当 CPU、内存、磁盘访问时,随着时间的推移,它们会变得越来越慢,发出更少的 IP 请求和带宽都可用。
如果有人能帮忙,我将不胜感激。
编辑:
代码量很大,因为我通过它使用异常来捕获有关域的诊断信息,即我无法连接的原因。如果需要,将在某处发布代码,但通过 HTTPLib 和 URLLib 的基本调用直接来自 python 示例。
更多信息:
两者
配额 -u mysql 配额 -u 根
空手而归
nlimit -n 返回 1024 更改 limit.conf 以允许 mysql 允许 16000 个软连接和硬连接,并且到目前为止能够运行超过 2000 个脚本,但问题仍然存在。
一些进展
好的,所以我已经更改了用户的所有限制,确保所有套接字都已关闭(它们没有关闭),尽管情况有所好转,但我的速度仍然慢了下来,尽管没有那么糟糕。
有趣的是,我还注意到一些内存泄漏 - 脚本运行的时间越长,使用的内存就越多,但我不确定是什么原因造成的。 我将输出数据存储在一个字符串中,然后在每次迭代后将其打印到终端,我也会在最后清除字符串,但是不断增加的内存是否可以归结为存储所有输出的终端?
编辑:不似乎没有 - 运行了 30 个脚本而没有输出到终端并且仍然存在相同的泄漏。 我没有使用任何聪明的东西(只是字符串、HTTPlib 和 URLLib)——想知道 python mysql 连接器是否有任何问题......?
【问题讨论】:
-
如果您提供一些代码可能会有所帮助。您如何准确地执行请求?
-
您确定您面临的问题与您的上游互联网连接变差无关吗?
-
不应该这样 - 连接非常稳固,双向 80MB 2:1 - 如果我开始说 500 个脚本,连接将保持在 50MB/s 左右一个小时左右,然后在几个小时内降低到 10MB/s。如果我然后开始另一个说 100,它将增加再次使用 40-50MB,然后在类似的时间段内变慢。 - 所有脚本都没有停止 - 它们似乎只是按照上面的 ps -al 输出进入睡眠状态。
-
lsof 也是一个不错的尝试命令。如果有 1024 个打开的文件,那么您达到了 ulimit 并且您希望进程处于休眠状态。您可以尝试提高 ulimit 并查看性能是否可以保持更长时间。
-
如果你使用一些异步,你可以使用更少(~10)个进程来发出并发请求。框架如twisted、gevent。这里是gevent example、twisted example。
标签: python performance http unix task