为了账号安全,请及时绑定邮箱和手机立即绑定

如何优化服务器上​​的 ImageMagick CPU 使用率

如何优化服务器上​​的 ImageMagick CPU 使用率

Go
拉莫斯之舞 2023-05-22 17:06:55
我正在尝试使用 ImageMagick 将一个图像重叠在另一个图像之上。我设置了一个 AWS beanstalk 机器,它有 16 个核心 cpu 和 32gb ram(c5 4x 大),并在 Go 环境中运行代码。每当 GET 请求到达服务器时,都会执行以下 shell 命令。这是我正在运行的命令cmd := "convert "+ img1 + " -page +"+fmt.Sprintf("%.1f", offsetX)+"+"+fmt.Sprintf("%.1f", offsetY) + " " + img2 + " -background none -flatten "+outputFilePathcmdout,err := exec.Command("sh","-c",cmd).CombinedOutput()//convert img1.png -page +10+10 img2.png -background none -flatten  output.pngimg1 的大小约为 500x500,im2 的大小约为 200x200我进行了负载测试,发现当前设置每秒只能处理 15 个请求,CPU 使用率为 51%。在 25req/sec 时,cpu 使用率变为 95%。我坚信我做错了什么。我正在使用 Imagemagick v6.7.8。升级到最新版本或从源代码(而不是 yum install)编译 ImageMagick 有帮助吗?我应该怎么做才能满足 100req/sec 并确保所有 vCPU 都得到最佳利用
查看完整描述

1 回答

?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

我试过我的 2015 i5 笔记本电脑(两个核心,四个线程)。我做了一些这样的测试数据:


$ mkdir sample

$ cd sample

$ vipsheader ../fg.png ../bg.png 

../fg.png: 200x200 uchar, 4 bands, srgb, pngload

../bg.png: 500x500 uchar, 4 bands, srgb, pngload

$ for i in {0..1000}; do cp ../fg.png fg$i.png; done

$ for i in {0..1000}; do cp ../bg.png bg$i.png; done

所以 1,000 张 500x500 和 200x200 PNG 图像。


首先,基本情况(IM 6.9.10):


$ time for i in {0..1000}; do convert bg$i.png -page +10+10 fg$i.png -background none -flatten out$i.png; done

real    0m49.461s

user    1m4.875s

sys 0m6.690s

49s 大约是每秒 20 次操作。


接下来,我尝试使用 GNU parallel。这是并行运行足够多的内核以保持所有内核加载的简单方法:


$ time parallel convert bg{}.png -page +10+10 fg{}.png -background none -flatten  out{}.png ::: {0..1000}

real    0m32.278s

user    1m46.428s

sys 0m11.897s

32s 是 31 次操作/秒。这是在双核笔记本电脑上进行的——您会发现使用更大的台式机可以获得更好的加速。

最后,我写了一个小的pyvips程序来完成你的任务。pyvips 是libvips的 Python 绑定,但也有 Go 绑定。

import pyvips


for i in range(0, 1000):

    bg_name = "bg" + str(i) + ".png"

    fg_name = "fg" + str(i) + ".png"

    out_name = "out" + str(i) + ".png"


    bg = pyvips.Image.new_from_file(bg_name, access="sequential")

    fg = pyvips.Image.new_from_file(fg_name, access="sequential")


    result = bg.composite2(fg, "over", x=10, y=10)


    result.write_to_file(out_name)

我懂了:


$ time ~/try/try289.py 

real    0m25.887s

user    0m36.625s

sys 0m1.442s

26s 大约是每秒 40 次操作。如果并行运行多个,您将能够更快地获得它。


您遇到的限制之一是 PNG 格式——该库是单线程的,而且速度很慢。如果你愿意尝试 TIFF,你可以获得相当多的速度。


带放气压缩的 TIFF 在功能上类似于 PNG。如果我尝试:


$ vips copy fg.png fg.tif[compression=deflate]

$ vips copy bg.png bg.tif[compression=deflate]

$ ls -l bg.*

-rw-r--r-- 1 john john 19391 Dec 27 20:48 bg.png

-rw-r--r-- 1 john john 16208 Jan  2 18:36 bg.tif

所以在这种情况下,它实际上要小一些。如果我将 pyvips 程序更改为:


bg_name = "bg" + str(i) + ".tif"

fg_name = "fg" + str(i) + ".tif"

out_name = "out" + str(i) + ".tif[compression=deflate]"

运行它,我看到:


$ time ~/try/try289.py 

real    0m17.618s

user    0m23.234s

sys 0m1.823s

大约 55 次操作/秒。


查看完整回答
反对 回复 2023-05-22
  • 1 回答
  • 0 关注
  • 104 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信