Hulu大规模容器调度系统Capos

Hulu是美国领先的互联网专业视频服务平台,目前在美国拥有超过2000万付费用户。Hulu总部位于美国洛杉矶,北京办公室是仅次于总部的第二大研发中心,也是从Hulu成立伊始就具备重要战略地位的分支办公室,独立负责播放器开发,搜索和推荐,广告精准投放,大规模用户数据处理,视频内容基因分析,人脸识别,视频编解码等核心项目。java

在视频领域咱们有大量的视频转码任务;在广告领域当咱们须要验证一个投放算法的效果时,咱们须要为每种新的算法运行一个模拟的广告系统来产出投放效果对比验证;在AI领域咱们须要对视频提取帧,利用一些训练框架产出模型用于线上服务。这一切都须要运行在一个计算平台上,Capos是Hulu内部的一个大规模分布式任务调度和运行平台。python

Capos是一个容器运行平台,包含镜像构建,任务提交管理,任务调度运行,日志收集查看,metrics收集,监控报警,垃圾清理各个组件。整个平台包含的各个模块,以下图所示:git

 

用户能够在界面上建立镜像描述符,绑定github的repo,生成镜像。以后在界面上建立做业描述符,填上镜像地址,启动参数,资源需求,选择资源池,就能够运行做业,看做业运行日志等。这些全部操做也能够经过restapi来调用,对于一些高级的需求,capos提供golang和python的sdk,可让用户申请资源,而后启动做业,广告系统就是利用sdk,在capos上面申请多个资源,灵活的控制这些资源的生命周期,一键启动一个分布式的广告系统来作模拟测试。github

Capos大部分组件都是用Golang实现的,Capos的核心组件,任务调度运行CapScheduler是今天主要和你们分享和探讨的模块。CapScheduler是一个基于mesos的scheduler,负责任务的接收,元数据的管理,任务调度。CapExecutor是mesos的一个customized executor,实现Pod-like的逻辑,以及pure container resource的功能,在设计上容许Capos用户利用capos sdk复用计算资源作自定义调度。golang

Capos Scheduler的架构图以下所示:算法

 

上图浅蓝色部分是mesos的组件,包括mesos master,mesos agent,mesos zookeeper。mesos做用是把全部单体的主机的资源管理起来,抽象成一个cpu,memory,port,gpu等的资源池,供之上的capos scheduler使用。docker

其中capos scheduler是一个active-standy的HA模型,在scheduler中咱们实现了一个raft based的k-v用来存储metadata,active的scheduler注册成为mesos之上的一个framework,能够收到资源,根据调度策略来启动做业。数据库

Capbox是一个定制实现的mesos的executor,做为mesos agent的资源的占位符,接收请求与mesos agent上的docker daemon通讯启动容器。其中也实现了POD-like的功能,同时能够启动多个容器共享network,磁盘等。编程

Capos scheduler提供两类做业运行,一个是简单做业直接在Capbox运行,另外一个是复杂带有编程语义的做业,咱们称之为appmaster,其自己运行占用一个capbox,而后经过编程语义二次申请capbox运行做业。json

首先说明下简单做业运行流程,这里的简单做业,提交的做业经过json描述,能够包含多个container,而后scheduler收到请求以后,命中某个offer,向mesos发送offer启动请求,在请求中同时夹带着做业json信息,把做业启动起来,scheduler根据mesos状态同步信息来控制做业的生命周期。

若是是appmaster programmatically二次调度的做业,首先须要把appmaster启动,这部分和简单做业运行是一致的,而后appmaster再申请一个到多个资源来启动capbox,运行做业。此时appmaster申请的capbox的生命周期彻底由appmaster决定,因此这里appmaster能够复用capbox,或者批量申请capbox完成本身特定的调度效果。多说一句,appmaster能够支持client-mode和cluster-mode,client-mode是指appmaster运行在集群以外,这种状况适用于把appmaster嵌入在用户原先的程序之中,在某些场景更符合用户的使用习惯。

说完capos的使用方式后,咱们能够聊下在capos系统中一些设计的思考:

1 Scheduler的调度job和offer match策略,以下图所示:

 

1.1 缓存offer。当scheduler从mesos中获取offer时候,capos scheduler会把offer放入到cache,offer在TTL后,offer会被launch或者归还给mesos,这样能够和做业和offer的置放策略解耦。 

1.2 插件化的调度策略。capos scheduler会提供一系列的可插拔的过滤函数和优先级函数,这些优先级函数对offer进行打分,做用于调度策略。用户在提交做业的时候,能够组合过滤函数和优先级函数,来知足不一样workload的调度需求。

1.3 延迟调度。当一个做业选定好一个offer后,这个offer不会立刻被launch,scheduler会延迟调度,以期在一个offer中match更多做业后,再launch offer。获取更高的做业调度吞吐。

2 Metadata的raft-base key value store

2.1 多个scheduler之间须要有一个分布式的kv store,来存储做业的metadata以及同步做业的状态机。在scheduler downtime切换的时候,新的scheduler能够接管,作一些recovery工做后,继续工做。

2.2 基于raft实现的分布式一致性存储。Raft是目前业界最流行的分布式一致性算法之一,raft依靠leader和WAL(write ahead log)保证数据一致性,利用Snapshot防止日志无限的增加,目前raft各类语言均有开源实现,不少新兴的数据库都采用 Raft 做为其底层一致性算法。Capos利用了etcd提供的raft lib (https://github.com/coreos/etcd/tree/master/raft), 实现了分布式的一致性数据存储方案。etcd为了加强lib的通用性,仅实现了raft的核心算法,网络及磁盘io须要由使用者自行实现。Capos中利用etcd提供的rafthttp包来完成网络io,数据持久化方面利用channel并行化leader的本地数据写入以及follower log同步过程,提升了吞吐率。

2.3 Capos大部分的模块都是golang开发,因此目前的实现是基于etcd的raft lib,底层的kv存储能够用boltdb,badger和leveldb。有些经验能够分享下,在调度方面咱们应该关注关键路径上的消耗,咱们起初有引入stormdb来自动的作一些key-value的index,来加速某些带filter的查询。后来benchmark以后发现,index特别在大规模meta存储以后,性能降低明显,因此目前用的纯kv引擎。在追求高性能调度时候,写会比读更容器达到瓶颈,boltdb这种b+ tree的实现是对读友好的,因此调度系统中对于kv的选型应该着重考虑想leveldb这种lsm tree的实现。若是更近一步,在lsm tree基础上,考虑kv分离存储,达到更高的性能,能够考虑用badger。不过最终选型,须要综合考虑,因此咱们底层存储目前实现了boltdb,badger和leveldb这三种引擎。

3 编程方式的appmaster

3.1 简单的做业能够直接把json描述经过restapi提交运行,咱们这边讨论的是,比较复杂场景的SaaS,可能用户的workload是一种分布式小系统,须要多个container资源的运行和配合。这样须要capos提供一种编程方式,申请资源,按照用户须要前后在资源上运行子任务,最终完成复杂做业的运行。

3.2 咱们提供的编程原语以下, Capbox.go capbox是capos中资源的描述

package client

import (
    "capos/types/server"
)

type CapboxCallbackHandler interface {
    OnCapboxesRunning(*prototypes.Capbox) error
    OnCapboxesCompleted(*prototypes.Capbox) error
}

type RecoveryCapboxHandler interface {
    GetCallbackHandler(string) (CapboxCallbackHandler, error)
}

type AMSchedulerLifeCycle interface {
    Start(*prototypes.AMContext) (*prototypes.RegisterAMResponse, error)
    Stop() error
}

type AMSchedulerAction interface {
    // container resource api
    CreateCapbox(*prototypes.CapboxRequest, CapboxCallbackHandler) (*prototypes.Capbox, error)
    ReleaseCapbox(string) error

    PreviousStateRecovery(*prototypes.RegisterAMResponse, RecoveryCapboxHandler) error
    PreviousStateDrop(*prototypes.RegisterAMResponse) error

    GetCapAgentsSnapshot() ([]*prototypes.CapAgent, error)

    ListenCapboxStateChange()
    StopListenCapboxStateChange()
}

appmaster能够用这些api能够申请资源,释放资源,获取资源的状态更新,在此基础上能够实现灵活的调度。

Task.go task也就是能够在capbox上运行的task, 以下图所示

package client

import (
    "capos/types/server"
)

type TaskCallbackHandler interface {
    OnTaskCompleted(*prototypes.CapTask) error
}

type RecoveryTaskHandler interface {
    GetCallbackHandler(capboxId string, taskId string) (TaskCallbackHandler, error)
}

type AMCapboxLifeCycle interface {
    Start() error
    Stop() error
}

type AMCapboxAction interface {
    // task management api
    StartTask(*prototypes.Capbox, *prototypes.CapTaskRequest, TaskCallbackHandler) (*prototypes.CapTask, error)
    StopTask(*prototypes.Capbox, string) error
    ListTask(*prototypes.Capbox) ([]*prototypes.CapTask, error)

    PreviousStateRecovery(*prototypes.RegisterAMResponse, RecoveryTaskHandler) error

    ListenCapTaskStateChange()
    StopListenCapTaskStateChange()
}

在资源基础上,appmaster能够用api启动/中止做业,appmaster也能够复用资源不断的启动新的做业。基于以上的api,咱们能够把广告模拟系统,AI框架tensorflow,xgboost等分布式系统运行在Capos之上。

4 capos对比下netflix开源的titus和kubernetes

4.1 netflix在今年开源了容器调度框架titus,Titus是一个mesos framework, titus-master是基于fenso lib的java based scheduler,meta存储在cassandra中。titus-executor是golang的mesos customized executor。由于是netflix的系统,因此和aws的一些设施是绑定的,基本上在私有云中不太适用。

4.2 Kubernetes是编排服务方面很出色,在扩展性方面有operator,multiple scheduler,cri等,把一切能够开放实现的都接口化,是众人拾柴的好思路,可是在大规模调度短做业方面仍是有提高空间。

4.3 Capos是基于mesos之上的调度,主要focus在大规模集群中达到做业的高吞吐调度运行。

在分布式调度编排领域,有诸多工业界和学术界的做品,好比开源产品Mesos,Kubernetes,YARN, 调度算法Flow based的Quincy, Firmament。在long run service,short term workload以及function call需求方面有service mesh,微服务,CaaS,FaaS等解决思路,私有云和公有云的百家争鸣的解决方案和角度,整个生态仍是颇有意思的。绝技源于江湖、将军发于卒伍,但愿此次分享能够给你们带来一些启发,最后感谢Capos的individual contributor(字母序): chenyu.zheng,fei.liu,guiyong.wu,huahui.yang,shangyan.zhou,wei.shao。 

相关文章
相关标签/搜索