Fluid + GooseFS 助力云原生数据编排与加速快速落地
前言
Fluid 作为基于 Kubernetes 开发的面向云原生存算分离场景下的数据调度和编排加速框架,已于近期完成了 v0.6.0 版本的正式发布。腾讯云容器 TKE 团队一直致力于参与 Fluid 社区建设,在最新版本中贡献了以下两大特性:缓存引擎高可用运行时、新增数据缓存引擎实现 GooseFSRuntime 。
什么是存算分离?云原生背景下为什么需要数据编排?Fluid 和 GooseFSRuntime 又是什么?别担心!针对这些问题,我们带你一一探索。本文将首先介绍 Fluid 技术的诞生背景以及与 GooseFS 之间的关系;其次通过在 TKE 集群上的实际操练让大家体验 Fluid v0.6.0 的两大特性;最后我们将和大家一起探讨 Fluid 社区的未来发展。希望通过这篇文章能让大家进一步了解云原生应用场景下的数据编排能力,期待有兴趣的你一起参与 Fluid 的社区建设。
现状和挑战
什么是存算分离架构?
“存算分离”是当前网络技术发展和社会经济进步的时代产物,是最适合当前时代发展需求的一种架构。公有云环境为了满足用户按需服务、无限拓展的需求,常使用块存储、文件存储和对象存储来取代本地存储,例如在创建 TKE 集群时,会根据单盘的最大吞吐量、IOPS 等指标选择挂载高性能云硬盘、SSD 或增强型 SSD。这些不同规格的存储载体本质上都是云硬盘,且需要不定量地消耗网络带宽。但是随着云厂商在技术上的不断推动,以及用户对成本、扩展性以及性能的极致追求,计算和存储分离已然成为了云原生架构的发展趋势。
CNCF 发布的 《2020年中国云原生报告》 指出,容器应用相对于两年前达到了 240% 的惊人增长,容器编排实施标准 Kubernetes 在生产中的比例也从 72% 上升到 82%。Kubernetes 作为云原生时代的底座,凭借便捷的可移植性、丰富的可扩展性以及编排调度的自动化能力,已然成为公有云、私有云还有混合云的首选。而目前很多 AI 和大数据的业务也在积极的向 Kubernetes 靠拢,例如开源机器学习平台 Kubeflow;大数据计算框架 Spark 也推出 Spark-operator 以满足基于 Kubernetes 构建大数据计算平台的需求。云原生应用向存储计算分离架构演进的趋势日益增长。
云原生存算分离架构面临的挑战?
从 Adrian Cockcroft 于2013年介绍 Netflix 在 AWS 上基于 Cloud Native 的成功应用,到2015年 Pivotal 的 Matt Stine 定义云原生架构以及云原生计算基金会 CNCF 的成立,云原生价值已经得到了企业用户的广泛接受。虽然云原生正在加速向垂直行业的渗透,但存算分离的公有云场景仍然让云原生业务的发展面临着诸多挑战:
- 云平台存算分离架构导致数据访问延时高。随着高速网络设备和负载的大规模使用,所有的数据都依赖网络 IO 到计算节点计算和汇总,尤其是数据密集型应用,大概率网络会成为瓶颈(没有银弹)。IO 的瓶颈最终会导致计算和存储的资源无法充分的利用,将会背离利用云来实现降本增效的初衷。
- 混合云场景下跨存储系统的联合分析困难。大多数公司的业务线可能会分为不同的小组,不同的小组针对不同的 Workload 使用的计算框架也各有不同,而框架支持的存储也各有特点。例如 HDFS 针对大数据领域、Lustre 针对超算领域等等。当需要联合数据进行综合性分析时,数据副本数增加、数据转换的成本增加,都必然导致资源(即人力)的成本增高、业务迭代的效率降低等风险。
- 云中数据安全治理与多维度管理日趋复杂。数据是很多公司的生命线,数据泄露、误操作、生命周期管理不当都会造成巨大损失。如何在云原生环境中保障数据隔离,保护好用户的数据生命周期,都存在较大挑战。
Fluid 能做什么?
Fluid 类似云原生世界的“物流管理系统”,物流的发出方是各种数据源,例如 COS、HDFS、Ceph 以及 Lustre 等;此外,还要有具备存储不同货物(即聚合不同数据源)能力的物流仓库,如 GooseFS;而物流的收货地址就是用户期望数据被使用的计算节点。
Fluid 的设计目标就是为了将货物(数据)高效、准确的投放到用户手中。在实际生活中,我们常以快递柜的形式进行快递的分发,即在货物到达指定快递柜后希望用户主动领取快递。这样可以避免快递积压,用户也可以弹性规划快递的领取时间。其实设计理念体现到云计算场景就类似算子下推,将更多的计算下推到存储层完成,减少所需传输的数据量。希望在最后一公里实现,“移动计算到存储”而不是“移动存储到计算”。
GooseFS & Fluid 探究
云原生数据湖加速器 GooseFS
数据湖加速器(Data Lake Accelerator Goose FileSystem,GooseFS),是由腾讯云推出的高可靠、高可用、弹性的数据湖加速服务。依靠对象存储(Cloud Object Storage,COS)作为数据湖存储底座的成本优势,为数据湖生态中的计算应用提供统一的数据湖入口,加速海量数据分析、机器学习、人工智能等业务访问存储的性能;采用了分布式集群架构,具备弹性、高可靠、高可用等特性,为上层计算应用提供统一的命名空间和访问协议,方便用户在不同的存储系统管理和流转数据。
分布式数据编排和加速框架 Fluid
Fluid 是 CNCF Sandbox 开源的分布式数据编排和加速框架,是学术界(南京大学等)原创研究和工业界落地实践的结合开源项目。在计算和存储分离的大背景驱动下,Fluid 的目标是为 AI 与大数据云原生应用提供一层高效便捷的数据抽象,将数据从存储抽象出来,以便达到:
- 通过数据亲和性调度和分布式缓存引擎加速,实现数据和计算之间的融合,从而加速计算对数据的访问;
- 将数据独立于存储进行管理,并且通过 Kubernetes 的命名空间进行资源隔离,实现数据的安全隔离;
- 将来自不同存储的数据联合起来进行运算,从而有机会打破不同存储的差异性带来的数据孤岛效应。
从用户角度来说,用户声明数据来源后,Fluid 将自动调度数据到最合适的节点,并向外暴露 kubernetes 原生持久化数据卷。用户应用例如大数据应用 hadoop、spark 或 AI 应用 Pytorch、Tensorflow 等只需要挂载数据卷,Fluid 就可以通过亲和性调度让应用达到数据加速和统一访问的目的。Fluid 项目开源短短半年多时间内发展迅速,吸引了众多大厂的专家和工程师的关注与贡献,项目 Adoptor 包括腾讯、微博、奇虎 360、中国电信、BOSS 直聘、第四范式等多家大型知名 IT 和互联网企业。
理清 TKE、Fluid 和 GooseFS 之间的关系
Fluid 与腾讯云 TKE 融合的架构如下所示,根据不同的视图分为计算调度层、存储层以及任务层,下面我们将对该架构剥茧抽丝,带你快速理清 Fluid、TKE、GooseFS 三者之间的关系。
- 计算调度层:TKE 以 Kubernetes 环境为底座提供了容器应用的部署平台,Fluid GooseFS 控制器将控制 GooseFS 实例中的 Master Pod、Worker Pod 以及 Fuse Pod 创建在最合适的 TKE Worker 节点。
- 存储层:控制器会根据用户指定的数据来源将底层存储例如 COS、HDFS 的数据缓存到 Worker Pod 中。
- 任务层:任务 pod 指定持久化存储卷,控制器 webhook 会注入亲和性信息,以实现将使用缓存任务优先调度到有缓存节点以及将不使用缓存任务先调度到没有缓存节点的目标。
总体来说,Fluid 通过云原生的架构,在数据最后一公里,通过“移动计算到存储”的理念解决了 AI/大数据 存算分离场景下的诸多痛点。
Fluid v0.6.0 特性体验
以下特性均由腾讯云 TKE 团队设计贡献
“缓存引擎高可用运行时”
在 GooseFS 分布式缓存文件系统中,高可用性包含两层,一是整个文件系统的可用性,二是数据的完整和一致性。Master 作为全局元数据管理组件,通过 Master High-Availability 保证文件系统的高可用;通过 Raft 算法实现选主、状态机同步等操作保证日志和元数据的完整和一致性。在真实业务场景下如果单个 master 出现故障,会直接影响业务的正常运行,这就要求 Fluid 需要支持缓存引擎多 master 来保证容错率。
“新增数据缓存引擎实现 GooseFSRuntime”
为了支持腾讯云 TKE 上的计算任务对缓存系统的需求,我们在新版本中新增了一种支撑 Fluid Dataset 数据管理和缓存的执行引擎实现。用户可以在 Fluid 中通过 GooseFSRuntime 使用 GooseFS 缓存能力进行腾讯云 COS 文件的访问和缓存。在 Fluid 上使用和部署 GooseFSRuntime 流程简单、兼容原生 K8s 环境、开箱即用,配合腾讯云 TKE 食用更佳。
特性 Demo
本文档将向你简单地展示上述特性
前提条件
在运行该示例之前,请参考安装文档完成安装,并检查 Fluid 各组件正常运行:
$ kubectl get pod -n fluid-system
goosefsruntime-controller-5b64fdbbb-84pc6 1/1 Running 0 8h
csi-nodeplugin-fluid-fwgjh 2/2 Running 0 8h
csi-nodeplugin-fluid-ll8bq 2/2 Running 0 8h
csi-nodeplugin-fluid-dhz7d 2/2 Running 0 8h
dataset-controller-5b7848dbbb-n44dj 1/1 Running 0 8h
通常来说,你会看到一个名为dataset-controller
的 pod、一个名为 goosefsruntime-controller
的 pod 和多个名为csi-nodeplugin
的 pod 正在运行。其中,csi-nodeplugin
这些 pod 的数量取决于你的 Kubernetes 集群中结点的数量。
新建工作环境
$ mkdir <any-path>/demo
$ cd <any-path>/demo
查看全部节点
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
192.168.1.145 Ready <none> 7d14h v1.18.4-tke.13
192.168.1.146 Ready <none> 7d14h v1.18.4-tke.13
192.168.1.147 Ready <none> 7d14h v1.18.4-tke.13
创建 Dataset 资源
cat >> dataset.yaml <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
name: hbase
spec:
mounts:
- mountPoint: https://mirrors.tuna.tsinghua.edu.cn/apache/hbase/stable/
name: hbase
EOF
$ kubectl create -f dataset.yaml
dataset.data.fluid.io/hbase created
mountPoint 这里为了方便用户进行实验使用的是 Web UFS, 使用 COS 作为 UFS 可见 加速 COS。
创建并查看 GooseFSRuntime 资源
cat >> runtime.yaml <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: GooseFSRuntime
metadata:
name: hbase
spec:
replicas: 3
tieredstore:
levels:
- mediumtype: MEM
path: /dev/shm
quota: 2G
high: "0.8"
low: "0.7"
master:
replicas: 3
EOF
$ kubectl create -f runtime.yaml
goosefsruntime.data.fluid.io/hbase created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
hbase-fuse-4v9mq 1/1 Running 0 84s
hbase-fuse-5kjbj 1/1 Running 0 84s
hbase-fuse-tp2q2 1/1 Running 0 84s
hbase-master-0 1/1 Running 0 104s
hbase-master-1 1/1 Running 0 102s
hbase-master-2 1/1 Running 0 100s
hbase-worker-cx8x7 1/1 Running 0 84s
hbase-worker-fjsr6 1/1 Running 0 84s
hbase-worker-fvpgc 1/1 Running 0 84s
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
hbase Bound default-hbase 100Gi ROX fluid 12h
$ kubectl get goosefsruntime
NAME MASTER PHASE WORKER PHASE FUSE PHASE AGE
hbase Ready Ready Ready 15m
$ kubectl exec -ti hbase-master-0 bash
# 可以看到其中一个节点是 LEADER 其余两个是 FOLLOWER
$ goosefs fs masterInfo
current leader master: hbase-master-0:26000
All masters: [hbase-master-0:26000, hbase-master-1:26000, hbase-master-2:26000]
我们这里主要关注三个地方:
- 到这里,我们已经创建了可以供计算任务访问的分布式缓存引擎 GooseFS,计算任务的 pod 只需要指定
persistentVolumeClaim.name
为 hbase 即可获取缓存加速的能力。 - 同时只需要通过指定
spec.master.replicas=n
,这里 n 为大于等于 3 的奇数,就可以直接开启 Master HA 模式。 - 只需要指定
spec.replicas=n
,控制器将为 GooseFS 缓存系统创建 3 个 worker pod 以及 3 fuse pod
数据预热和加速
// 不使用缓存情况下任务时间
$ cat >> nginx.yaml <<EOF
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- mountPath: /data
name: hbase-vol
volumes:
- name: hbase-vol
persistentVolumeClaim:
claimName: hbase # 挂载 pvc claimName 和 dataset 一致
EOF
$ kubectl create -f nginx.yaml
$ kubectl exec -it nginx /bin/bash
$ root@nginx:/# time cp -r /data/hbase /
real 1m9.031s
user 0m0.000s
sys 0m2.101s
$ kubectl delete -f nginx.yaml
// 使用缓存加速
// 创建 Dataload 资源
$ cat >> dataload.yaml <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
name: hbase-dataload
spec:
dataset:
name: hbase
namespace: default
target:
- path: /
replicas: 1
EOF
$ kubectl create -f dataload.yaml
// 查看缓存预热进度
$ kubectl get dataset hbase --watch
NAME UFS TOTAL SIZE CACHED CACHE CAPACITY CACHED PERCENTAGE PHASE AGE
hbase 545.32MiB 545.32MiB 5.59GiB 100.0% Bound 16m
$ kubectl create -f nginx.yaml
$ kubectl exec -it nginx /bin/bash
$ root@nginx:/# time cp -r /data/hbase /
real 0m0.278s
user 0m0.000s
sys 0m0.273s
这种大幅度的加速效果(1m9s -> 0.278s 加速248倍) 归因于 GooseFS 所提供的强大的缓存能力。总结下来,通过 GooseFSRuntime 将用户定义的数据源统一管理,通过缓存来加速应用的访问。
这里主要展示 v0.6.0 的两大功能:缓存引擎高可用运行时以及新增数据缓存引擎实现 GooseFSRuntime ,不涉及 Fluid 其他功能,其他功能可见 使用文档。
Fluid Roadmap
上图为 Fluid 社区现规划的 Roadmap, 主要分为六个方面:自动化运维和可观测性、多运行时支持、数据弹性伸缩、编排调度优化、Fluid Agent 以及接入模式。目前自动化运维、多运行时支持以及接入模式基本实现,后期社区主要关注以下三个方面:
- 弹性拓展方面,目前已经支持基于自定义指标对缓存 Worker 进行 HPA(Horizontal Pod Autoscaler) 以及针对业务波峰波谷的 CronHPA 。但是由于缓存引擎数据再平衡(re-balance)功能的缺失,目前无法利用扩缩容达到降本增效的目的,这个也是社区后期重点关注的特性。
- Fluid Agent 方面,通过 agent push 模式,上报一些关键的运维指标例如是否有残留需要清理、节点是否有缓存等;同时不同节点上的系统信息例如 cpu/memory 使用量、磁盘使用量、page cache 使用信息等,通过这些信息可以指导 fluid 调度器对数据集进行最优调度。
- 调度策略方面,目前主要涉及三个方面的调度:
- 数据集调度:目前已经适配 kubernetes 调度,例如 Toleration、Node Selector、Preferred 调度;后期我们希望以 Scheduling Framework 的方式通过 Filter、Scoring、Binding 等操作实现数据集最优调度。
- 任务调度:目前已经可以通过 webhook 自动对指定 namespace 下的负载加入亲和性和反亲和性标签进行任务调度;
- 任务调度和数据预热协同调度:通过调度信息对 Job Queue 中 Job 使用的数据进行预加载,达到流水线优化的目的。
总结与展望
本文首先介绍了 Fluid 技术的诞生背景以及数据编排功能如何在存算分离场景下解决云原生业务对"移动计算到存储”的需求痛点;其次通过简要分析 Fluid 的架构,理清了 Fluid、GooseFS、TKE 三者的关系,并通过简单的 Demo 展示了 v0.6.0 的两大基础功能;最后通过 Fluid Roadmap 总结了目前社区已经完成的工作以及未来的发展规划。
总的来说,在公有云实现计算和存储的极致弹性才是增效降本的前提。只有让我们的业务更好的使用弹性的能力,获取云原生乃至云计算最大的红利,才能让应用生于云、长于云。