ZIMG -- 高性能图片服务器浅谈

来源:互联网 发布:云计算平台标准规范 编辑:程序博客网 时间:2024/05/18 01:51

(偶然的在网上看到这篇文章, 觉得ZIMG很优秀, 只是目前版本是1.0还不支持分布式, 也期望后续版本如作者所说会支持集群.

项目代码可以去github: https://github.com/buaazp/zimg/)

综述

2011年李彦宏在百度联盟峰会上就提到过互联网的读图时代已经到来1,图片服务早已成为一个互联网应用中占比很大的部分,对图片的处理能力也相应地变成企业和开发者的一项基本技能。需要处理海量图片的典型应用有:
1. 图片类应用,如百度相册。
2. 导购类应用,如Guang.com。
3. 电商类应用,如淘宝。
4. 云存储服务,如七牛云存储。
除此之外几乎所有的网站都需要考虑自己图片处理的解决方案,以免在流量变大之后显得手足无措。
本文将从作者自己设计完成的图片服务程序zimg的设计思路出发,探讨高性能图片服务器的特点、难点和应对办法。

主要问题

要想处理好图片,需要面对的三个主要问题是:大流量,高并发,海量存储。下面将逐一进行讨论。

大流量

除了那些拥有自己数据中心的大型企业,中小型企业都需要考虑到流量问题,因为流量就是成本,图片相对于文本来说流量增加了一个数量级,省下的每一个字节都是白花花的银子。我曾经在一篇博客2里看到,作者在业务逻辑中引入PHP的imagick模块进行压缩,短短几行代码就做到了每个月为公司节省2万人民币的效果,可见凡是涉及到图片的互联网应用,都应该统筹规划,降低流量节约开支。

高并发

高并发的问题在用户量较低时几乎不会出现,但是一旦用户攀升,或者遇到热点事件,比如淘宝的双十一,或者网站被人上传了一张爆炸性的新闻图片,短时间内将会涌入大量的浏览请求,如果架构设计得不好,又没有紧急应对方案,很可能导致大量的等待、更多的页面刷新和更多请求的死循环。总的来说,就是要把图片服务的性能做得足够好。

海量存储

在2012年的介绍Facebook图片存储的文章3里提到,当时Facebook用户上传图片15亿张,总容量超过了1.5PB,这样的数量级是一般企业无法承受的。虽然我们很难做出一个可以跟Facebook比肩的应用,但是从架构设计的角度来说,良好的拓展方案还是要有的。我们需要提前设计出最合适的海量图片数据存储方案和操作方便的拓容方案,以应对将来不断增长的业务需求。

以上三个问题,其实也是相互制约和钳制的,比如要想降低流量,就需要大量的计算,导致请求处理时间延长,系统单位时间内的处理能力下降;再比如为了存储更多的图片,必然要在查找上消耗资源,同样也会降低处理能力。所以,图片服务虽然看起来业务简单,实际做起来也不是一件小事。

设计方案

zimg是作者针对图片处理服务器而设计开发的开源程序,它拥有很高的性能,也满足了应用在图片方面最基本的处理需求,下面将从架构设计、代码逻辑和性能测试等方面进行介绍。

总体思路

想要在展现图片这件事情上有最好的表现,首先需要从整体业务中将图片服务部分分离出来。使用单独的域名和建立独立的图片服务器有很多好处,比如:
1. CDN分流。如果你有注意的话,热门网站的图片地址都有特殊的域名,比如微博的是ww1.sinaimg.cn,人人的是fmn.xnpic.com等等,域名不同可以在CDN解析的层面就做到非常明显的优化效果。
2. 浏览器并发连接数限制。一般来说,浏览器加载HTML资源时会建立很多的连接,并行地下载资源。不同的浏览器对同一主机的并发连接数限制是不同的,比如IE8是10个,Firefox是30个。如果把图片服务器独立出来,就不会占用掉对主站连接数的名额,一定程度上提升了网站的性能。
3. 浏览器缓存。现在的浏览器都具有缓存功能,但是由于cookie的存在,大部分浏览器不会缓存带有cookie的请求,导致的结果是大量的图片请求无法命中,只能重新下载。独立域名的图片服务器,可以很大程度上缓解此问题。

图片服务器被独立出来之后,会面临两个选择,主流的方案是前端采用Nginx,中间是PHP或者自己开发的模块,后端是物理存储;比较特别一些的,比如Facebook,他们把图片的请求处理和存储合并成一体,叫做haystack,这样做的好处是,haystack只会处理与图片相关的请求,剥离了普通http服务器繁杂的功能,更加轻量高效,同时也使部署和运维难度降低。
zimg采用的是与Facebook相似的策略,将图片处理的大权收归自己所有,绝大部分事情都由自己处理,除非特别必要,最小程度地引入第三方模块。
注:zimg的1.0版本,设计面向图片量在TB级别的中小型服务,物理存储暂时不支持分布式集群,分布式功能将在2.0版本中完成。

架构设计

为了极致的性能表现,zimg全部采用C语言开发,总体上分为三个层次,前端http处理层,中间图片处理层和后端的存储层。下图为zimg架构设计图:
总体架构

http处理层引入基于libevent的libevhtp库,libevhtp是一款专门处理基本http请求的库,它太适合zimg的业务场景了,在性能和功能之间找到了很好的平衡点。图片处理层采用imagemagick库,imagemagick是现在公认功能最强,性能最好的图片处理函数库。存储层采用memcached缓存加直接读写硬盘的方案,更加深入的优化将在后续进行,比如引入TFS4等。为了避免数据库带来的性能瓶颈,zimg不引入结构化数据库,图片的查找全部采用哈希来解决。
事实上图片服务器的设计,是一个在I/O与CPU运算之间的博弈过程,最好的策略当然是继续拆:CPU敏感的http和图片处理层部署于运算能力更强的机器上,内存敏感的cache层部署于内存更大的机器上,I/O敏感的物理存储层则放在配备SSD的机器上,但并不是所有人都能负担得起这么奢侈的配置。zimg折中成本和业务需求,目前只需要部署在一台服务器上。由于不同服务器硬件不同,I/O和CPU运算速度差异很大,很难一棒子定死。zimg所选择的思路是,尽量减少I/O,将压力放在CPU上,事实证明这样的思路基本没错,在硬盘性能很差的机器上效果更加明显;即使以后SSD全面普及,CPU的运算能力也会相应提升,总体来说zimg的方案也不会太失衡。

https://github.com/buaazp/zimg

0 0