Fluid支持子数据集

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 当然随着Fluid使用的深入,也有不同的需求出现。其中社区一个比较共性的需求:1. 可以跨namespace访问数据集缓存 2. 只允许用户访问数据集的某个子目录特别是JuiceFS的用户,他们倾向于使用Dataset指向JuiceFS的根目录。然后对于不同数据科学家组分配不同的子目录作为不同的数据集,并且希望彼此间的数据集不可见;同时还支持子数据集的权限收紧,比如根数据集支持读写,子数据集可以收紧为只读。

什么是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各组件正常运行
$ kubectlget 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. 查看数据集状态
$ kubectlget 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 --bashmount | 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 2dr--r----- 1 root root 6 Dec 1607:25 spark-3.1.3
dr--r----- 1 root root 7 Dec 1607:25 spark-3.2.3
dr--r----- 1 root root 7 Dec 1607:25 spark-3.3.1
root@nginx:/# ls -ltr /data/spark-3.1.3/total 842999-r--r-----1 root root  25479200 Feb  62022 spark-3.1.3.tgz
-r--r-----1 root root 164080426 Feb  62022 spark-3.1.3-bin-without-hadoop.tgz
-r--r-----1 root root 231842529 Feb  62022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r-----1 root root 227452039 Feb  62022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r-----1 root root 214027643 Feb  62022 pyspark-3.1.3.tar.gz
-r--r-----1 root root    347324 Feb  62022 SparkR_3.1.3.tar.gz
root@nginx:/# ls -ltr /data/spark-3.2.3/total 1368354-r--r-----1 root root  28375439 Nov 1418:47 spark-3.2.3.tgz
-r--r-----1 root root 209599610 Nov 1418:47 spark-3.2.3-bin-without-hadoop.tgz
-r--r-----1 root root 301136158 Nov 1418:47 spark-3.2.3-bin-hadoop3.2.tgz
-r--r-----1 root root 307366638 Nov 1418:47 spark-3.2.3-bin-hadoop3.2-scala2.13.tgz
-r--r-----1 root root 272866820 Nov 1418:47 spark-3.2.3-bin-hadoop2.7.tgz
-r--r-----1 root root 281497207 Nov 1418:47 pyspark-3.2.3.tar.gz
-r--r-----1 root root    349762 Nov 1418: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状态
$ kubectlget 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<<EOFba >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
$ kubectlget 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 --bashroot@nginx:/# mount | grep /dataalluxio-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  62022 spark-3.1.3.tgz
-r--r-----1 root root 164080426 Feb  62022 spark-3.1.3-bin-without-hadoop.tgz
-r--r-----1 root root 231842529 Feb  62022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r-----1 root root 227452039 Feb  62022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r-----1 root root 214027643 Feb  62022 pyspark-3.1.3.tar.gz
-r--r-----1 root root    347324 Feb  62022 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)
$ kubectlget 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 --bashmount | 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  62022 spark-3.1.3.tgz
-r--r-----1 root root 164080426 Feb  62022 spark-3.1.3-bin-without-hadoop.tgz
-r--r-----1 root root 231842529 Feb  62022 spark-3.1.3-bin-hadoop3.2.tgz
-r--r-----1 root root 227452039 Feb  62022 spark-3.1.3-bin-hadoop2.7.tgz
-r--r-----1 root root 214027643 Feb  62022 pyspark-3.1.3.tar.gz
-r--r-----1 root root    347324 Feb  62022 SparkR_3.1.3.tar.gz

总结:

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

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
机器学习/深度学习 人工智能 并行计算
GPU
GPU
519 1
|
Go
Golang语言之gRPC程序设计示例
这篇文章是关于Golang语言使用gRPC进行程序设计的详细教程,涵盖了RPC协议的介绍、gRPC环境的搭建、Protocol Buffers的使用、gRPC服务的编写和通信示例。
516 3
Golang语言之gRPC程序设计示例
|
8月前
|
存储 缓存 弹性计算
聚宽揭秘:为什么量化研究员喜欢在Kubernetes上使用Fluid简化数据管理?
通过引入阿里云的 ack-fluid 技术,基于 JindoRuntime 的分布式缓存加速,解决了多数据源、弹性扩展、动态挂载等挑战,显著提升了数据处理效率和资源利用率,降低运营成本。这一方案帮助量化研究员实现了更高效的开发和实验流程,为未来的优化和扩展奠定了基础。
|
Kubernetes 应用服务中间件 nginx
使用kind搭建kubernetes
使用kind搭建kubernetes
475 5
|
10月前
|
人工智能 Kubernetes Cloud Native
跨越鸿沟:PAI-DSW 支持动态数据挂载新体验
本文讲述了如何在 PAI-DSW 中集成和利用 Fluid 框架,以及通过动态挂载技术实现 OSS 等存储介质上数据集的快速接入和管理。通过案例演示,进一步展示了动态挂载功能的实际应用效果和优势。
|
12月前
|
存储 Java 数据库连接
南大通用GBase 8s大对象类型clob和text的比较说明
本文探讨了GBase数据库中用于存储大对象数据的字段类型,包括TEXT、CLOB、BYTE和BLOB,分析了它们的特点、适用场景及在实际应用中的最佳实践。重点介绍了不同数据大小对应的字段类型选择,以及在数据库工具和程序中操作这些类型的方法,强调了合理选择字段类型对提升数据库性能的重要性。
|
Prometheus Kubernetes 监控
NVIDIA GPU Operator分析六:NVIDIA GPU Operator原理分析
背景我们知道,如果在Kubernetes中支持GPU设备调度,需要做如下的工作:节点上安装nvidia驱动节点上安装nvidia-docker集群部署gpu device plugin,用于为调度到该节点的pod分配GPU设备。除此之外,如果你需要监控集群GPU资源使用情况,你可能还需要安装DCCM exporter结合Prometheus输出GPU资源监控信息。要安装和管理这么多的组件,对于运维
3364 0
|
存储 缓存 分布式计算
Fluid新魔法:跨Kubernetes Namespace共享数据集
Fluid帮助数据科学家优化数据访问。不同的数据科学家团队会在多个不同的Namespace中创建数据密集型作业,且这些作业将访问相同的数据集。多个数据科学家复用相同的数据集,特别是开源数据集。各数据科学家拥有自己独立的Namespace提交作业。如果对于每个Namespace运行缓存运行时并进行缓存预热,会造成缓存资源浪费和作业启动延迟问题。
1016 0
Fluid新魔法:跨Kubernetes Namespace共享数据集
|
Kubernetes 监控 Linux
不借助 Docker Desktop 在Mac上开发容器应用
![](https://ata2-img.oss-cn-zhangjiakou.aliyuncs.com/neweditor/e2096947-f310-4ac5-a413-ec2b28b0e040.png) Docker Desktop是最为流行的开发者工具,Docker公司在 8/31 宣布对Docker Desktop的用户协议进行了变更,对个人开发者继续免费,但是对商业开发者采取了收费策
1944 114
不借助 Docker Desktop 在Mac上开发容器应用
|
存储 人工智能 Kubernetes
深势科技基于 Serverless 容器为科研人员打造高效的开发平台
深势科技基于 Serverless 容器为科研人员打造高效的开发平台