背景
得益于网络带宽的提高,大数据领域近些年一直在追求存储与计算分离,来提高计算服务的可扩展性。同时期,云原生崛起,受益于此东风,越来越多的依托于云架构的基础组件被开发并开源了出来,其中就包括本文的主角 juicefs。另外依托于 azure 云的 github codespaces 服务,也开始面向广大开发者开放。
笔者有幸获得 codespaces 的 beta 服务,开始尝试将一些开源项目的开发迁移到云上的 codespaces 中进行。在初步接触过程中,也发现 codespaces 不仅是个web ide,更是一台性能还不弱的计算实例。但是在这个过程中,遇到了诸多问题,比如线下 mac 和云上的数据和文件不同步,导致需要依靠 http server 来实现一些编译好的文件互传。
不禁思考,为什么不能将开发空间也实现计算和存储分离呢?codespaces/mac 均是计算设备,理论上个人开发者在不同时空上可能会切换使用不同设备,同时因比如编译大型项目、测试分布式训练任务也需要切换不同算力的设备。但是存储希望能够在不同的计算设备间共享,避免掉复杂的手动同步过程。
听起来可行?如何实现?就想到了 juicefs, 一个依托于云上对象存储 + 元数据管理的新型云原生文件系统。它将文件系统的树形结构以及其他元信息存储于云上数据库(redis/tikv/mysql...),将分片 chunk 存储于云上对象存储(s3/oss/obs/....),实现了 fuse 挂载,从而提供了一个共享文件系统。不禁为这个想法点赞!
codespaces + juicefs 是个好主意
说干就干,于是先在 codespaces 实例中验证了下使用 juicefs 的可行性。我们可以通过使用 sqlite 和本地文件系统来模拟 juicefs 单机部署的过程,验证 fuse 在 codespaces 实例中的挂载。
可行性验证
首先在 codespaces 中安装 fuse. 此步骤必需,如果缺失,后续 juicefs 可能不会抛出对应的错误,导致难以排查 root cause.
sudo apt-get install fuse
在本地部署单机版的 juicefs
# 下载最新版的 juicefs.
wget https://github.com/juicedata/juicefs/releases/download/v1.0.0-beta3/juicefs-1.0.0-beta3-linux-amd64.tar.gz
tar zxvf juicefs-1.0.0-beta3-linux-amd64.tar.gz
# 初始化 juicefs 元数据引擎和 fs name
juicefs format sqlite3://myjfs.db myjfs
# 挂载到 codespaces 本地
juicefs mount sqlite3://myjfs.db ~/jfs
一切正常,说明在 codespaces 内部使用挂载无问题
详细部署文档可见: https://juicefs.com/docs/zh/community/quick_start_guide
申请元数据存储引擎实例 + 对象存储
上文只是进行一个简单的可行性验证。但是我们为了实现共享的文件系统,需要使用云上的数据库 + 云上的对象存储。
本文笔者使用了 redis cloud 提供的免费 redis 服务,以及七牛云的对象存储。申请过程就不赘述,申请完之后,就需要如下的几个信息
Tips:
Juicefs 公司也提供了免费的元数据引擎云服务,因此可以白嫖一波,无需再购买公有云上的 redis 服务。
另外得益于 juicefs 的架构,理论上 webdav 也可以作为 juicefs 的后端存储。(理论上同样可以白嫖阿里云盘)
部署分布式版本的 juicefs
# 初始化元数据引擎, 此命令只需初始化一次
juicefs format \
--storage qiniu \
--bucket {endpoint} \
--access-key {ak} \
--secret-key {sk} \
redis://{username}:{pwd}@{redis-url}:{port} \
zustonjfs
# 挂载文件系统,此命令可在多个计算实例上执行,获得一个共享的文件系统
juicefs mount redis://{username}:{pwd}@{redis-url}:{port} ~/jfs
启动配置集成
为了实现启动 codespaces 实例,就能自动挂载 juicefs 的文件系统,我们可以直接集成到 codespaces 的 Dockerfile 中。配置上述的 juicefs 挂载命令到 github 项目下的 .devcontainer/Dockerfile 下,如下
ARG VARIANT=8-bullseye
FROM mcr.microsoft.com/vscode/devcontainers/java:0-${VARIANT}
# [Option] Install Maven
ARG INSTALL_MAVEN="true"
ARG MAVEN_VERSION=""
RUN mkdir -p /dev_container_install_dir
WORKDIR /dev_container_install_dir
RUN mv /usr/bin/python /usr/bin/python27
RUN ln -s /usr/bin/python3.9 /usr/bin/python
RUN wget https://github.com/juicedata/juicefs/releases/download/v1.0.0-beta3/juicefs-1.0.0-beta3-linux-amd64.tar.gz \
&& tar zxvf juicefs-1.0.0-beta3-linux-amd64.tar.gz
RUN ./juicefs mount redis://{username}:{pwd}@{redis-url}:{port} ~/jfs -d
场景举例
云编译
因为项目需要,经常需要修改和编译 Hadoop、Flink 等大型项目的代码,但编译耗时良久,在 mac 上风扇呼呼的转。
因此可以将项目代码放置在 juicefs 共享文件系统中,在 codespaces 实例中进行编译。同时编译完成的产出物,则直接在 mac 上通过 juicefs 取用测试。
云分布式训练
算法工程师在 mac 上编写的训练程序受限于环境,无法在分布式下得到充分测试。因此使用 codespace 来构建分布式训练就成为了一个可选项。
但是 codespace 目前仅支持转发 http port,为了实现构建 TensorFlow 分布式训练集群,我们需要借助 tailscale 来将多个 codespace 实例组成虚拟局域网。同时为了方便管理编排分布式 TensorFlow,我们使用 Ray 来实现资源调度。
更重要的是,TensorFlow 分布式训练不仅需要共享训练数据,还依赖 checkpoint 来进行容错,因此使用 juicefs 来作为共享文件系统,并通过挂载为本地磁盘来接入。
在采用了上述多个组件后的整体架构图如下:
关于如何在 Ray 上部署 TensorFlow 训练,可参见:https://github.com/zuston/raytf
云 jupyterlab
在 codespace 中部署 jupyterlab 作为计算, 使用 juicefs 来共享 mac 的数据,使得计算和存储分离。更多的用法,还在等待挖掘
总结
codespace + juicefs 真香!
背景
得益于网络带宽的提高,大数据领域近些年一直在追求存储与计算分离,来提高计算服务的可扩展性。同时期,云原生崛起,受益于此东风,越来越多的依托于云架构的基础组件被开发并开源了出来,其中就包括本文的主角 juicefs。另外依托于 azure 云的 github codespaces 服务,也开始面向广大开发者开放。
笔者有幸获得 codespaces 的 beta 服务,开始尝试将一些开源项目的开发迁移到云上的 codespaces 中进行。在初步接触过程中,也发现 codespaces 不仅是个web ide,更是一台性能还不弱的计算实例。但是在这个过程中,遇到了诸多问题,比如线下 mac 和云上的数据和文件不同步,导致需要依靠 http server 来实现一些编译好的文件互传。
不禁思考,为什么不能将开发空间也实现计算和存储分离呢?codespaces/mac 均是计算设备,理论上个人开发者在不同时空上可能会切换使用不同设备,同时因比如编译大型项目、测试分布式训练任务也需要切换不同算力的设备。但是存储希望能够在不同的计算设备间共享,避免掉复杂的手动同步过程。
听起来可行?如何实现?就想到了 juicefs, 一个依托于云上对象存储 + 元数据管理的新型云原生文件系统。它将文件系统的树形结构以及其他元信息存储于云上数据库(redis/tikv/mysql...),将分片 chunk 存储于云上对象存储(s3/oss/obs/....),实现了 fuse 挂载,从而提供了一个共享文件系统。不禁为这个想法点赞!
codespaces + juicefs 是个好主意
说干就干,于是先在 codespaces 实例中验证了下使用 juicefs 的可行性。我们可以通过使用 sqlite 和本地文件系统来模拟 juicefs 单机部署的过程,验证 fuse 在 codespaces 实例中的挂载。
可行性验证
首先在 codespaces 中安装 fuse. 此步骤必需,如果缺失,后续 juicefs 可能不会抛出对应的错误,导致难以排查 root cause.
sudo apt-get install fuse
在本地部署单机版的 juicefs
一切正常,说明在 codespaces 内部使用挂载无问题
详细部署文档可见: https://juicefs.com/docs/zh/community/quick_start_guide
申请元数据存储引擎实例 + 对象存储
上文只是进行一个简单的可行性验证。但是我们为了实现共享的文件系统,需要使用云上的数据库 + 云上的对象存储。
本文笔者使用了 redis cloud 提供的免费 redis 服务,以及七牛云的对象存储。申请过程就不赘述,申请完之后,就需要如下的几个信息
redis 连接串, 包括可访问地址 + 用户名 + 访问密码
对象存储连接串,包括 endpoint + ak + sk
部署分布式版本的 juicefs
启动配置集成
为了实现启动 codespaces 实例,就能自动挂载 juicefs 的文件系统,我们可以直接集成到 codespaces 的 Dockerfile 中。配置上述的 juicefs 挂载命令到 github 项目下的 .devcontainer/Dockerfile 下,如下
场景举例
云编译
因为项目需要,经常需要修改和编译 Hadoop、Flink 等大型项目的代码,但编译耗时良久,在 mac 上风扇呼呼的转。
因此可以将项目代码放置在 juicefs 共享文件系统中,在 codespaces 实例中进行编译。同时编译完成的产出物,则直接在 mac 上通过 juicefs 取用测试。
云分布式训练
算法工程师在 mac 上编写的训练程序受限于环境,无法在分布式下得到充分测试。因此使用 codespace 来构建分布式训练就成为了一个可选项。
但是 codespace 目前仅支持转发 http port,为了实现构建 TensorFlow 分布式训练集群,我们需要借助 tailscale 来将多个 codespace 实例组成虚拟局域网。同时为了方便管理编排分布式 TensorFlow,我们使用 Ray 来实现资源调度。
更重要的是,TensorFlow 分布式训练不仅需要共享训练数据,还依赖 checkpoint 来进行容错,因此使用 juicefs 来作为共享文件系统,并通过挂载为本地磁盘来接入。
在采用了上述多个组件后的整体架构图如下:
关于如何在 Ray 上部署 TensorFlow 训练,可参见:https://github.com/zuston/raytf
云 jupyterlab
在 codespace 中部署 jupyterlab 作为计算, 使用 juicefs 来共享 mac 的数据,使得计算和存储分离。更多的用法,还在等待挖掘
总结
codespace + juicefs 真香!