【编者的话】本次分享介绍七牛数据处理团队的容器技术实践经验,分享七牛如何通过自主研发的容器调度框架打造易扩展、易部署、高自由度、高可用、高性能的数据处理平台。
主要内容包括四个方面:
- 海量数据处理的业务场景
- 海量数据处理平台的挑战
- 自研容器调度框架介绍
- 海量数据处理平台实践
一、数据处理业务场景
首先介绍一下七牛数据处理业务的背景。七牛云目前平台上有超过50万家企业客户,图片超过2000亿张,累积超过10亿小时的视频。 用户把这些图片和视频存储在七牛上后会有一些数据处理方面的需求,如缩放、裁剪、水印等。这些文件持续在线且数据种类多样,如果用户把这些文件在自己的基板上处理好后再上传到七牛,是非常不合算的事情。而七牛最先提供基于存储的数据处理功能方便用户去做数据处理,这些数据处理通常放在企业的客户端或服务器端来操作,对接上七牛云存储的数据处理接口后,即可对图片和音频进行丰富的实时转码功能,转码生成的新规格文件放在七牛提供的缓存层供App调用,不用占用存储空间,对企业来说不仅成本大大降低,还可提高开发效率。 下图为一个图片裁剪的数据处理示例:七牛的文件处理程序简称FOP(File Operation),不同的文件处理操作使用不同的FOP。用户只需上传一个原文件就可以通过使用七牛的数据处理功能得到各种样式丰富的文件。下图为文件从上传存储到处理到分发的流程图:
二、海量数据处理平台的挑战
七牛云的海量数据成就了Dora十分强大的数据处理能力,目前七牛的数据处理服务已经日处理数近百亿次。面对这样海量的数据处理请求,原有的数据处理平台也面临着新的挑战:
日均请求量百亿级,CPU 密集型计算
目前系统每天有近百亿的数据处理请求量,拥有近千台的计算集群,整个存量、增量都非常大。而数据处理集群中绝大部分的机器都是用来跑图片、音视频转码的,这些都是CPU密集型的计算,这意味着后台需要很多台机器,而且CPU的核数越多越好。在年底数据处理平台可能会在目前近千台的计算集群基础上翻好几倍,需要有快速物理扩展和高效智能管理的能力。
服务器负载不均衡,资源利用率不高
实时在线处理的业务处理时间短,但是量大,需要大量的实例来应对高并发的情况。而异步处理的业务处理时间长,也需要分配足够的资源来。当实时业务并不繁忙而异步处理业务增长时,并不能使用分配给实时业务的资源, 这种静态资源分配机制带来的分配不合理问题,导致服务器负载不均衡,资源利用率不高。
突发流量不可测量, 大量冗余资源
在新接入用户并不能完全正确的预测请求量,原来的模式是通过快速扩容机器并验证上线,需要一定的处理时间,对于这种非计划内的请求量需要准备大量的冗余资源来应对突发流量。
集群负载过重,不能自动按需扩展
个别用户突增数据处理请求时导致集群负载压力过大,CPU处理变慢, 请求时间变长,请求任务堆积,影响其他业务,并不能在现有的资源基础上进行快速扩展,也不能根据实际的业务压力进行按需自动扩展集群实例。
用户自定义应用(UFOP)质量及规模未知
七牛除了提供官方的数据处理服务,也支持客户将自定义数据处理模块部署到七牛云存储的就近计算环境,避免远程读写数据的性能开销和流量成本,满足用户多方位的数据处理需求。但是各种UFOP运行在同一个平台上就可能会存在部分UFOP的质量问题或请求量过大而分配的资源不足导致影响平台上其他服务的正常运行。
三、自研容器调度系统介绍
为了解决以上问题,七牛基于资源管理系统Mesos自主研发了一套容器调度框架(DoraFramework),通过容器技术打造了易扩展、易部署、高自由度的数据处理平台Dora。整体架构图如下所示:各组件介绍:
Mesos:由ZooKeeper、Mesos Master、Mesos Agent构成了基础的Mesos数据中心操作系统,可以统一管理机房中的所有物理机,负责资源层面的调度,是二层调度系统最基础的运行环境 。
DoraFramework:业务层调度框架,通过DoraFramework使用Mesos管理所有的物理机资源,完成业务进程的调度与管理。
Consul:包含服务发现,健康检查和KV存储功能的一个开源集群管理系统,DoraFramework调度系统使用Consul的服务发现和健康检查机制提供基础的服务发现功能,使用KV存储功能来存储DoraFramework的metadata。
Prometheus:一个开源的监控系统,实现机器级别,容器级别及业务系统级别的监控。
Pandora: 七牛的内部的日志控制管理系统,负责生产环境所有日志的汇聚及处理。
在这个架构中,我们选择通过容器技术实现跨机器实现弹性的实时调度。调度框架可以根据具体的业务负载情况动态的调度容器的个数, 很好的解决了静态配置导致的资源利用率不高的问题 。而容器秒启的特性也解决了当有大量突发请示进入,可以快速启动服务的问题。在网络方面,由于UFOP是用户部署运行的服务,并不知道用户是否有开启其他的端口使用,所以使用的是Bridge模式,需要对外使用端口的都需要通过NAT进行暴露,这样服务内部使用了什么端口并不会对外界环境造成影响 ,对平台环境做了非常好的安全隔离。
数据处理平台的调度系统我们选择的是Mesos 自研容器调度框架(DoraFramework)。选择Mesos做为资源管理系统一个是因为Mesos的相对其他的容器调度系统更成熟,Kubernetes是2015 才发布可生产环境运行的版本,Docker Swarm则是2016年才发布,这两个产品的生产实践在调研时基本还没什么大型生产实践经验,而Mesos则已有七八年的历史,且资源管理方面已经在如苹果,Twitter等大型公司得到生产实践,稳定性比较好;第二个是因为Mesos支持调度成千上万的节点,以七牛目前已经达到近千台物理机的规模,且每年都在大幅度增长的情况,Meoso这种支持超大规模调度的资源管理框架更合适七牛的业务发展; 第三是因为Mesos的简单性,开放性及可扩展性,Mesos是一个开源的分布式弹性资源管理系统,整个Mesos系统采用了双层调度框架:第一层由Mesos收集整个数据中心的资源信息,再将资源分配给框架;第二层由框架自己的调度器将资源分配给自己内部的任务。Mesos自身只做资源层的管理,这种简单性带来的则是稳定性。而容器的调度框架则可以使用开源框架如Marathon/chronos或自主研发。Kubernetes虽然功能很丰富,但是也比较复杂,组件及概念都比较多,并且缺乏开放性和可扩展性,只能使用它提供的调度功能,而不能根据自身业务的情况定制调度框架,会造成对Kubernetes过于依赖的情况。
为什么不选择Mesos的核心框架Marathon 而选择自研,出于三方面的考虑:1. Marathon有些方面不支持我们期望的使用姿势,比如不太好无缝对接服务发现;2. Marathon采用Scala开发,出了问题不好排查,也不方便我们做二次开发;3. 如果选用Marathon的话,我们上面还是要再做一层对 Marathon的包装才能作为Dora的调度服务,这样模块就会变多,部署运维会复杂。
DoraFramework是七牛使用go语言自研的容器调度框架。DoraFramework实现了Mesos两层调度中业务进程的调度,是Dora调度系统中的核心组件,通过与Mesos和consul组件之间的交互, 对外提供API接口。架构图如下:
DoraFramework主要功能介绍:
- 自动化应用的部署
- 服务注册与发现
- 弹性调度容器数量
- 负载均衡
- 支持在指定机器上增加或减少实例
- 支持高可用
- 应用的版本和升级管理
- 支持获取实例的状态及日志数据
- 支持业务级别的监控
- 支持实例的故障修复
DoraFramework与Marathon调度架构的对比:
- DoraFramework调度系统的服务注册与发现使用Consul实现, Consul是用于实现分布式系统的服务发现与配置,支持跨数据中心的内部服务或外部服务的发现, 对外提供DNS接口,而Marathon-lb并不支持跨数据中心的服务发现。
- Marathon是通过Marathon-lb所在节点的servicePort服务端口或VHOST来发现服务 ,要求网络模式必须为Bridge。因为Marathon-lb还负责负载均衡的功能,在大型的业务环境下,如果Marathon-lb出现异常,则会影响框架正确的服务发现。
- Dora调度系统可以做更精确的弹性调度。因为它不仅支持做资源使用层面的监控,还支持做业务级别的监控,在对实例进行调度时就可以根据实际的业务压力进行调度。
- Dora调度系统内的负载均衡组件是通过从Consul中获取到所有的可用实例的地址进行负载分发,并可以根据每个实例的业务负载情况进行更精确的分发。而Marathon-lb并没有业务层的监控数据。
- Consul提供系统级和应用级健康检查,可以通过配置文件及HTTP API两种方式来定义健康检查,并支持TCP、HTTP、Script、Docker和Timeto Live(TTL)五种方式做Check。Marathon的默认的Health Checks只检查Mesos中的任务状态,当任务为running时,就被认为是health状态,这样不能做应用级的健康检查。Marathon通过REST API可以查看应用的健康状态, 但只支持TCP、HTTP和Command三种方式。
- Dora调度系统提供的监控栈在业务进程运行过程会汇总采集业务运行状况指标,如请求次数,请求延时等信息,业务进程对外暴露一个标准的http监控接口,监控接口的数据产出符合Prometheus监控数据格式。Prometheus通过配置Consul作为服务发现地址,会从Consul中获取需要收集监控数据的业务进程列表,从业务进程暴露的http监控接口pull监控数据。
我们使用Consul做注册中心,实现服务的注册与发现。Consul自带key/value存储,可通过DNS接口做服务发现,且具体健康检查的功能,并支持跨数据中心的服务发现。API Gateway可以通过Consul提供的DNS接口查询到服务所有的可用实例的列表信息,并将请求进行转发。
服务的自动注册和撤销
新增微服务实例时,采取的原则是等待实例为运行状态后将实例的访问地址注册到Consul Client的Service Registration,并配置这个服务的健康检查,再将数据同步到 Consul Server的服务注册表中。
对于减少实例时,采取的原则是先将实例从Consul Server的服务注册表中删除,等待冷却时间之后,再从通过调度系统将这个实例销毁。从而完成服务的自动注册和撤销。
服务发现
外在系统想访问服务时,可通过服务名称从Consul Server提供的DNS接口查询到当前服务在Consul Server中注册的所有健康实例的访问地址, 再将请求发送给实例。
四、海量数据处理平台实践
我们生产环境的配置管理采用的是Ansible,Ansible默认使用SSH进行远程连接,无需在被管节点上安装附加软件,可以批量系统配置、批量部署、批量运行命令等,非常适合七牛的大规模IT环境。而Playbooks 是一种简单的配置管理系统与多机器部署系统的基础,使用非常简单,且具有可读性,非常适合于复杂应用的部署。我们通过Ansible可以实现数据处理平台的一键式安装和删除,新增和删除节点,还包括对组件版本的升级及回退,以及生产环境的批量配置修改等操作,简化了复杂的运维配置管理工作。在实践中,选择一台主机做为中控机,安装Ansible,再配置这台中控机与所有远程主机的SSH互信,再在中控机上配置Playbook文件,即可对多台主机进行批量操作。对于简单的操作,可执行如下命令:
$ansible-playbook main.yml -i hosts
在main.yml里编辑所有需要做的操作,在hosts文件里写入所有需求操作的主机IP地址,即可完成对hosts文件里所有主机的批量操作。而对于复杂的操作,则可通过编写Playbook进行配置。roles里存放不同的角色任务,比如Mesos Master上执行的任务和Mesos Agent上执行的任务不同,则可放在不同的roles里,也可以把Mesos、Zookeeper、Consul放的不同的roles里。tasks里则是role里具体执行的任务,handlers则是tasks里触发执行的任务。template则是模板文件,比如我们需要个性Consul的默认配置文件,可以修改后的配置文件放在这个目录下,在执行时用这个文件替换默认的配置文件。
在监控方面,数据处理平台拥有完整的监控体系,包括了主机监控,容器监控,服务监控,流量监控,日志监控。主机和容器的监控主要通过Prometheus的各种Exporter来做,采集到包括CPU、内存、网络以及磁盘的实时使用情况,服务监控和流量监控则通过七牛自己的监控程序进行监控,可以监控到服务的状态、存活性、句柄数、及所有处理命令的请求数、失败数等。日志监控则是通过七牛内部的日志平台Pandora系统进行监控,包括收集系统日志,容器日志和业务进程日志。通过修改开源的文件收集器Filebeat的output,将采集到的日志全部传送到七牛内部的日志监控系统Pandora进行日志监控。
监控数据显示如下:
以上就是七牛云数据处理平台基于容器技术实践的情况。目前七牛的数据处理平台具备零运维、高可用、高性能的数据处理服务能力,可让用户轻松应对图片、音视频及其他各类数据的实时、异步处理场景。七牛的数据处理业务系统不仅可以处理来自七牛云存储的数据处理请求,也支持来自非七牛云存储的数据处理请求,还可以直接处理来自七牛云分发Fusion的数据处理请求,用来提高CDN中间源数据的处理速度。而数据处理平台Dora则是一个开放的平台,不仅可以运行七牛自己的数据处理服务,也支持运行用户自定义的数据处理服务,并具备丰富的运维管理功能,可以使用户从繁杂的运维管理和架构设计中脱离出来,从而专注于实现数据处理单元。 七牛数据处理平台的业务支撑能力如下:
Q&A
Q:请问管理系统是基于什么开发的?这个系统会开源吗?Q:刚开始看Mesos框架实现,请问自定义的Scheduler中如何调用自定义的executor?
A:Dora的调度框架是基本GO语言开发的。目前不会开源,但提供私有部署。
Q:请问目前Consul集群是多大规模呢?有没有考虑Consul扩展的性能瓶颈呢?
A:Schesuler跟executor这个都是按照Mesos最新的v1版的HTTP API去做的,这个没有不兼容的问题,只是mesos go版本的SDK有些老旧,更新也比较缓慢,这个地方我们自己根据需要做了些更改。
Q:Dora是否可以支持MySQL的自动伸缩扩容?
A:Consul是在每个slave节点上会有一个Consul的Agent ,我们一个机房有200多台专门用于数据处理的机器,所以Consul的集群规模也就这么大,单机房。对我们当前来说不存在瓶颈,因为我们对Consul的使用的场景相对单一简单:作为Metadata的可靠存储,Metadata的更新其实并不是很频繁,这个我们参考过别人做过的一些性能测试和我们自己的一些测试,性能是满足需求的。另外一个功能就是服务发现与实例的健康检查,健康检查是由运行在每个机器上的Consul Agent负责的,均摊到每个机器上,其实单个机器上的实例数不会特别的多,所以这部分也没有太大的压力。当然了,这个也是跟业务规模相关的,假定哪天Consul的扩展性成我们的问题了,也说明我们的业务量特别特别的大了,我们也是很期望这一天到来的。
Q:你们的Ansible host文件是动态生成的嘛?代码推送也是通过Ansible嘛?新增删除节点,以及回滚等操作是如何实现的?
A:Dora系统的应用场景还是运行一些数据处理命令这类无状态的服务。MySQL这类系统不适合直接跑在Dora这个里面,如果期望MySQL跑在Mesos上面的话,需要自己实现一个专门针对MySQL的调度器,因为MySQL实例的扩缩容,实例故障的修复都有MySQL自身特定的需求。我们公司MySQL这类有状态服务的容器化是由公司另一个容器平台实现的。MySQL的用的是Percona XtraDB Cluster方案,我们利用另一个容器平台的API写了一个Percona XtraDB Cluster的调度器,把Percona XtraDB Cluster的大部分运维操作在容器平台上自动化了。
Q:Dora的调度策略是怎么样的?可否简单介绍一下。
A:最开始实践的时候不是动态生成的,其实我们是可以从Consul中获取到当前集群里面的节点和节点的一些简单的配置信息,后面有考虑从Consul里面拿节点信息,动态生成用于Ansible灰度的host文件。代码推送也是使用的Ansible,如果能和外网连接的机器,也可以使用GitHub。因为我们的Playbook的角色是通过组件区分的,新增删除节点只需要修改Host文件,把相应的节点加入安装或删除相应的组件。如回滚操作:$ ansible-playbook rollback.yml -i hosts -e "hosts_env=XXX app_env=XXX version_env=XXX"
参数说明:
- hosts_env:表示要回滚的主机组,如Master
- app_env:表示要回滚的组件,如ZooKeeper
- xxx_version:表示要回滚组件的版本号,如v1.0.1.20160918
Q:Prometheus目前是单机的,数据量大了怎么办?Prometheus 的监控数据是存在InfluxDB吗?
A:首先保证同一种数据处理命令的实例尽量均匀分散在不同的机器上,然后再是保证均衡每个机器上的负载。
Q:这么大文件量,你们在存储技术方面有什么特别的处理吗?怎么实现高性能和海量存储之间均衡?
A:目前我们是按业务拆分server,数据量可以支撑。我们没有使用InfluxDB,还是用的原生的LevelDB。
以上内容根据2016年11月1日晚微信群分享内容整理。分享人陈爱珍,七牛云布道师,负责DevOps ,容器,微服务相关技术的落地研究与布道。多年企业级系统运维管理经验,对大型分布式系统架构设计及运维有丰富的经验。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesz,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。
A:七牛云存储的设计目标是针对海量小文件的存储,所以它对文件系统的第一个改变也是去关系,也就是去目录结构(有目录意味着有父子关系)。所以七牛云存储不是文件系统,而是键值存储,或对象存储。我们每个大文件都是切割成小文件存储下来的,元信息单独存放在数据库中,用户请求的时候通过业务层合并处理后返回。因此理论上磁盘只存储小文件,大文件存储和读取的性能主要在于文件切割和合并。
有疑问加站长微信联系(非本文作者)