资讯专栏INFORMATION COLUMN

又拍云图片处理集群架构

n7then / 1861人阅读

摘要:又拍云图片处理集群规模及架构图片处理集群规模台核内存的服务器,相当于有核的处理能力。平时花瓣网的图片处理量就已经占集群超过,一下子翻几十倍的处理量进来,肯定会对作图服务造成影响。

黄慧攀,又拍云 CTO。最早在 2001 年开始 web 开发工作;2006 年创办 yo2.cn 优博网(WordPress 博客平台);2010 年加入又拍云开始构建第一代云存储和云 CDN 服务。曾从事前端、后端和服务端等工作,目前主要从事技术架构工作。

又拍云的云处理服务包括图片和音视频处理服务,其中图片处理系统每秒处理图片数量 3000 多张,一天要处理 1 亿张图片左右。图片处理服务面向的客户主要有电商、图片社交两类,他们也是图片处理需求的大户,其他类型的客户对图片处理需求比较少。

选择适合业务场景的系统架构

我们今天不谈具体产品,只讨论系统架构,很多人关注在图片处理领域选用 GraphicsMagick、ImageMagick 或者软编码或硬编码的性能高低。这些方案都各有利弊,需要按业务场景来选择。

又拍云因为是公有云处理服务,使用场景和作图功能要求很泛,什么打水印、模糊、加特效等,因此用软编码的方式是选择。

对于业务只有做缩略图功能要求的,肯定是硬编码的性能高。

又拍云图片处理集群规模及架构

图片处理集群规模

30 台 24 核、48G 内存的服务器,相当于有 30 * (24 - 1) = 690 核的处理能力。

这是我们的狗眼监控系统,对平台每个子服务都有 QPS 和平均处理耗时等关键指标的监控。上图是作图集群的 QPS 统计,处理能力、处理量都很稳定。

现行架构

前端部署了 8 台 nginx 做 7 层负载均衡,这里没用 LVS 做 4 层负载均衡,由于这个场景下 nginx 本身不存在瓶颈,因此我们简单使用了 IP 轮询方式,并在业务代码中来做容错。

Nginx 中配置 30 台 GmServer 的 upstream。这其中 28 台为普通的 GmServer,另外 2 台是 BigGmServer,这个是非常特殊的角色,Why?

因为我们提供的是公有云服务,客户传什么图进来,我们是不知道的,各种各样,甚至有几十兆的 GIF 图。但这种图所占整体的比例非常小,远低于 1%。所以我们只部署了 2 台 BigGmServer 来做这部分的处理任务。

自研的 GmServer

GmServer 最重要的策略特性是:

Server 只并发处理 CPU 核数以内的任务,如果超出了就返回 502,让 nginx 做容错处理,选择下一台处理服务器。

这个架构策略比选用哪个图片处理库重要得多。

因为在并发数超出 CPU 处理能力的时候,整体的处理性能下降比较严重,大家都在抢占 CPU,结果是大家都做不好。

GmServer 是基于 Linux + epoll + GraphicsMagick 开发的,在可控范围内做到全部内存处理图片,不走磁盘 IO。

对于 GraphicsMagick 本身还有不少处理逻辑会使用到本地磁盘 IO,我们把这部分放到 /dev/shm 上。

服务器 48G 内存,才 23 个并发任务,所以是够用的。完全基于内存做处理,可以避开磁盘 IO 的损耗,取得较高性能。

另外一个大头是修复 GraphicsMagick 的 BUG 和新功能的添加。因为是公有云,所以接收的图片各种各样,甚至有些是缺损的或者是经过“{{BANNED}}”压缩的 gif,GraphicsMagick 不一定能够识别和处理。

我们有专人长期在为此而战斗,并且这些 BUG 修复一般都会提交给 GraphicsMagick 官方,用以给开源社区一些贡献。

比如较大的一个就是 WebP 格式的支持,是我们工程师给 GraphicsMagick 提交的。

又拍网到现在的又拍云,使用 GraphicsMagick 有 6~7 个年头,在这方面的技术和经验积累非常多。如果您在使用过程中遇到特殊无法处理的图片,可以邮件联系找我们看看是否能做到兼容处理:huipan.huang@upai.com。

任务调度逻辑详解

处理图片任务 a(普通图片)

8 台 nginx 中随机选 1 台,再 nginx 把任务随机分配给 1 个 GmServer,处理完成。

处理图片任务 b(大图片或者大 GIF)

8 台 nginx 中随机选 1 台,再 nginx 把任务随机分配给 1 个 GmServer,处理 5 秒超时返回 413。再由 nginx 把任务分配给 BigGmServer。

这个 5 秒超时是很特殊的经验值,对于小图片处理都是几十毫秒的事,2k 分辨率的也就百毫秒,所以 5 秒以上的图片就特别{{BANNED}}了。

为了保障绝大部分普通图片的处理服务,所以我们把这种{{BANNED}}图片扔到 BigGmServer 去处理,BigGmServer 配置的任务超时时间是 60 秒。

为什么要扔到 BigGmServer?请想象一下普通处理集群,被{{BANNED}}图片占满会出现什么效果?

因为 nginx 的 7 层负载均衡还带容错能力,1 个{{BANNED}}图片进来处理不了,会尝试其他机器,不一会儿整个集群都被这个{{BANNED}}图片给占了,所以我们有必要把任务分类处理的。

(任务 a、b、c 示意图)

处理图片任务 c(普通图片)

这里有个前提假设:我们的 GmServer 只能做 2 个并发任务(否则我画图得画 24 个)即目前状态下 GmServer 不会再接收任务。新来的 c 任务会返回 502,让 nginx 重新选择一台 GmServer 来处理任务。即使遍历集群也就 20ms 以内,一般下一跳就能得到处理了。

现行架构的优缺点分析

一般每周 review 一下处理的 QPS,关注一下吐出的错误码比例,能准确判断到集群是否过载,提前能做好扩容工作。

当前架构优点

服务稳定,过载时业务不会全面受到影响。

架构简单、通用。

当前架构不足

动态扩容不友好,因为架构太简单,动态扩容的实现复杂度高一些,因为需要跟 nginx 做联动。为此要配置自动发现和 nginx 动态配置 upstream 等(当然这块用 nginx + Lua 很好做)。

最近 Docker 很火,我们也有在关注这方面的技术。综合分析下来,打算做一套新的架构,把我们图片处理和音视频处理,原来两套独立的集群混合起来,把资源利用率做上去。

未来的新架构方向

Nginx 改为使用自己研发的 ServiceServer,基于消息队列实现任务排队。此前的 GmServer 转为 GmWorker,主动对接消息队列来处理任务。

这个架构的优点是:Worker 轻量级,且很容易做动态扩容,因为 Server 端不需要配置 Worker 信息,Worker 在启动时主动向 Server 申报身份和认领任务。接下去配合 Docker 的动态扩容就非常方便。

这里有个重点是

ServiceServer 可支撑图片集群、音视频处理,甚至普通 Web 请求任务。

Worker可混合部署。

Worker 不需要做服务监听,可以很方便的用 docker 横行扩展。

如果想走捷径,可以考虑 nginx Plus 版本的 7 层负载均衡支持队列功能,也能达到这个效果。但也有较大的缺点:$1900 / 单机 / 年。当然这个 nginx 的方案,做 docker 的横向扩展时,还是逃不掉跟 nginx 做联动、自动发现等事情。

运营中遇到过的坑

集群自身是没遇到过什么大的坑,只有些小逻辑 bug 的问题。但在服务上有缓存失效和业务攻击的问题,需要做自动降级和适当屏蔽。

先参考下我们的服务架构

缓存失效时候的高可用设计

数据中心缓存有磁盘损坏或者服务器故障时,会导致大部分的缓存失效,从而导致落到作图服务的请求数增大好几倍。而作图服务是无法承受如此大压力的,所以我们允许向用户吐 503 错误码。

注意这个错误码要配置起码 1 分钟以上的缓存失效时间,以避免用户重复刷新请求。如果不设置一个让客户端缓存的时间,那这个 503 错误码吐得没什么意义了。

CDN 缓存一般不会出问题,因为它是分布式、多缓存节点的架构,服务器数量太庞大,即使有磁盘坏或者机器故障所产生的震荡都很小,不必担心。

不同租户隔离与高可用设计

但还要担心的一个是“恶意”请求,这里说的恶意是带双引号的,因为它并不是真正意义的攻击,很可能只是客户一个小变动导致。比如修改了一个缩略图版本号配置,这个操作就会导致旧版本的缩略图缓存全部失效,而要重新到作图服务处理。

如果这是个小客户,那没啥事,但如果是像花瓣网这样的大客户,就问题很严重了。平时花瓣网的图片处理量就已经占集群超过 50%,一下子翻几十倍的处理量进来,肯定会对作图服务造成影响。一个客户影响整个平台!

为此我们在 nginx 上加了针对客户的峰值控制系统,来避免这种情况而影响整个平台。

针对具体场景的优化与设计

缩略图版本号的使用确实给业务带来非常大的方便,随时可针对业务的需求切换使用不同的缩略图格式,点下鼠标马上生效。

但这也是有代价的,就是上面所说的影响。无法完美解决这个问题,要不把作图集群扩到完全无缓存都能处理的能力,要不就接受繁忙时会出现部分图片 503 错误。

而我们会考虑到成本,显然无法提供到峰值的处理能力,那势必要接受一定的错误量。但这个也是可以尽量避免,比如应用方要做缩略图版本切换时,可以考虑提前预热一段时间,灰度切换,使得这个峰值能得到一定的均衡。

图片在线服务的安全问题

另外一些缺乏经验的云厂商,也提供在线作图服务,且更方便。比如 http://a.com/b.jpg?w=100   通过参数自由配置想要的缩略图大小,试想一下,被人恶意组合url参数来刷你的作图集群,会是怎么个效果。

上面提到,如果客户有类似需求,较好自动化控制单客户占用资源,我们也是去年才提供通过 url 参数来作图的功能。 建议大家在新建这样的服务时,要多考虑周到。

Q & A

1. 前端部署了 8 台 nginx 做 7 层负载均衡,这里没用 LVS 做 4 层负载均衡。为何如此设计?

黄慧攀:这个不是性能的问题,只是开发多几行代码,或运维多一个 LVS 管理的事而已。我们是在业务代码上, {s1….s8} 随机选 1 台的。LVS 大多起负载均衡作用,但在这个场景下 nginx 本身压力很小并不存在瓶颈,因此我们简单使用了 IP 轮询方式,并在业务代码中来做容错。

 

2. 后端存储图片的数据库用的是什么 ?

黄慧攀:这个我们是存在云存储里面的。建议你用 Key/Value 数据库也行。

3. 后续有没有考虑将图片的处理用 GPU 做?

黄慧攀:前面说到过我们的业务需求复杂度比较高,用 GPU 会大大增加我们的研发难度和投入。目前的场景选用 CPU 的方案最适合我们。

4. 能否简单对比下 GraphicsMagick、ImageMagick 优缺点?

黄慧攀:你可以这么理解,gm 是 im 的一个基础库,im 在 gm 上做了更好的功能封装。套了层壳,性能是 gm 较好的。

5. 又拍云的图片服务是否提供 OCR 服务?

黄慧攀:暂时没这样的计划。

6. 老架构按业务区分流量和服务,胜在稳定。新架构在业务上混搭,彼此间是否有权重和流控,会不会有某类流量陡增对其他类业务产生冲击,或者说如何保障每类业务稳定?

黄慧攀:这个就看我们怎么做 Worker 部分的开发。我们每个 Worker 启动都会锁定 1 个  CPU 核上的,不会对其他 Worker 造成影响;

另外说到的任务权重,和个别业务需要突发处理的情况,我们有做考虑。先分成 2 类任务, 1、同步任务(如图片处理);2、异步任务。 我们优先处理同步任务,对每单个客户要做好全局的资源限制。

7. 我们的系统通过参数来处理图片,而业务方可能直接用链接,这样导致每次都走一遍图片处理逻辑,有什么优化方案?

黄慧攀:自己内部的服务,可以考虑增加权限及 IP 访问频率等限制即可。 如果是云服务商可以参考我上面方案。

群友:可以对参数做加密,时间戳也打进去,一方面鉴权,一方面验证请求有效期。

黄慧攀:Good idea 。其实,我还是建议用缩略图版本号。

群友:处理过的图片会存储磁盘吗?

黄慧攀:处理过的图片,不存磁盘。 但上面有 2 层缓存。

8. 上文所说 nginx 请求 gm_server 时,能否用连接池代替上面逐台尝试的做法?

黄慧攀:用连接池会导致负载不均衡的。 遍历池子的损耗很小。另外如果考虑连接池了,用上面新架构模式或许更好, 放到消息队列,Worker 来消费。

9:超时判断是在 nginx?那样虽然返回错误码了,但 gm 的转换还在进行,还是会占用资源?

黄慧攀:超时判断是 gmserver 做的,gmserver 是多进程的,自己内部直接把自己杀了。如果用 nginx 来做肯定面临你说的问题,所以非常必要自己开发这个 gmserver。

欢迎加入本站公开兴趣群

软件开发技术群

兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流

QQ群:26931708

Hadoop源代码研究群

兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop

QQ群:288410967 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/4168.html

相关文章

  • 工具推荐丨推荐拍云web版API管理工具,一款辅助使用拍云的轻量工具

    摘要:没想到会找到其他开发者针对又拍云开发又拍云管理工具这样的工具,我个人觉得也算是又拍云在接口方面比较开放的一个的案例吧。 今年上半年,我通过又拍云搭建了一个独立博客,不久之后就遇到了很多实际问题:网上看到图片想收藏到空间,YouTube上的MV想放到自己的博客,想对一段音视频进行在线预览和编辑……当时我查了下,必须要通过API接口编写一段程序才能完成(不是程序猿,搭建独立博客已经要了我半...

    adam1q84 评论0 收藏0
  • 边缘计算 VS 云计算,谁才是未来

    摘要:什么是边缘计算边缘计算,其定义也比较宽泛,可以理解为最近端的云计算,但是边缘计算从许多共识来看,并不隶属于云计算,而是云计算的补充或者云计算的预处理。 计算是互联网中一个永恒的话题,设备的所有运行都可以看成是 0 和 1 的运算。在计算中近些年有两个越来越响亮的技术:云计算和边缘计算。现如今是云计算方兴未艾,边缘计算已经有了燎原之势,本文将对这两种技术做下简单的对比介绍,让大家能够对边...

    tolerious 评论0 收藏0
  • 拍云直播服务有哪些功能?

    摘要:又拍云直播服务,依托又拍云强大的技术平台和直播技术功底,针对广电赛事直播互动直播等各种直播应用场景提供稳定快速的直播接入和分发服务,为客户提供高并发低时延的一站式直播服务。服务咨询了解更多又拍云视频服务 showImg(https://segmentfault.com/img/bVxFJc); 又拍云直播服务,依托又拍云强大的 CDN 技术平台和直播技术功底,针对广电赛事直播、互动直播...

    liangzai_cool 评论0 收藏0
  • 【省带宽、压成本专题】从产品架构来看,PCDN如何节流50%

    摘要:优势又拍云在产品架构方面的优化,让相比其他有巨大的优势。作为国内成熟云服务厂商,又拍云在行业不断探索,寻求更先进的技术,帮助客户减少带宽成本,提高加速稳定性。在未来,又拍云将会为客户带来更多更好的服务。 过去几年,我们一直在视频省流量方面潜心钻研,取得不俗的成果。本次省带宽、压成本系列一共会推出六篇文章,从技术迭代、硬件更新等角度出发,向大家介绍节省CDN流量,降低视频播放成本的方法。...

    番茄西红柿 评论0 收藏0
  • 【省带宽、压成本专题】从产品架构来看,PCDN如何节流50%

    摘要:优势又拍云在产品架构方面的优化,让相比其他有巨大的优势。作为国内成熟云服务厂商,又拍云在行业不断探索,寻求更先进的技术,帮助客户减少带宽成本,提高加速稳定性。在未来,又拍云将会为客户带来更多更好的服务。 过去几年,我们一直在视频省流量方面潜心钻研,取得不俗的成果。本次省带宽、压成本系列一共会推出六篇文章,从技术迭代、硬件更新等角度出发,向大家介绍节省CDN流量,降低视频播放成本的方法。...

    skinner 评论0 收藏0

发表评论

0条评论

n7then

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<