暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

NOS图片处理系统

数据管理 2016-10-11
790

概述

NOS(Netease Object Storage)致力于提供最优质的对象存储以及基于存储的富媒体和上下行加速服务,一站式解决移动互联网时代非结构数据管理难题(非结构化数据的解决方案),助力产品方实现最佳用户体验。

当前NOS承载着几乎所有网易互联网产品blob数据的存储,图片、视频、附件等是最常见的应用场景,而其中很大一部分数据为图片数据,比如网易lofter、网易云音乐、网易考拉海淘、易信朋友圈都有非常多的图片应用场景。几乎所有的这些产品都会大量得使用到NOS提供的图片处理服务。

NOS图片处理服务从2013年上线到现在已经上线差不多快3年半的时间

  • 图片处理服务器从几台扩容到几十台;系统负载tps从几百tps上升到现在的2w+tps,近上百倍负载增长。

  • 功能从简单的裁剪缩略到提供丰富的图文水印、链式处理等功能,已能满足专业的lofter图片处理的需求。

  • 架构不断演变以适应更多的功能、性能、扩容性等各方面的需求。

很多变化历历在目,唯一不变的是我们一直站在用户的立场上为广大网易产品提供稳定高效的服务,助力产品实现最佳用户体验。(NOS图片处理服务的具体功能点介绍,详见,PS:还有基本的音视频服务)

以下为NOS图片系统发展的timeline

本文从以下几个方面与大家分享下NOS图片处理解决方案:

  • 图片核心处理单元

  • 数据的获取nosfs

  • 系统过载控制

  • 图片处理架构

1. 图片核心处理单元Tobie

分治永远是解决所有复杂问题的解决方案,在计算机科学中体现的尤为明显。如上为一个基本的图片核心处理单元。主要分为以下几个层次接口层、并发层、处理层、数据层。

  • 接口网络层

接口层向上层调用者提供HTTP RestFul Service,如下为对存储在nos的一张图片资源 Koala.jpg 执行简单的缩略操作。

http://nos.netease.com/doc/Koala.jpg?imageView&thumbnail=100x0

更多详细的操作见: NOS富媒体处理最佳实践

接口层为基于Libevent实现的 C++ http服务。Master负责网络层的处理,包括接收来自客户端的请求,进行合理解析分发到任务队列,以及接收来自worker的处理结果并返回给客户端。Master基于libevent实现Non-Blocking的网络IO处理,所以基本单线程能够hold住整个图片处理单元的网络负载。

  • 并发处理层

并发层worker从任务队列中获取请求并进行实际的图片处理工作,并发层Processor为通用的数据处理单元,当前已经整合Grapbic Magic 图片处理单元以及ffmpeg视频处理单元,后续如果有新的处理服务也可以非常方便的整合实现其它的处理功能。同时Processor也实现了Lua 扩张功能,可以非常方便的进行外部命令调用,从而非常快速的整合新的处理功能。

  • 数据接口层

数据层实现了内存的数据接口以及本地文件系统的POSIX访问接口。数据资源可以是本地资源,也可以是来自网络资源。本地资源提供内存和File接口是非常直接的,网络上的资源是(对于我们来说主要也是通过网络方式来获取NOS上的资源)通过基于nosfs模块实现将NOS HTTP Rest API接口到Posix接口的转换。

2. nosfs

NOS提供的是标准的HTTP RestFul API,而某些图片或者视频处理库只提供了基于本地文件的处理接口;所以面对这样的场景我们基于fuse(用户态文件系统开发框架)实现了nosfs,将nos上的资源以文件系统中文件的方式暴露给上层应用。

NOFS的基本框架如上图所示。APP(Tobie) 使用 open、read、write等文件系统POSIX API接口读取文件内容,陷入内核后,Fuse 内核模块会将用户的调用请求转发给上层我们基于libfuse实现的NOSFS模块,NOSFS 将文件系统形式Read、Write 调用转化为NOS HTTP PUT GET 请求实现协议的转换和数据的读取和写入。

以下为基于fuse的hello world 文件系统的编写,详见helloworld,可以很方便得通过实现.read、.open 等handler函数的具体实现将自身的协议转换为文件系统的Posix接口。



3. 处理单元的过载控制

3.1 过载与排队
3.2 tobie过载问题与解决方案

对于时延敏感的服务(同步调用),当外部请求超过系统处理能力,如果系统没有做相应保护,可能导致历史累计的超时请求达到一定规模,像雪球一样形成恶性循环。由于系统处理的每个请求都因为超时而无效,系统对外呈现的服务能力为0,且这种情况下不能自动恢复。

对于图片处理系统来说,是典型的CPU消耗性业务,往往32核机器对外只能提供几百的TPS的服务能力。如果系统在高负载情况下CPU成为瓶颈而请求还是在不断累积,那么很容易造成恶性循环。

NOS图片服务刚上线的时候就因为此类问题吃过不少亏,下图简要说明了图片服务刚上线之前的构架。逻辑层(tomcat)是统一的,不仅承担了用户数据的读写,还要转发处理图片服务请求。某次系统发生局部故障,Tobie处理集群中的某台机器处理能力降低不能快速进行图片处理,但是tobie的IO线程并没有block,还可以正常得进行请求得接收,从而导致请求积压,这不仅仅导致我们Tobie做了很多无用功(处理队列中已经超时的请求),更重要的是导致上层调用方(诸业务服务器)等待在这个故障图片处理节点上等待图片处理结果,而不能处理其它包括文件读写等核心业务。

所以事后,我们做的第一件事情是核心服务的拆分,将上传下载、图片处理业务逻辑隔离开来。并且后续又针对图片处理核心模块系统层次的做了深层次的梳理,包括操作系统层次,保留libevent网络库层次,应用层次等。

如上图所示,从服务端收到客户端发送的Sync信号连接,连接进入Sync-Received队列,到三次握手完成进入Establish队列之后;再到上传网络库libevent通过epoll多路服用方式将底层的连接Accept放入event队列;直到连接上接收到一个完整的HTTP请求之后,IO线程回调上层应用的回调函数将HTTP请求插入请求队列,最后worker从请求获取请求进行处理。

当然系统层次或者libevent层次我们能够控制的余地较小,在底层做控制也不是非常优雅和通用,所以我们通过在应用层对请求队列做了一些控制,比如限制队列的长度,超过队列长度的时候直接拒绝请求;又比如每个请求插入队列的时候打上时间戳,worker取请求的时候发现已经等待很长时间了直接丢弃请求返回错误等等。另外我们结合nginx的健康检查机制,在服务已经过载情况下自动将请求调度到其它节点。

总结来说,以下几点为我们实践过程中总结出来的构架设计的关键点:

  • 分布式系统中一个节点过载可能导致整个服务不可用,(tomcat类同步调用框架尤为容易受影响)

  • 核心服务的隔离,拆分

  • 前端不能信任后端, 所以第其他模块调用必须设置合理超时、一定的保护后端的责任

  • 后端应该尽力而为,服务不了果断拒绝,SLA

4. 图片处理架构

如上为NOS图片处理的整体框架,Nginx将图片请求转发到NosMeida,NosMedia层次的功能主要为图片协议正确性检查,调用NosAuth对用户的请求进行认证。ATS(apache traffic server)缓存集群用户缓存图片处理结果(当前NOS使用的是代理缓存的模式),tobie处理集群氛围大集群以及小集群,小集群用户处理较小的图片资源的处理,大集群用户处理超大图片、以及针对视频的操作。


推荐阅读
Parquet与ORC:高性能列式存储格式
视频云直播端网络QoS算法总结和技术展望
redis3.2新功能--GEO地理位置命令介绍
Cassandra 故障探测原理--Accrual Failure Detector



点击阅读原文,了解更多技术干货


文章转载自数据管理,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论