基于 Docker 的 Serverless 架构实践
WalkerPitca
8年前
<h2><strong>一、计算的进化</strong></h2> <p>UCloud 是一个做 IaaS (基础设施即服务)的服务商, IaaS 本质上有三块:计算的虚拟化、网络的虚拟化、存储的虚拟化。</p> <p>其中计算的虚拟化本身是以主机 uhost 为主,后来面向一些虚拟机解决不了的问题,比如高性能的 DB 等一些需要很强计算能力的场景时推出了 uphost,可以页面上生产物理机;后来面向更传统的行业,推出了托管云项目,用户可以把机器托管到机架上面,当网络、虚拟机和物理机打通了,就是所谓的混合云的架构。</p> <p>下一个计算产品是什么?</p> <p>云计算是通过网络快速获取计算资源、网络资源和存储资源的,云计算本身的发展有不同的形态:基于 IaaS 的形态之上出现了 PaaS (平台基于服务)、BaaS (后端即服务)和 FaaS (函数基于服务)等类似的产品,。</p> <p>对于用户来说,PaaS 基本上解决了运维部署的工作,提供了代码托管的环境;但是 PaaS 需要自己写代码,而 BaaS 已经把服务提供好了,可以直接调用,但是如果很多个请求过来,PaaS 就无法同时执行; FaaS 会按照请求量执行函数,结束后就销毁掉,因此可以同时执行多个请求。</p> <p>FaaS 概念今年火起来是在 6 月份 martinfowler 上的一篇关于 Serverless 的博文,AWS 推出Lambda 的时候说:“ AWS 对一个应用的理解就是数据+函数+事件。”Lambda 支持 Python、Java 和 note.js,你可以按照它的方式写一个函数,并且可以在它的页面上设定有哪些事件的时候执行这个函数,这也是 FaaS 具体的形态。</p> <p>Serverless跟前面三者有相同之处也有区别,传统的架构是业务逻辑是放在一个数据化的 Sever 上面,但 Serverless 没有服务器,认证模块、DB、计算都是放在别人提供的服务上的,自身的客户端只要将这些服务按照逻辑组合起来就可以了。</p> <p>简单来说,提供这个服务的厂商来帮你搞定 Sever,你只管逻辑把它跟客户端串起来就可以,降低了自己写 Server 的门槛。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/93d05acc2d8dd7f335c72e4e82d86a58.png"></p> <p>在做计算的虚拟化的时候会购买大量的物理机,但是有很多物理机资源是空闲的,因为做虚拟化产品,最核心的部分是怎么管理物理机资源,用户申请到虚拟机的时候,怎么知道虚拟机分配到哪台物理机上面是合适的。按照物理机的负载权重来随机分配、按照一定比例分配都可以,但是每个人申请的虚拟机最后运行效率是不一样的,这就会导致物理机在运行过程中负载有高有低,从而导致大量的剩余资源。</p> <p>这个算法有没有改进的空间?如何把数以万台的服务器、大量的 CPU 和内存资源压榨出来?</p> <p>需求:</p> <p>•业务跑在虚拟机上,每次扩容都要向资源部门申请资源</p> <p>• 运维部门部署和运维工作量大</p> <p>• 剩余资源如何以更便于使用的方式提供出来</p> <h2><strong>二、通用计算的实现</strong></h2> <h3><strong>方案一:在这片物理机上面再生成一个非常大配置的虚拟机,专门给他们用,这样的话就可以把剩余资源给占了,避免浪费。</strong></h3> <p>虚拟化的问题:</p> <p>• 隔离性好,但调度粒度过大</p> <p>UCloud 的 IO 性能对比于业界的虚拟机要好,但是虚拟机的 IO 是托到本地盘而不是基于网络盘的,这就对在线迁移提了很高的要求,因为基于网络盘的虚拟机在线迁移只需要迁内存和整个设备的状态就可以了,而基于本地盘的在线迁移要把块设备的数据全部迁移过去,所以如果磁盘很大的话,就会导致迁移速度很慢,调度虚拟机时非常困难,或者时间周期很长。</p> <p>• 以资源为中心而不是以服务为中心</p> <p>申请虚拟机部署服务本质上还是以资源为中心的,要知道虚拟机的 ip,并且要部署、监控它等等。</p> <p>• ⽤户需要关心 vm 的部署和监控</p> <h3><strong>方案二:考虑使用 Docker</strong></h3> <p>好处:</p> <p>•更细的粒度</p> <p>• 更轻的调度</p> <p>• 易于部署</p> <p>• 计算资源做服务化打包,提供以服务为中心的视角 。如果一个程序打包成 Docker 的话,通过 Docker 为单位调度,调度的是这个服务,而不是资源。</p> <p>• 跨语⾔。任何语言按照 Docker 的标准打包起来的话就变成一个通用的、方便移植的东西,对语言没有任何限制。</p> <h3><strong>方案三:根据虚拟化和Docker 的好处采取内外结合的方案</strong></h3> <p>•问题: Docker 隔离性问题,以 Docker 为粒度提供对外服务并不安全,如果它有问题可能损坏运行环境。</p> <p>•解决:采用 vm+ Docker 的模式 ,将算法打包成 Docker , 以 restful 方式执行算法。</p> <p>产品架构图:</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/b7e5304503f099c7fb88f60e248c882b.png"></p> <p>ULB4是内网负载均衡,可以做到跨机房的容灾。</p> <p>openresty的目的是用于做灰度发布,当程序有更新的时候,把流量导到某个地方去。</p> <p>虚线框是产品完整的逻辑,每个set 都是平等的,并且是每个是独立的服务,其中一个挂了不会影响其他的服务,可以通过 set 去灰度一些重要功能:</p> <p>API 负责对外提供服务;</p> <p>TaskManger 负责调度;</p> <p>Executor 则是每个虚拟机都部署的,用来执行 Docker ;</p> <p>产品名词解释</p> <p>• Docker 镜像:计算任务的算法打包方式,将 Docker 镜像提交至 GeneralCompute 的镜像仓库,用于后面的计算任务提交</p> <p>• 任务:通过用计算服务提供的 http api 提交,任务内容包含:Docker 镜像路路径,算法输入。任务的输出由api 返回。任务分为同步任务及异步任务:</p> <p>1) 同步任务</p> <p>用于实时计算,客户端提交任务后等待api返回任务结果。</p> <p>2) 异步任务</p> <p>用于离线长耗时的计算,客户端提交任务后,api 返回任务 id, 客户端根据任务 id 查询任务状态及结果。</p> <p>服务使用方式:</p> <p>用户将服务打包成 Docker 并上传到 Docker仓库 ,通过HTTP API方式调用任务,拉起 Docker 完成计算,Docker 跑在 vm 集群中,位置和调度由 TaskManager 完成</p> <p>好处:</p> <p>忘掉资源,忘掉部署,专注算法</p> <p>产品优势:</p> <p>1)海量计算能力</p> <p>十万核级的计算能力,自动高效完成计算分布,你可以通过一套 api 享受到十万核级别的计算能力。</p> <p>2)以计算为中心</p> <p>用户无需要关心资源位置及环境部署,只需要专注自己的算法及通过 api 做任务编排就可以了。</p> <p>3)灵活易用</p> <p>以 Docker 方式打包自定义算法,支持 API 方式调用计算服务,易于集成到应用的业务流程。paas 有个重要的问题没解决,就是供应商绑定的问题,docker 提供的方案就很大程度地解决了这个问题。</p> <p>4)按需付费</p> <p>按实际消耗的计算资源计费,无需付出非计算资源(内存,磁盘)的费用,无需担心浪费。 这可能是最吸引用户的地方。</p> <p>5)自动扩容+高并发</p> <p>可以同时提交多个API,同时跑多个算法,算法跑在不同的节点上,完全是并发的,但是隐含了一个限制,就是这个任务必须是无状态的,这也是 FaaS 的要求。</p> <p>但是 Docker 的优点很明显,缺点也很明显,用户在使用 Docker 的过程中不应该追求最新的技术,应该根据自己的需求出发。</p> <h2><strong>三、通用计算的应用例子</strong></h2> <h3><strong>1.图片处理实践 - UFILE 图片处理</strong></h3> <p>ufile 是 UCloud 的类 S3 服务,用户提供一张图片,ufile 提供几种图片处理的算法,通过算法对图片进行缩略图、格式转换、旋转、打水印等操作,再给用户返回一张处理好的图片。</p> <p>需求:</p> <p>• 实时性</p> <p>• 跨语言的算法</p> <p>• 大并发。ufile的用户量很大。</p> <p>• 海量的计算</p> <p>实现:</p> <p>将ufile的图片处理算法打包成 Docker,基于数据流的实时计算,将输入流重定向到Docker实例的标准输入,图片处理算法读取标准输入并将处理结果输出到标准输出,管理程序将Docker标准输出变成HTTP流返回给用户。</p> <p>普通实现图解:用户通过 ufile api 将图片传到 server 上面,发现 URL 不一样调用不同的算法把图片处理完,再把图片返回给用户。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/f3334c62c40092f2b415a43dbc0e3f6f.png"></p> <p>使用 Serverless 架构实现图解:把算法打包成 Docker 镜像传到镜像仓库里,通过 api 把图片传过来,api 可以指定算法对应的镜像,就把图片返回去。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/c2d8e6a3b4bac4a8dcef75b1b20dbb7e.png"></p> <p>优点:</p> <p>• 节省了大量的物理机。</p> <p>• 节省了大量的人力。不需要写 server,只要写镜像,而且不用关心资源在哪里,和扩容和看镜像的问题。</p> <h3>2.图片处理实践 - OCR 识别</h3> <p>OCR 识别的作用是把题目扫描成图片,通过 opencv 和机器学习的方式识别题目的内容。</p> <p>需求:</p> <p>• 每天 1600 万的图片处理</p> <p>• 每张图片处理时间 2~3s</p> <p>• 算法优化依赖特殊的 CPU 指令</p> <p>实现:</p> <p>将opencv及机器学习模型打包成 docker 镜像,计算节点支持特殊 CPU 指令,并发执⾏。</p> <p>普通实现图解:用户把图片传给中控 Server ,中控 Server 是一个持久化的服务,里面的逻辑把图片识别完返回物理机集群里,但是写 Server 的门槛对于做机器学习的人员来说太高。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/8de5f5a8e7776454c94b2ec9492f0e1d.png"></p> <p>使用 Serverless 架构实现图解:将opencv及机器学习模型打包成 Docker 镜像后就没有 Server ,用户直接把图片通用的 api 传过来即可,相当于机器学习的模型在线化的服务。</p> <p style="text-align: center;"><img src="https://simg.open-open.com/show/1b1d71df9ef97f54f63537a22ecf79cb.png"></p> <p>优点:</p> <p>• 节省百台物理机</p> <p>• 算法优化不用考虑并发,只需专注单张图片的处理效率</p> <h2><strong>四、未来展望</strong></h2> <p>• 基于深度学习的图片处理</p> <p>• 基于通用计算平台的分布式训练</p> <p>• 基于通用计算平台的模型在线化服务</p> <p>• 科学计算</p> <p>• 基于通用计算的 paas & faas产品</p> <p> </p> <p>来自:https://my.oschina.net/osccreate/blog/792470</p> <p> </p>