Web抓取性能问题EC2与家用PC

时间:2019-06-24 09:57:00

标签: python performance amazon-web-services amazon-ec2 web-scraping

我用Python编写了一个网页抓取工具,该抓取工具在家里的笔记本电脑上都能很好地工作。将其部署到AWS EC2后,刮板的性能会下降。现在,我对EC2实例(甚至是小型实例和小型实例,请参阅下面的更多详细信息)的性能感到困惑。

python中的刮板: 通常,刮擦的内部循环执行以下操作: (1)刮板在一个站点上查找URL(每个站点20个,一个站点=一个“ site_break”)。在第二步中,它(2)获得每个URL的源代码,在第三步中,它(3)将必要的信息提取到数据帧中,在第四步中,它(4)将数据帧另存为pkl。 在所有循环之后,它将打开并合并数据帧,并将其另存为csv。

关键(最耗时的部分)是: (2)源代码的下载(I / O受下载速度的限制):程序将源代码填充到RAM中 (3)处理源代码(CPU 100%)

要充分利用RAM并将类似的过程结合在一起,每个循环都由site_break = 100组成,即100个站点* 20个网址/ site = 2000个网址。这将PC的RAM填充到96%(请参阅下文)。由于我必须在步骤1和步骤2中等待服务器响应,因此我实现了maxWorkers = 15的线程化(或者20-35,结果类似)。此实现将运行时间减少了80%。我相信我可以通过实现asyncio来获得其他的。%。不过,我想从精益MVP开始。在消耗处理器的第3步中,我尚未实现多处理(因为)是因为我的目标是在t2.micro上(只有一个处理器)实现具有成本效益/免费的实现。

规格: 家用PC:Intel Core i7-6500 CPU,2.59 Ghz(2个内核,4个逻辑处理器),RAM 8.00 GiB,64位,x64、50Mbit / s下载速率(有效高达45 Mbit / s),Python 3.7。 3,conda env

EC2 t2.micro:vCPUs = 1,RAM 1.0 GiB,网络性能“低到中等”(论坛上的研究告诉我,这可能超过50 Mbit),Ubuntu 18.04,Python 3.7.3,conda env

EC2 t3a.small:vCPUs = 2,RAM 2.0 GiB,网络性能“低至中等”,但是另一个AWS站点告诉我:“高达5 Gbit / s”,Ubuntu 18.04,Python 3.7.3,conda env < / p>

由于t2.micro的RAM仅为1 GiB,因此我将site_break从100降低到25。此后,RAM仍然已满,因此我将其从25减少到15、12、10,最后5.对于12、10尤其是5,它工作得很好: 我需要5:30分钟才能在PC上使用site_break = 100进行循环。 t2.micro需要site_break = 5的8-10sec,这导致大约100个站点的3:00min,这让我第一时间感到满意。 不幸的是,出现以下问题:20-30次循环后性能下降。循环时间从8秒迅速增加到2分钟以上。我的第一个假设是它是低内存,在小循环中它似乎并没有装满。停止并清洁RAM后,第二或第三次循环后性能会下降。如果几个小时后重新启动,第一种情况(在20-30次循环后下降)会重复。

因为我首先认为它与RAM有关,所以我在t3a.small上启动了第二个实例,该实例具有更多的CPU,RAM和“高达5 Gbit / a”的网络性能。我切分看起来为site_break = 25并启动脚本。我仍然以每个循环1:39-1:55min的恒定速度运行(在最佳阶段(t5为10秒= 5 => 50秒),速度是t2.micro的一半。 并行地,我从家用PC上以site_break = 25启动了脚本,并且每个循环以1:15-1:30min的速度不断提高。 (手动停止时间会导致下载速度降低10-15秒,处理速度降低10-15秒)。 这一切使我感到困惑。

现在我的问题是: 1.为什么t2.micro detetoriate经过数次循环后,为什么性能变化如此之大? 2.为什么t3a.small比t2.micro慢50%?我认为无论如何,“更大”的机器都会更快。

这让我陷入困境:

  1. 不想定期使用我的家用PC(每天抓取),因为该连接在凌晨4点中断一小段时间,并导致脚本挂起)。而且,我不希望脚本一直手动运行,也不希望PC一直运行并阻止我的私人Internet流。

  2. t2.micro:没有用,因为劣化后的性能无法接受。

  3. t3a.small:性能比私人PC低10-20%。我希望它会更好吗?这让我怀疑是否要放弃EC2。而且,与一开始的t2.micro相比,我无法理解其性能较低。

2 个答案:

答案 0 :(得分:0)

经过一些测试,我可以得出令人满意的解决方案:

  1. 实例从t3a.small切换到t3.small的性能提高了约40%,甚至比我的家用PC快10-20%。感谢@kdgregory
  2. 我通过将asyncio与多处理而不是多线程结合使用来改进了我的代码。这不仅可以提高速度,还可以提高内存利用率。而且,我摆脱了使用bs4.BeautifulSoup(Python high memory usage with BeautifulSoup)之后仍然存在的标记。通过最后的改进,我可以防止运行时内存增加。
  3. 长时间编程后,内存低于以前。我发现我犯了一个初学者的错误:https://www.linuxatemyram.com/幸运的是,这不是问题。

现在,该代码甚至比家用PC上的代码还要快,并且可以自动运行。

答案 1 :(得分:0)

  1. 为什么t2.micro detetoriate经过几次循环后,为什么性能变化如此之大?

如果您的RAM尚未满,则很可能是因为Amazon限制了您实例消耗的资源,无论是CPU还是I / O。亚马逊会在一段时间内为您提供更多的计算量和吞吐量(以适应任何短期的峰值),但您不应将其误认为基准性能。

  1. 为什么t3a.small比t2.micro慢50%?我认为无论如何,“更大”的机器都会更快。

T3实例是为CPU使用率适中,使用时会出现临时性峰值的应用程序而设计的。使用t3时,您要么付出了溢价才能承受更大和更频繁的尖峰,要么却获得了更低的基准性能(对于相同的价格),从而能够承受更大和更频繁的尖峰。这与您想要恒定的CPU和I / O的网络抓取配置文件不匹配。