如何提高此架构的性能?

时间:2013-11-05 17:57:34

标签: performance web architecture cluster-computing server-side

我正在运行一个由于大量图像缩略图而导致CPU繁重的网站。

这就是我目前的做法:

  1. 用户将图片上传到服务器
  2. 服务器保留副本,并将图像存储在Amazon S3上
  3. 当请求缩略图时,服务器使用本地副本生成它,然后将其存储在S3上;然后将S3 URL提供给客户端
  4. 后续请求的优化如下:服务器在memcached中缓存S3 URL,因此它不会再次执行工作;如果文件存在,服务器永远不会再生成缩略图;服务器使用中等大小的缩略图来生成小尺寸的缩略图,因此不能使用不必要的大文件
  5. 现在,我正在托管一个Linode 4G实例(8个内核,4x优先级,4GB RAM),尽管我的优化程度和memcached命中率为70%,但我的平均CPU为170%。我经常看到所有8个CPU同时处于频繁峰值100%的同时为它们中的许多工作。

    我正在使用nginx和gunicorn来提供Django应用程序,并使用PIL生成缩略图。

    如何改进此架构?

    我在考虑一些可能性:

    #1。最简单:在前面添加第二个相同的服务器和负载均衡器,这样他们就可以共享负载。

    这个问题是两台服务器不共享本地图像缓存。我可以通过在网络驱动器上放置这样的共享来解决这个问题,还是延迟最终会阻碍增益?

    #2。更难一点:将缩略图代码从我的应用程序中分离出来,作为单独的Web服务,可以在第二台服务器上运行。这样,主应用程序和数据库不会受到高CPU使用率的影响,并且网页将快速提供。无论如何,缩略图已经与JavaScript异步提供

    有人可以推荐其他解决方案吗?

2 个答案:

答案 0 :(得分:1)

您确定自己的性能问题来自缩略图吗?好的,我想你已经检查过了。

您可以在用户上传图片后立即(或不久)缩小尺寸并将2张缩略图上传到S3。通过这种方式,您应该能够节省不必要的CPU负载,因为每次HTTP请求都会检查这些缩略图并使用memcached执行IPC。

答案 1 :(得分:0)

在某种程度上,你的问题是一个“好”的问题(或者至少它可能会更糟),因为单独的图像大小调整任务之间没有依赖关系,因此你可以在多个服务器上轻松地分发它们。一些评论:

  1. 您是否检查过是否可以执行任何操作以使图像调整操作更快? (Google提出了这个问题,不知道是否有任何帮助:http://dmmartins.appspot.com/blog/speeding-up-image-resizing-with-python-and-pil)即使您仍然发现需要添加更多服务器,您可以采取的任何措施都可以使每个服务器更加高效,这将使每个服务器更进一步

  2. 如果您的用户越来越多,您最终将需要“向外扩展”,但从短期来看,您可以通过为下一个“等级”再支付80美元来解决问题服务(8个核心,8倍优先级)。

  3. 图像调整大小真的是您应用的唯一瓶颈吗?如果图像大小调整是“免费”的,那么在渲染页面,运行数据库查询等之前,您可以在现有服务器上进一步扩展多少会限制吞吐量?如果你不知道,做一些模拟负载测试并找出它会很好。我问,因为如果渲染页面,数据库查询等也是瓶颈,或者很快就会成为瓶颈,你将不得不分发应用程序。在这种情况下,你不妨在主应用程序中保持缩略图,并立即分发它,而不是让你的缩略图在第二台服务器上作为Web服务运行。

  4. 无论您是分发主应用程序,还是将缩略图分成不同服务器上的单独应用程序,您都需要某种权威商店来跟踪S3上每个缩略图的保存位置。您可以将这些信息保存在memcached,数据库或任何您想要的位置。这并不重要。即使你把它保存在memcached中,也不意味着你不能在2台服务器之间共享缓存--1台服务器可以连接到在另一台服务器上运行的memcached实例。

  5. 您询问检查在不同服务器上保存的缓存的“延迟”是否会“阻碍增益”。我认为你不必担心这一点。您的问题是吞吐量,而不是延迟。这些高延迟网络操作并行化很好。因此,如果您只是并行处理更多请求,您仍然可以充分利用您的CPU(这是目前的资源瓶颈)。