Fluid支持子数据集

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
简介: 什么是Fluid?在云上通过云原生架构运行AI、大数据等任务,可以享受计算资源弹性的优势,但同时也会遇到,计算和存储分离架构带来的数据访问延迟和远程拉取数据带宽开销大的挑战。尤其在GPU深度学习训练场景中,迭代式的远程读取大量训练数据方法会严重拖慢GPU计算效率。另一方面,Kubernetes只提供了异构存储服务接入和管理标准接口(CSI,Container Storage Interface),

什么是Fluid?

在云上通过云原生架构运行AI、大数据等任务,可以享受计算资源弹性的优势,但同时也会遇到,计算和存储分离架构带来的数据访问延迟和远程拉取数据带宽开销大的挑战。尤其在GPU深度学习训练场景中,迭代式的远程读取大量训练数据方法会严重拖慢GPU计算效率。

另一方面,Kubernetes只提供了异构存储服务接入和管理标准接口(CSI,Container Storage Interface),对应用如何在容器集群中使用和管理数据并没有定义。在运行训练任务时,数据科学家需要能够管理数据集版本,控制访问权限,数据集预处理,加速异构数据读取等。但是在Kubernetes中还没有这样的标准方案,这是云原生容器社区缺失的重要能力之一。

Fluid对“计算任务使用数据的过程”进行抽象,提出了弹性数据集Dataset的概念,并作为“first class citizen”在Kubernetes中实现。Fluid围绕弹性数据集Dataset,创建了数据编排与加速系统,来实现Dataset管理(CRUD操作)、权限控制和访问加速等能力。

Fluid中有两个最核心的概念:Dataset和Runtime。

  • Dataset 是指数据集,是逻辑上相关的一组数据的集合,会被计算引擎使用,比如Spark,TensorFlow,PyTorch等等。
  • Runtime 指的是提供分布式缓存的系统,目前 Fluid 支持的 Runtime 类型有 JuiceFS、Alluxio、JindoFS,GooseFS,其中 Alluxio、JindoFS 都是典型的分布式缓存引擎; JuiceFS 是一款分布式文件系统,具备分布式缓存能力。这些缓存系统使用Kubernetes集群中节点上的存储资源(如:内存和磁盘)来作为远程存储系统的计算侧缓存。

为什么Fluid需要支持子数据集(subDataset)?

Fluid最早的模式默认支持一个Dataset独占一个Runtime,可以理解为一个数据集就有专门的缓存集群加速。可以针对于数据集的特点,比如单文件大小特征,文件数量规模,客户端数量进行定制优化;并且提供单独的缓存系统。它能够提供最好的性能以及稳定性,并且不会互相干扰,但是它的问题在于硬件资源浪费,需要为每个不同的数据集部署缓存系统;同时运维复杂,需要管理多个缓存Runtime。这种模式其实本质上是单租户架构,适合于对于数据访问吞吐和延时高要求的场景。

当然随着Fluid使用的深入,也有不同的需求出现。其中社区一个比较共性的需求:

  1. 可以跨namespace访问数据集缓存 
  2. 只允许用户访问数据集的某个子目录

特别是JuiceFS的用户,他们倾向于使用Dataset指向JuiceFS的根目录。然后对于不同数据科学家组分配不同的子目录作为不同的数据集,并且希望彼此间的数据集不可见;同时还支持子数据集的权限收紧,比如根数据集支持读写,子数据集可以收紧为只读。

本文以AlluxioRuntime为例子向您演示如何使用Fluid支持子数据集能力。

使用样例:

想像一下,用户A在Kubernetes的命名空间spark下创建数据集spark, 该数据集包含spark的三个版本,希望团队A只能看到数据集spark-3.1.3, 团队B只能看到数据集spark-3.3.1。

.
|-- spark-3.1.3
|   |-- SparkR_3.1.3.tar.gz
|   |-- pyspark-3.1.3.tar.gz
|   |-- spark-3.1.3-bin-hadoop2.7.tgz
|   |-- spark-3.1.3-bin-hadoop3.2.tgz
|   |-- spark-3.1.3-bin-without-hadoop.tgz
|   `-- spark-3.1.3.tgz
|-- spark-3.2.3
|   |-- SparkR_3.2.3.tar.gz
|   |-- pyspark-3.2.3.tar.gz
|   |-- spark-3.2.3-bin-hadoop2.7.tgz
|   |-- spark-3.2.3-bin-hadoop3.2-scala2.13.tgz
|   |-- spark-3.2.3-bin-hadoop3.2.tgz
|   |-- spark-3.2.3-bin-without-hadoop.tgz
|   `-- spark-3.2.3.tgz
`-- spark-3.3.1
    |-- SparkR_3.3.1.tar.gz
    |-- pyspark-3.3.1.tar.gz
    |-- spark-3.3.1-bin-hadoop2.tgz
    |-- spark-3.3.1-bin-hadoop3-scala2.13.tgz
    |-- spark-3.3.1-bin-hadoop3.tgz
    |-- spark-3.3.1-bin-without-hadoop.tgz
    `-- spark-3.3.1.tgz

这样就实现了不同团队可以访问不同子数据集,并且彼此间的数据不可见。

阶段1: 管理员创建数据集,指向根目录

  1. 在运行该示例之前,请参考 安装文档 完成安装,并检查Fluid各组件正常运行
kubectl get po -n fluid-system
NAME                                         READY   STATUS      RESTARTS   AGE
alluxioruntime-controller-5c6d5f44b4-p69mt   1/1     Running     0          149m
csi-nodeplugin-fluid-bx5d2                   2/2     Running     0          149m
csi-nodeplugin-fluid-n6vbv                   2/2     Running     0          149m
csi-nodeplugin-fluid-t5p8c                   2/2     Running     0          148m
dataset-controller-797868bd7f-g4slx          1/1     Running     0          149m
fluid-webhook-6f6b7dfd74-hmsgw               1/1     Running     0          149m
fluidapp-controller-79c7b89c9-rtdg7          1/1     Running     0          149m
thinruntime-controller-5fdbfd54d4-l9jcz      1/1     Running     0          149m
  1. 创建命名空间spark
$ kubectl create ns spark
  1. 在命名空间development创建Dataset和AlluxioRuntime, 其中数据集为可读写
$ cat<<EOF >dataset.yaml
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: spark
  namespace: spark
spec:
  mounts:
    - mountPoint: https://mirrors.bit.edu.cn/apache/spark/
      name: spark
      path: "/"
  accessModes:
    - ReadWriteMany
---
apiVersion: data.fluid.io/v1alpha1
kind: AlluxioRuntime
metadata:
  name: spark
  namespace: spark
spec:
  replicas: 1
  tieredstore:
    levels:
      - mediumtype: MEM
        path: /dev/shm
        quota: 4Gi
        high: "0.95"
        low: "0.7"
EOF

$ kubectl create -f dataset.yaml
  1. 查看数据集状态
$ kubectl get dataset -n spark
NAME    UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
spark   3.41GiB          0.00B    4.00GiB          0.0%                Bound   61s
  1. 在命名空间spark创建Pod访问数据集
$ cat<<EOF >app.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: spark
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: spark
  volumes:
    - name: spark
      persistentVolumeClaim:
        claimName: spark
EOF

$ kubectl create -f app.yaml
  1. 查看应用通过dataset可以访问的数据, 可以看到3个文件夹:spark-3.1.3, spark-3.2.3, spark-3.3.1, 同时可以看到 挂载权限为RW( ReadWriteMany )
$ kubectl exec -it -n spark nginx -- bash
mount | grep /data
alluxio-fuse on /data type fuse.alluxio-fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other,max_read=131072)
root@nginx:/# ls -ltr /data/
total 2
dr--r----- 1 root root 6 Dec 16 07:25 spark-3.1.3
dr--r----- 1 root root 7 Dec 16 07:25 spark-3.2.3
dr--r----- 1 root root 7 Dec 16 07:25 spark-3.3.1
root@nginx:/# ls -ltr /data/spark-3.1.3/
total 842999
-r--r----- 1 root root  25479200 Feb  6  2022 spark-3.1.3.tgz
-r--r----- 1 root root 164080426 Feb  6  2022 spark-3.1.3-bin-without-hadoop.tgz
-r--r----- 1 root root 231842529 Feb  6  2022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r----- 1 root root 227452039 Feb  6  2022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r----- 1 root root 214027643 Feb  6  2022 pyspark-3.1.3.tar.gz
-r--r----- 1 root root    347324 Feb  6  2022 SparkR_3.1.3.tar.gz
root@nginx:/# ls -ltr /data/spark-3.2.3/
total 1368354
-r--r----- 1 root root  28375439 Nov 14 18:47 spark-3.2.3.tgz
-r--r----- 1 root root 209599610 Nov 14 18:47 spark-3.2.3-bin-without-hadoop.tgz
-r--r----- 1 root root 301136158 Nov 14 18:47 spark-3.2.3-bin-hadoop3.2.tgz
-r--r----- 1 root root 307366638 Nov 14 18:47 spark-3.2.3-bin-hadoop3.2-scala2.13.tgz
-r--r----- 1 root root 272866820 Nov 14 18:47 spark-3.2.3-bin-hadoop2.7.tgz
-r--r----- 1 root root 281497207 Nov 14 18:47 pyspark-3.2.3.tar.gz
-r--r----- 1 root root    349762 Nov 14 18:47 SparkR_3.2.3.tar.gz

阶段2: 管理员创建子数据集,指向目录spark 3.1.3

  1. 创建命名空间spark-313
$ kubectl create ns spark-313
  1. 管理员在 spark-313 命名空间下,创建:

引用数据集spark,其mountPoint格式为dataset://${初始数据集所在namespace}/${初始数据集名称}/子目录,  在本例子中应该为dataset://spark/spark/spark-3.1.3 

注: 当前引用的数据集,只支持一个mount,且形式必须为dataset://(即出现dataset://和其它形式时,dataset创建失败),数据集权限为读写;

$ cat<<EOF >spark-313.yaml
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: spark
  namespace: spark-313
spec:
  mounts:
    - mountPoint: dataset://spark/spark/spark-3.1.3
  accessModes:
    - ReadWriteMany
EOF

$ kubectl create -f spark-313.yaml
  1. 查看dataset状态
$ kubectl get dataset -n spark-313
NAME    UFS TOTAL SIZE   CACHED   CACHE CAPACITY   CACHED PERCENTAGE   PHASE   AGE
spark   3.41GiB          0.00B    4.00GiB          0.0%                Bound   108s
  1. 用户在 spark-313  命名空间,创建Pod:
$ cat<<EOF >app-spark313.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: spark-313
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: spark
  volumes:
    - name: spark
      persistentVolumeClaim:
        claimName: spark
EOF

$ kubectl create -f app-spark313.yaml
  1. 在spark-313命名空间访问数据, 只能看到spark-3.1.3文件夹中的内容,并且可以 看到pvc权限RWX
$ kubectl get pvc -n spark-313
NAME    STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
spark   Bound    spark-313-spark   100Gi      RWX            fluid          21h
$ kubectl exec -it -n spark-313 nginx -- bash
root@nginx:/# mount | grep /data
alluxio-fuse on /data type fuse.alluxio-fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other,max_read=131072)
root@nginx:/# ls -ltr /data/
total 842999
-r--r----- 1 root root  25479200 Feb  6  2022 spark-3.1.3.tgz
-r--r----- 1 root root 164080426 Feb  6  2022 spark-3.1.3-bin-without-hadoop.tgz
-r--r----- 1 root root 231842529 Feb  6  2022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r----- 1 root root 227452039 Feb  6  2022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r----- 1 root root 214027643 Feb  6  2022 pyspark-3.1.3.tar.gz
-r--r----- 1 root root    347324 Feb  6  2022 SparkR_3.1.3.tar.gz

阶段3: 管理员创建子数据集,指向目录spark 3.3.1

  1. 创建命名空间spark-331
$ kubectl create ns spark-331
  1. 管理员在 spark-331 命名空间下,创建:

引用数据集spark,其mountPoint格式为dataset://${初始数据集所在namespace}/${初始数据集名称}/子目录,  在本例子中应该为dataset://spark/spark/spark-3.3.1 

注: 当前引用的数据集,只支持一个mount,且形式必须为dataset://(即出现dataset://和其它形式时,dataset创建失败),并且指定读写权限为只读ReadOnlyMany

$ cat<<EOF >spark-331.yaml
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: spark
  namespace: spark-331
spec:
  mounts:
    - mountPoint: dataset://spark/spark/spark-3.3.1
  accessModes:
    - ReadOnlyMany
EOF

$ kubectl create -f spark-331.yaml
  1. 用户在 spark-331  命名空间,创建Pod:
$ cat<<EOF >app-spark331.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: spark-331
spec:
  containers:
    - name: nginx
      image: nginx
      volumeMounts:
        - mountPath: /data
          name: spark
  volumes:
    - name: spark
      persistentVolumeClaim:
        claimName: spark
EOF

$ kubectl create -f app-spark331.yaml
  1. 在spark-331命名空间访问数据, 只能看到spark-3.3.1文件夹中的内容, 并且可以 看到PVC权限ROX( ReadOnlyMany )
$ kubectl get pvc -n spark-331
NAME    STATUS   VOLUME            CAPACITY   ACCESS MODES   STORAGECLASS   AGE
spark   Bound    spark-331-spark   100Gi      ROX            fluid          14m$ kubectl exec -it -n spark-331 nginx -- bash
mount | grep /data
alluxio-fuse on /data type fuse.alluxio-fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0,allow_other,max_read=131072)
root@nginx:/# ls -ltr /data/
total 842999
-r--r----- 1 root root  25479200 Feb  6  2022 spark-3.1.3.tgz
-r--r----- 1 root root 164080426 Feb  6  2022 spark-3.1.3-bin-without-hadoop.tgz
-r--r----- 1 root root 231842529 Feb  6  2022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r----- 1 root root 227452039 Feb  6  2022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r----- 1 root root 214027643 Feb  6  2022 pyspark-3.1.3.tar.gz
-r--r----- 1 root root    347324 Feb  6  2022 SparkR_3.1.3.tar.gz

总结:

在本例子中,我们展示了Sub Dataset的能力,也就是将某个Dataset的子目录作为Dataset。能够实现同一套数据集,根据不同的细分策略,被不同的数据科学家使用。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
机器学习/深度学习 存储 PyTorch
【14】自定义宝可梦数据集
【14】自定义宝可梦数据集
250 0
【14】自定义宝可梦数据集
|
3月前
|
机器学习/深度学习 JavaScript 前端开发
深度学习必备:对数据集的拆分、根据拆分图片拆分labels、对全部标注标签进行区间检查
使用JavaScript代码或浏览器扩展可以一次性在浏览器中打开多个相同的标签页。
|
4月前
|
分布式计算 自然语言处理 MaxCompute
构建NLP 开发问题之如何在数据加载框架中实现从两个ODPS表中分别读取正样本和负样本,并在batch内以1:1的方式混合
构建NLP 开发问题之如何在数据加载框架中实现从两个ODPS表中分别读取正样本和负样本,并在batch内以1:1的方式混合
|
6月前
|
Python
创建模型
创建模型。
28 1
|
6月前
|
数据可视化
R语言建立和可视化混合效应模型mixed effect model
R语言建立和可视化混合效应模型mixed effect model
|
数据格式
重写transformers.Trainer的compute_metrics方法计算评价指标时,形参如何包含自定义的数据
  这个问题苦恼我几个月,之前一直用替代方案。这次实在没替代方案了,transformers源码和文档看了一整天,终于在晚上12点找到了。。。
542 0
|
机器学习/深度学习 数据可视化 Java
TensorFlow 高级技巧:自定义模型保存、加载和分布式训练
本篇文章将涵盖 TensorFlow 的高级应用,包括如何自定义模型的保存和加载过程,以及如何进行分布式训练。
|
存储 缓存 分布式计算
Fluid支持子数据集
当然随着Fluid使用的深入,也有不同的需求出现。其中社区一个比较共性的需求: 1. 可以跨namespace访问数据集缓存 2. 只允许用户访问数据集的某个子目录 特别是JuiceFS的用户,他们倾向于使用Dataset指向JuiceFS的根目录。然后对于不同数据科学家组分配不同的子目录作为不同的数据集,并且希望彼此间的数据集不可见;同时还支持子数据集的权限收紧,比如根数据集支持读写,子数据集可以收紧为只读。
556 2
Fluid支持子数据集
|
机器学习/深度学习 存储 人工智能
从Tensorflow模型文件中解析并显示网络结构图(pb模型篇)
从Tensorflow模型文件中解析并显示网络结构图(pb模型篇)
从Tensorflow模型文件中解析并显示网络结构图(pb模型篇)
|
PyTorch API 算法框架/工具
TorchVision Transforms API 大升级,支持目标检测、实例/语义分割及视频类任务
TorchVision Transforms API 大升级,支持目标检测、实例/语义分割及视频类任务
211 0