作者 | 刘东东
来源 | 凌云时刻(微信号:linuxpk)
前言
AI 时代的到来,给企业的底层 IT 资源的丰富与敏捷提出了更大的挑战。利用阿里云稳定、弹性的 GPU 云服务器,领先的 GPU 容器化共享和隔离技术,以及 K8S 集群管理平台,好未来通过云原生架构实现了对资源的灵活调度,为其 AI 中台奠定了敏捷而坚实的技术底座。
在 2020 年云栖大会上,好未来 AI 中台负责人刘东东,分享了他对 AI 云原生的理解与好未来的 AI 中台实践,本文为演讲内容整理。
大家好,我是好未来 AI 中台技术负责人刘东东。今天我给大家带来的演讲主题是《好未来 AI 云原生的浅谈》。
我的分享主要分成四个部分:
第一,AI 服务对云原生的挑战。
第二,AI 与云原生的服务部署。
第三,AI 与云原生的服务治理。
最后想谈一谈, K8S 与 Spring Cloud 的有机结合。
AI 服务对云原生的挑战
首先,我们来讲一讲 AI 服务对云原生的挑战。在云原生时代,AI 服务其中最大的一个特点就是,需要更大的算力支持,以及更强大的一个服务的稳定性。
我们的服务不单单只是原来的一个单体服务,现在已经转入到一个集群服务。同时对性能的稳定性要求,已经从 3 个 9,开始向 5 个 9 发起了挑战。
那么这些问题,已经不再是原有的传统技术架构能够解决的。所以我们需要一个新的技术架构。
这个新的技术架构是什么呢?就是云原生。
我们来看一看,云原生对我们带来的变化。云原生带来的最大变化,我总结为四个要点和两大方面。
四大要点分别是,DevOps、持续交付、微服务、容器的四个特点。两个方面则是服务部署和服务治理。当然,它还有 12 个要素的整体系统总结。
今天重点来讲的是服务部署和服务治理。
在云原生浪潮下,我们是如何处理服务部署和服务治理呢?
首先我们通过 AI 与云原生的服务部署,即通过 K8S,加上一个资源的虚拟化,资源的池化等技术,解决了 AI 服务对各种硬件资源的数量级增长需求。
第二个,AI 服务与云原生的服务治理进行有机结合。通过服务治理的技术,包括服务发现、HPA、负载均衡等,解决 AI 服务对 5 个 9 的 SLA 的需求。
AI 服务的云原生部署
第一点谈一下是怎么把 AI 与云原生的服务部署结合起来的。
首先看一下,在 AI 时代下服务部署有哪些特点呢?
第一个就是硬件资源需求与费用增长的一个矛盾。AI 服务对于硬件的需求成数量级增长,但是硬件预算并没有成数量级增长。
第二,AI 服务对硬件的需求是多样化的。如,对高 GPU 的需求、高 CPU 的需求、高内存的需求,甚至还有部分混合的需求。
第三,AI 服务对资源的隔离是有需求的。每一个 AI 服务都能够独立使用这些资源,并且相互之间不会打扰。
第四,AI 服务能够对资源池化有要求。AI 服务不需要去感知机器的具体配置,一旦将所有的资源进行池化,即可降低资源碎片,提升使用率。
最后一点,AI 服务对突发的资源是有请求的。因为流量是不可预知的,企业需要随时保持,能够随时扩充资源池的能力。
我们的解决方案是什么呢?
首先,我们使用 Docker 的虚拟化技术,实现资源的隔离。
然后使用 GPU 共享技术,将 GPU、内存、CPU 等资源进行池化,然后将整个资源进行统一的管理。
最后,使用 K8S 的 resources,包括污点(taints)、容忍度(tolerations)等这些技术特性,实现服务的灵活配置。
另外,建议大家要买一些高配置的机器,这些高配置的机器,主要是为了进一步降低碎片。
当然,还要实现对整个集群硬件的监控,充分利用 ECS 可以各种复杂的时间规则调度特性(下图的 cron 是一个基于时间的作业调度任务),应对高峰流量。
接下来,我们更仔细地看看好未来 AI 中台是如何解决这些 AI 部署问题的。
这个页面是我们的一个 Node 的服务管理,通过这个业务,我们是可以清晰看到每一个服务器上面的部署情况,包括资源使用情况、部署哪些 pod、哪些节点等等。
第二个实际上是 AI 中台的服务部署页面。我们是可以通过压码文件,精准地控制每一个 pod 的内存、CPU、GPU 的使用。同时,通过污点等技术,让服务器的多样化部署得到满足。
根据我们的对比实验,使用云原生的方式部署对比用户自行部署,成本大概节省了 65%。而且,这样的优势会随着 AI 集群的增长,在经济收益上和临时流量扩容上,将会受益更多。
AI 与云原生服务治理
接下来再讨论一下 AI 与云原生的服务治理。
简单介绍一下什么叫微服务?其实微服务,只是服务的一种架构风格,它实际上是将单个服务,作为一整套的小型服务开发,然后每一个应用程序都有自己进程去运行,并且通过轻量级的一些,比如说 HTTP、API 等进行通信。
这些服务,实际上是围绕着业务本身去构建的,可以通过自动化的部署等手段去集中管理。同时,通过不同的语言去编写,使用不同的存储资源。
总结起来微服务有哪些特点?
第一,微服务它足够小,甚至它只能做一件事情。
第二,微服务是无状态的。
第三,微服务相互之间是相互独立的,并且它们是面向接口的。
最后,微服务是高度自治的,每个人只对自己负责。
看到这些微服务的特点之后,再去想一想,AI 服务与微服务特点,我们发现,AI 服务天生适合微服务。每一个微服务,其实本质上只做一件事情。比如 OCR,OCR 服务,只做 OCR 服务;ASR,主要做 ASR 服务。
继而,每一个 AI 服务的请求都是独立的。举个简单例子,一个 OCR 请求和另外一个 OCR 请求,在本质上是没有什么关联的。
AI 服务对横向扩容是有天生苛求的。为什么?因为 AI 服务队资源的渴求非常大。于是,这种扩容就显得非常有必要性了。
AI 服务之间的依赖性也特别小。比如说像我们的 OCR 服务,可能对 NLP 的服务,或者是对其它的 AI 服务,可能没有什么太大的要求。
所有的 AI 服务,都可以通过写申明式的 HTTP,甚至 API 的方式,提供 AI 能力。
进一步去看一下 AI 服务,会发现,并不能将所有的 AI 服务进行微服务化。于是,我们做了什么事?
第一,需要将 AI 服务做成一个无状态的服务,这些无状态服务,都是有畜牲化、无状态、可丢弃,并且不采用任何的一些磁盘或者内存的请求方式,去做一些存储功能。这样就可以让服务部署在任何的一个节点,任何一个地方。
当然,并不是所有的服务都能做到无状态。如果它有状态了怎么办呢?我们会通过配置中心、日志中心、Redis、MQ,还有 SQL 等数据库,存储这些请求状态。同时,确保这些组件的高可靠性。
这个就是好未来 AI 中台 PaaS 的整体架构图。首先可以看一下最外层是服务接口层。最外层接口层是面向外部提供 AI 能力的。
平台层里最重要的层是服务网关,主要是负责一些动态路由、流量控制、负载均衡、鉴权等。再往下就是我们的一些服务发现,注册中心,容错、配置管理、弹性伸缩等等一些功能。
再下面是业务层,这些业务层就是我们所说的,一些 AI 的推理服务。
最下面就是阿里云给我们提供的 K8S 集群。
也就是说整体的一个架构是,K8S 负责服务部署,SpringCloud 负责服务治理。
我们是怎么通过技术手段来实现刚才说的一个整体架构图?
首先是通过 Eureka 作为注册中心,实现分布式系统的服务发现与注册。通过配置中心 Apoll 来管理服务器的配置属性,并且支持动态更新。网关 Gateway,可以做到隔离内外层的效果。熔断 Hystrix,主要是分为分时熔断和数量熔断,然后保护我们的服务不被阻塞。
负载均衡加上 Fegin 操作,可以实现整体流量的负载均衡,并且将我们的 Eureka 相关注册信息进行消费。消费总线 Kafka 是异步处理的组件。然后鉴权是通过 Outh2+RBAC 的方法去做的,实现了用户的登录包括接口的鉴权管理,保证安全可靠。
链路追踪,采用的是 Skywalking,通过这种 APM 的一个架构,我们可以追踪每一个请求的情况,便于定位和告警每一个请求。
最后日志系统是通过 Filebeat+ES,分布式收集整个集群的日志。
同时我们也开发了一些自己的服务,比如说部署服务、Contral 服务。主要是负责与 K8S 进行通信,收集整个 K8S 集群里面服务的服务部署、K8S 相关的硬件信息。
然后告警系统是通过 Prometheus+Monitor 去做的,可以收集硬件数据,负责资源、业务等相关的告警。
数据服务是主要用于下载,包括数据回流,然后截取我们推理场景下的数据情况。
限流服务是限制每个客户的请求和 QPS 相关功能。
HPA 实际上是最重要的一个部分。HPA 不单单只支持内存级别的,或 CPU 级别的 HPA,还支持一些 P99、QPS、GPU 等相关规则。
最后是统计服务,主要是用于统计相关调用量,比如请求等。
我们通过一个统一的控制台,对 AI 开发者提供了一站式的解决方案,通过一个平台解决了全部的服务治理问题,提升了运维的工作自动化,让原来需要几个人维护的一个 AI 服务的情况,变成了一个人能够做到维护十几个 AI 服务。
这个页面展示的就是服务路由、负载均衡、限流相关的配置页面。
这个页面展示的是我们在接口级别的一些告警,以及部署级别的硬件告警。
这是日志检索,包括实时日志相关功能。
这个是手动伸缩和自动伸缩操作页面。其中自动伸缩包括 CPU、内存级别的 HPA,也包括基于相应响应时长制定 HPA、定时的 HPA。
K8S 与 Spring Cloud 的有机结合
最后来聊一下 K8S 与 SpringCloud 的有机结合。
可以看一下这两张图。左图是我们 SpringCloud 数据中心到路由的图。右边是 K8S 的 service 到它的 pod 的图。
这两个图在结构上是非常接近的。我们是怎么做到呢?实际上是将我们的 Application 与 K8S 的 service 进行绑定,也就是说最终注册到我们 SpringCloud 里面 LB 的地址,实际上是把它转成了 K8S service 的地址。这样就可以将 K8S 与 SpringCloud 结合起来。这是路由级别集合。有了这个集合,就能达到最终的效果。
SprigCloud 它是一个 Java 的技术语言站。而 AI 服务的语言是多样化的,有 C++、Java,甚至有 PHP。
为了实现跨语言,我们引入了 sidecar 技术,将 AI 服务与 sidecar 通过 RPC 去通信,就可以屏蔽语言的特性。
Sidecar 主要的功能有,应用服务发现与注册、路由追踪、链路追踪,以及健康检查。