重新定义容器化 Serverless 应用的数据访问

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 本文首先聚焦到 AI 和大数据等应用 Serverless 化的最大挑战:计算和存储分离架构带来的数据访问延迟和远程拉取数据带宽巨大的挑战。尤其在 GPU 深度学习训练场景中,迭代式的远程读取大量训练数据方法会严重拖慢 GPU 计算效率。

作者:车漾、刘奖、景奇


随着 IT 基础设施从物理机到虚拟机,再到以 Kubernetes 为代表的容器环境,甚至到 Serverless 的逐渐演进,今天的计算和应用的形态以一日千里的速度发展。尤其是 AI 和数据分析等数据智能应用的 Serverless 化已经成为了一种趋势。 Gartner 曾预测,到 2023 年 70% 的 AI 应用将基于容器和 Serverless 技术开发。这是大家相信的未来,但应用 Serverless 化之路充满艰辛,比如现有应用迁移门槛高供应商锁定基础设施响应能力不足可观测性欠缺存储接入繁琐等。


这些都是用户对于 Serverless 基础平台提供商的刚性需求,谁能更加开放,谁能更好提供 Serverless 应用所运行的基础设施和生态系统,谁才能成为客户的最终选择,而不仅仅是谁提供的计算资源弹性能力更强或者成本更低,这实际是云计算巨头的内功较量。


1.png

(图片来源于网络)


本文首先聚焦到 AI 和大数据等应用 Serverless 化的最大挑战:计算和存储分离架构带来的数据访问延迟和远程拉取数据带巨大的挑战。尤其在 GPU 深度学习训练场景中,迭代式的远程读取大量训练数据方法会严重拖慢 GPU 计算效率。

Serverless 的数据访问挑战


Serverless 云平台对用户提供的核心能力就是极致弹性,但是这里讨论的弹性并不只是资源弹性,而是站在用户视角的应用弹性或者说业务弹性,即从用户决定扩容开始到应用真正就绪提供服务的端到端时间。资源弹性时间是其中很重要的部分,计算资源能够实现秒级,甚至毫秒级扩容,相关基础设施就很快会面临巨大的压力,其中最常见的基础设施就是存储。如果存储系统的 IO 吞吐能力跟不上实例变化的速度,例如对于业务来说,容器实例 2 秒就完成了扩容,但还需要花几十秒钟甚至几分钟等待从存储下载数据,那么极致弹性也就无从谈起。


应该说 Serverless 容器化的技术体系对于传统的存储系统提出了新的挑战:


1. 高密访问:

计算资源无存储能力,数据完全下沉到存储系统,导致并发数据访问压力陡增。这一方面影响存储系统的稳定性,另一方面也会打满存储系统服务带宽。


2. 网络延时:

计算存储分离架构拉长了存储访问链路,跨网络通信数据和元数据访问的额外延迟。


3. IO 吞吐能力的扩容成本高:

传统分布式存储带宽与吞吐仅和数据使用容量成正比,而 Serverless 平台会创建大量的容器并发的访问存储系统的数据,会触发存储系统访问限流。这就造成计算资源极致弹性与存储系统有限带宽之间的矛盾。


换而言之,Serverless 的大数据和 AI 场景需要数据分流(Data Offloading),缩短数据读取链路和提供弹性的 IO 吞吐能力。但是考虑到现有云存储系统的稳定性,成本和通用性,这个架构演进会是一个任重道远的工作。

Fluid:应用使用数据过程的抽象


Fluid 是云原生计算基金会(CNCF)旗下的官方沙箱开源项目。该开源项目定位于面向云原生场景下的数据密集型应用加速和编排,社区主要开发者和维护者来自阿里巴巴、南京大学等多家知名企业和高校。Fluid 的思路是将存储系统的能力进行分层,分解为数据存储和数据访问能力,并且将一部分的数据访问能力向上平移到计算集群中;并且在大数据(AI)场景下,对“计算任务使用数据的过程”进行抽象,提出了弹性数据集 Dataset 的概念,并将数据分布式缓存技术与云原生自动弹性(Autoscaling),可迁移(Portablity),可调度(Scheduling)能力相结合。


Fluid 项目地址:
https://github.com/fluid-cloudnative/fluid


2.png


数据访问能力向上平移的好处是可以利用计算集群中闲置的资源,通过分布式数据缓存能力一方面提供数据分流降低中心存储压力,另一方面利用数据本地性,VPC 网络性能优势和数据访问复用的特性,缩短数据访问路径,提升性能;通过 Dataset 的抽象,在特定语境下,根据应用的需求定义数据访问的范围,特征以及弹性,并且根据这些特性进行特定性能优化。


All problems in computer science can be solved by another level of indirection


实际上 Fluid 还是遵循计算科学中的所有问题都可以通过增加一层抽象来解决的原则,在 Kubernetes 为代表的计算集群提供数据访问编排层 Dataset 抽象, 实现 Dataset 管理(CRUD 操作)、数据预热,数据备份/恢复权限控制和访问加速等能力,Fluid 的架构可以通过 CacheRuntime plugin 的方式,扩展兼容多种分布式缓存服务。目前已经支持了阿里云 EMR 的 JindoFS,开源的 Alluxio,Juicefs 等缓存引擎, 而对于用户来说这是一个透明的体验。


没有银弹,Fluid 的实质是利用计算集群的空闲资源(CPU,Memory,Disk)和特定场景的抽象假设简化问题,通过数据分流(Data Offloading降低中心存储的压力;就近缓存(Tiered Locality Cache)亲和性调度(Cache Locality Scheduling)提升数据访问性能;在计算资源高并发访问数据的时候,通过自动化扩容缓存集群提供弹性 IO 吞吐能力


3.png


在此基础上,Fluid 支持数据弹性和可操作性,能够根据计算吞吐需求实现:


  1. 数据集的可伸缩性——Fluid 支持 Runtime 弹性伸缩的模式,通过控制缓存 worker 的数量实现弹性伸缩。


  1. 数据集合的可操作性——Fluid 支持通过 Dataload CRD 来进行多种模式的预热,包括指定文件列表、文件夹的元数据进行预热。

从下到上优化,Fluid 拥抱阿里云 ECI


因此如何将分布式缓存引擎落地到 Serverless 容器化平台就成了一个挑战。而其中的关键问题是如何能够安全,开放,灵活的在 Serverless 容器化平台中运行。将 Fluid 开源软件与 Serverless 平台相结合加速应用访问数据性能在业界是第一次尝试,需要双方相向而行,共同定义协作的界面和权责, 否则改变不会发生。Fluid 需要尊重 Serverless 平台的概念模型和生命周期(比如一个 Pod 占用一个虚拟机的模式),Serverless 平台需要提供基于一定标准的最小开放性。


这背后主要有三个问题:


1. 协议与分工界面不清:Serverless 平台是黑盒系统,运行时支持都是由平台提供商开发的,对于 Kubernetes 生态的支持并不完善。比如多数 Serverless 不支持社区广泛支持的 CSI Plugin、Device Plugin 机制等。传统的方式是将各种存储系统客户端注入 Serverless Pod 运行的虚拟机镜像,但这就要面对虚拟机镜像管理就要面对绑定严重,升级困难,镜像臃肿等问题,同时软件问题排查时边界不清。


2. 安全风险和开放性的平衡:Serverless 平台一定是多租户的,因此平台安全性是生命线。但是 Serverless 赋能更多场景,就需要支持更多的开源软件,而这时一定会引入更多个攻击面;因此需要仔细的权衡二者之间关系。这非常考验平台的硬核实力,也需要软件供应链的控制能力。


3. 分布式与 Serverless 之间的冲突: Serverless 应用假设执行的是简单的、独立的任务,相互间不通信,同时计算任务完全无状态;生命周期管理也要差异。 然而,Fluid 本身是要通过分布式缓存系统实现提速的。这里涉及到的分布式(网络通信),有状态(缓存),生命周期一致性,又是一个矛盾点。


为了支持 Serverless 场景,阿里云容器服务团队,基础软件和操作系统团队,弹性计算 ECI 团队,数据湖存储团队联合作战,提供了从底到顶的完整解决方案。解决问题的基本思路是对不同的问题分而治之,而原则是:


  • 拥抱已有标准,比如通过 Kubernetes 中 Sidecar,Device Plugin 等标准作为开放接口。保障用户一致性体验。
  • 精细化 Linux 特权控制
  • 关注点分离,让不同的角色关注自己的能力,存储和计算可以并行演进。


最终的方案是:通过 Sidecar 机制透明替换 Perstistent Volume Claim,并且对于现有 FUSE 方案 进行安全加固;同时将分布式缓存和弹性能力运行在 ServerFull 节点(ECS);另外针对包含 Sidecar 的任务应用进行特殊的支持。

价值


开放标准


对于存储能力提供方,存储组件无需与 Serverless 平台直接对接,由开源的 Fluid 扮演适配角色,标准公开同时降低计算平台维护存储客户端的复杂度。对于用户来说,以 sidecar 模式运行存储客户端,云上和云下使用体验基本一致, 同时无需担心平台绑定。


关注点分离


关注点分离是 Fluid 用来解决存储能力提供者与 Serverless 平台团队缺乏责任分层的困境。


对于存储能力提供团队,不需要将存储客户端以安装包的方式加载到虚拟机,这样就可以独立迭代自身能力,无需依赖 Serverless 平台团队虚拟机镜像发布节奏;同时问题排查时也无需等待 Serverless 平台团队收集日志,提升了问题诊断和修复的效率。


对于 Serverless 平台团队,存储组件作为 sidecar 存在,减小的虚拟机镜像中软件的复杂度和大小,同时也避免了频发发布虚拟机镜像引入的稳定性风险,降低了问题排查的复杂度。


弹性


可以与分布式存储相结合,通过用户使用自身计算集群的资源,按需的实现吞吐能力扩容。一方面为用户提供了弹性按 IO 需求付费的选择,也降低了存储的成本压力。

安全


通过精细化特权控制,实现 Serverless 下一定的程度实现能力分层,在开放的前提下为底层平台提供安全保障。

可观测


传统存储客户端以进程方式运行在 Serverless 平台中,健康状态和资源消耗都是黑盒;存储客户端问题排查也需要依赖 Serverless 平台运维,而新的模式下,存储客户端以容器的形态运行,提供了完整的可观测性。

快速体验


该实验模拟模型推理服务启动时下载并且初始化模型。


前置条件



操作步骤


1. 查看 Fluid 是否安装成功以及版本是否是最新:


$ helm list -n fluid-system
NAME        NAMESPACE       REVISION    UPDATED                                 STATUS      CHART           APP VERSION
ack-fluid   fluid-system    1           2022-08-13 16:05:47.540883158 +0800 CST deployed    ack-fluid-0.8.1 0.8.0-50edf67


2. Fluid 依赖 Webhook 机制注入 Serverless 依赖的 sidecar


$ kubectl label namespace default fluid.io/enable-injection=true


3. 检查 namespace 的标签是否成功打开


$ kubectl get namespace default --show-labels
NAME      STATUS   AGE     LABELS
default   Active   5h28m   fluid.io/enable-injection=true


4. 创建数据集和缓存运行时


本示例使用 JindoFS 作为数据集的缓存引擎并挂载一个 OSS Bucket,OSS Bucket 中存储着应用需要访问的数据集。该 OSS Bucket 位于北京地域,Bucket 名为 large-model-sh。在实际使用中,请根据实际使用的 OSS Bucket 属性进行修改。


4.1 创建 Secret 加密 Access Key


$ cat << EOF > secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: access-key
stringData:
  fs.oss.accessKeyId: <YOUR_ACCESS_KEY_ID>
  fs.oss.accessKeySecret: <YOUR_ACCESS_KEY_SECRET>
EOF


4.2 上述例子中的 Access Key 可在 RAM 访问控制页面查询


$ kubectl create -f secret.yaml


4.3 创建 Dataset 和 JindoRuntime


$ cat << EOF > dataset.yaml
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: serverless-data
spec:
  mounts:
  - mountPoint: oss://large-model-sh/
    name: demo
    path: "/"
    options:
      fs.oss.endpoint: oss-cn-beijing-internal.aliyuncs.com
    encryptOptions:
      - name: fs.oss.accessKeyId
        valueFrom:
          secretKeyRef:
            name: access-key
            key: fs.oss.accessKeyId
      - name: fs.oss.accessKeySecret
        valueFrom:
          secretKeyRef:
            name: access-key
            key: fs.oss.accessKeySecret
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
  name: serverless-data
spec:
  replicas: 1
  tieredstore:
    levels:
      - mediumtype: MEM
        path: /dev/shm
        quota: 10Gi
        high: "0.95"
        low: "0.7"
EOF


相关参数:


4.png


4.4 执行以下步骤


$ kubectl create -f dataset.yaml


4.5 查看 Dataset 状态:


$ kubectl get dataset serverless-data 
NAME              UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
serverless-data   1.16GiB          0.00B    10.00GiB         0.0%                Bound   80s


4.6 对应会创建 pvc


$ kubectl get pvc
NAME              STATUS   VOLUME                    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
serverless-data   Bound    default-serverless-data   100Gi      ROX            fluid          91s


5. 创建基于 ECI 的 Deployment 访问数据集


$ cat << EOF > serving.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: model-serving
spec:
  selector:
    matchLabels:
      app: model-serving
  template:
    metadata:
      labels:
        app: model-serving
        alibabacloud.com/fluid-sidecar-target: eci
        alibabacloud.com/eci: "true"
      annotations:
         k8s.aliyun.com/eci-use-specs: ecs.s6-c1m2.xlarge
    spec:
      containers:
        - image: fluidcloudnative/serving
          name: serving
          ports:
            - name: http1
              containerPort: 8080
          env:
            - name: TARGET
              value: "World"
          volumeMounts:
            - mountPath: /data
              name: data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: serverless-data
EOF


  • labels中alibabacloud.com/eci: "true"表示该容器以 ECI 容器方式启动 


  • labels 中 alibabacloud.com/fluid-sidecar-target "eci"告知 Fluid 该 Pod 以 Serverless 方式启动,Fluid 会利用 Webhook 自动向应用 Pod 注入 Fuse 容器,让应用 Pod 可通过 POSIX 接口访问数据集 


  • annotations 中的 k8s.aliyun.com/eci-use-specs 表示使用的 ECI 实例规格


6. 创建 Deployment


$ kubectl create -f serving.yaml


7. 查看启动日志,可以看到启动加载数据的时间是 64s


$ kubectl logs model-serving-546578c447-5x6fm -c serving
Begin loading models at 16:35:38
real    1m4.999s
user    0m0.000s
sys 0m1.143s
Finish loading models at 16:36:43
2022-08-13 16:36:43 INFO Hello world sample started.


8. 删除该服务


$ kubectl delete -f serving.yaml


9. 预热缓存数据, 该步骤不是必须执行的操作


$ cat<<EOF >dataload.yaml
apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
  name: serverless-data-warmup
spec:
  dataset:
    name: serverless-data
    namespace: default
EOF


执行 Dataload, 并查看缓存效果。可以看到 1.2G 数据已经完全缓存了。


$ kubectl create -f dataload.yaml
dataload.data.fluid.io/serverless-dataload created
$ kubectl get dataload
NAME                  DATASET           PHASE      AGE     DURATION
serverless-dataload   serverless-data   Complete   2m43s   34s
$  kubectl get dataset
NAME              UFS TOTAL SIZE   CACHED    CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
serverless-data   1.16GiB          1.16GiB   10.00GiB         100.0%              Bound   19m


10. 再次创建该服务


$ kubectl create -f serving.yaml


此时查看启动时间发现当前启动加载数据的时间是 6.263s,变成没有预热的情况下耗时的 1/10,速度提升了 10 倍


kubectl logs model-serving-546578c447-pkcpf  -c serving
Begin loading models at 17:18:54
real    0m6.263s
user    0m0.000s
sys 0m0.998s
Finish loading models at 17:19:00
2022-08-13 17:19:04 INFO Hello world sample started.


更多使用方法请参考文档:

https://help.aliyun.com/document_detail/440049.html

展望


Fluid 与 Serverless 场景的结合只是刚刚开始,和 Serverless 同行(With the Serverless),与 Serverless 协作(On the Serverless),服务好 Serverless(For the Serverless)。 在第一阶段,我们与 JindoFSX Runtime 一起实现了 Serverless 无缝对接,后续我们也会支持开源社区的 JuiceFS,Alluxio;同时我们在内核和容器层面的修改也会贡献到社区,一起推动 Serverless 平台的改变。


致谢


Fluid 支持 Serverless 的工作感谢来自阿里云,南京大学,Juicedata,哔哩哔哩的小伙伴们共同努力,这是 Serverless 支持数据场景的第一步,我们一起加油来让云的世界更加美好。如果您有兴趣也可以钉钉搜索群号:32850151,加入 Fluid 开源社区技术交流群。如果您认为 Fluid 有用的话,欢迎与感谢您给 Fluid 项目一个 star。


Fluid 的代码仓库地址为:

https://github.com/fluid-cloudnative/fluid 


5.jpeg


作者简介:


车漾,阿里云容器服务高级技术专家

刘奖,阿里云操作系统部资深技术专家

景奇,阿里云弹性计算技术专家




如何高效调度 AI 和大数据作业?怎样提高 GPU 等资源效率和弹性?快来尝试 ACK 云原生 AI 套件吧!基于标准 Kubernetes,提供组件化、可扩展、可灵活组合和定制的云原生 AI 能力,全栈优化 AI 性能、效率和成本,助力企业级用户快速定制化构建 AI 平台。戳此处链接领取 2022 年免费体验席位

相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
相关文章
|
6天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
6天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
8天前
|
运维 开发者 Docker
Docker Compose:简化容器化应用的部署与管理
Docker Compose:简化容器化应用的部署与管理
|
14天前
|
JavaScript 持续交付 Docker
解锁新技能:Docker容器化部署在微服务架构中的应用
【10月更文挑战第29天】在数字化转型中,微服务架构因灵活性和可扩展性成为企业首选。Docker容器化技术为微服务的部署和管理带来革命性变化。本文探讨Docker在微服务架构中的应用,包括隔离性、可移植性、扩展性、版本控制等方面,并提供代码示例。
52 1
|
8天前
|
前端开发 开发者 Docker
深入探索Docker Compose:简化多容器应用的部署
深入探索Docker Compose:简化多容器应用的部署
32 0
|
6天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
28 2
|
16天前
|
Kubernetes 监控 开发者
掌握容器化:Docker与Kubernetes的最佳实践
【10月更文挑战第26天】本文深入探讨了Docker和Kubernetes的最佳实践,涵盖Dockerfile优化、数据卷管理、网络配置、Pod设计、服务发现与负载均衡、声明式更新等内容。同时介绍了容器化现有应用、自动化部署、监控与日志等开发技巧,以及Docker Compose和Helm等实用工具。旨在帮助开发者提高开发效率和系统稳定性,构建现代、高效、可扩展的应用。
|
12天前
|
关系型数据库 MySQL API
|
28天前
|
存储 Docker 容器
docker中挂载数据卷到容器
【10月更文挑战第12天】
67 5
|
5天前
|
缓存 监控 开发者
掌握Docker容器化技术:提升开发效率的利器
在现代软件开发中,Docker容器化技术成为提升开发效率和应用部署灵活性的重要工具。本文介绍Docker的基本概念,并分享Dockerfile最佳实践、容器网络配置、环境变量和秘密管理、容器监控与日志管理、Docker Compose以及CI/CD集成等技巧,帮助开发者更高效地利用Docker。

热门文章

最新文章

相关产品

  • 函数计算