滴滴 OrangeFS 数据湖存储关键技术揭秘!

news2024/11/24 17:45:23

2015年,滴滴为解决小文件和图片的存储,成立 GIFT 小对象存储项目。伴随着业务不断成长,我们面临的挑战也越来越多,经历多次非结构化存储架构演进,具体如下图所示:

fa83242591e4a63751762fa5959e4b1f.png

随着公司不断发展,滴滴的业务有两个发展的趋势:云原生技术战略和新业务涌现,都给存储系统带来了新的挑战。

在云原生战略中,业务的极致弹性是提高资源利用率降低成本的一个目标。保障极致弹性的基础是容器的轻量化,而要实现容器的轻量化就必须实现存算分离。但目前弹性云的容器都是使用本地盘来存储业务日志或数据,这样天然和宿主强绑定,无法实现存算分离,且宿主机的磁盘利用率只有30%左右,容器漂移后数据还会出现易丢失现象。如果是业务日志数据,还需要通过采集方式存储到 HDFS 中,即:本地盘一份,HDFS 一份,双份存储,成本高。

同时,滴滴的自动驾驶,机器学习,国际化,金融等业务的不断发展,涌现了很多边端上传大量数据、服务端训练的场景,而边端和服务端对存储的需求又有一定的差异。例如:机器学习的训练场景主要是通过 S3 协议上传数据到滴滴 GIFT 对象存储系统中,通过类似 S3FS 方式挂载文件系统进行训练,这种模式缺点是处理流程长,延迟高,性能无法满足业务需求,且非完整的文件系统,对于 apend 或 rename 操作非常重。

解决思路

为了满足云原生技术战略和新业务的涌现需求,弹性云 K8S 通过 Posix 协议挂载网络盘写入网约车日志或数据,并通过 S3 或 HDFS 协议并发查询日志,解决了数据因飘移造成丢失、采集链路长(也就是通过 S3 或 HDFS 协议直接读取 Posix 写入日志数据)等问题,同时管理弹性云磁盘又能提供磁盘利用率。而机器学习的训练场景可以通过 S3 协议上传数据,Posix 协议去挂载训练,也可以解决流程长,延迟高问题。

我们需要提供一套支持多协议融合的云原生分布式存储系统,内部称之为:OrangeFS 云原生数据湖存储系统,整个系统核心技术主要包括:

  1. 多协议融合:采用统一文件组织结构,在这种结构基础上实现 Posix、S3、HDFS 三种不同存储协议融合。

  2. 云原生:基于 CSI 插件可以快速地在 Kubernetes 上使用 OrangeFS。

  3. 多云存储引擎:为了保证云上云下架构一致,应用于不同的场景,云下可以使用滴滴自研的 DFS 数据存储服务,线上可以使用 AWS S3、阿里云 OSS、腾讯云 COS、谷歌云等等。

  4. 多租户:为了降低业务部署成本,我们支持多租户管理,提供细粒度的租户隔离策略。

28e3ea75fed5943c20dff809e44bd073.png

核心技术

1. 文件组织结构

为了减少数据流动成本,我们参考并学习行业通用的多协议融合模式,主要有2种,第一种:在对象存储系统基础上构建文件系统,比较常见 S3FS。第二种:采用统一文件组织结构,在这种结构基础上实现 Posix、S3、HDFS 三种不同存储协议,例如:JuiceFS、CubeFS。

基于AWS S3对象存储实现的 S3FS,可以把 S3 bucket 挂载到系统中以 POSIX 方式访问,但无法提供原子的 rename和文件的随机写操作。例如:在 ofs-test 桶中有“/a/a1/a2/1.txt…”等文件,需要 rename 根目录下的a/文件夹为x/,具体如下图所示:

c97148db4b533a7e89ab255597c93791.png

采用统一文件组织结构模型,在这种结构基础上实现不同存储协议,可实现真正的文件系统和对象存储系统。例如:通过ofs-test 桶中有“/a/a1/a2/1.txt…”等文件,通过文件系统 rename 根目录下的a/文件夹为x/,只需要修改目录树节点的名称,其他无需变更。

a926cf2294a221240654d412cb81a5ab.png

为了提供系统读写的并发性能,我们把一个文件拆成多个固定大小段,我们称之为 Chunk。每个Chunk内部都会存在多次写入或修改的可能,我们把每次写入或修改不固定的大小块称之为 Blob(Binary Large Object)。一个 Blob 是由多个固定长的数据块组成,我们称之为 Block。具体如下图所示:

9dc7c3c5d2b3eb6475b08ec57dbad988.png

Chunk 和 Blob 数据信息我们存储到自研的 MDS 元信息存储服务中,而 Block 分块,我们存储在自研的 DFS 数据存储服务或公有云的S3、cos、oss等产品中。

1.1 写组织结构

文件在写场景时,提高性能减少Blob数量,每个 Chunk 默认只生成一个 Blob,每次直接写入对应的数据块,我们称之为 block。具体如下图所示:

3b40d4841e99a9fd67c62057993d0388.png

当业务写入或修改的内容对应的数据块与上一个Blob有重叠时,就会生成新的Blob,只要数据不重叠,那么就不生新的 Blob。如上图,在 block3 到 block5 之间插入一个新的数据块,就会生成一个新 Blob,具体如下图所示:

080b1bf0f991ec1a716ece0a9be85eb4.png

当业务写入数据刚好介于 block3 中间部分,那么这类场景也是生成新的 Blob,来保证每次写入都是顺序写,具体如下图所示:

0d7bcbe76afab420367425af9a92e6c4.png

当业务写入的数据刚好是在 Block5 数据块上,而且新写入的数据与 Block 5 原内容不重叠,那么可以做 append 操作,具体如下图所示: 

386d6ba4059f2f46d9ed27aa53612312.png

1.2 读组织结构

文件在读的场景时,读取到某个 Chunk 时,会将所有的 Blob 进行合并,获取到一个新的 Blob,再将新的 Blob 对应的数据块 Block 返回给上层调用服务。具体如下图所示:

82bec0d678eb1d19c79d489774e5be6f.png

2. 多协议融合

我们已知文件组织结构设计后,那如何在统一的文件组织结构上实现不同的协议?对于 OrangeFS 数据湖存储来说用户可以根据自己熟悉的协议对文件进行上传、下载等操作。它是个标准对象存储,也是文件存储,同时也是 HDFS,可以同时应用于三个生态,具体如图所示:    

c6e405d7bac4c1e429237a749e4d195b.png

我们在 OrangeFS 封装 VFS 和 PathFS 层。VFS 提供给 Posix 协议使用,封装了文件所有操作接口,包括:打开、创建、读、写、同步等操作。PathFS 提供给 S3、HDFS 协议使用,主要是单文件多个操作集合,例如:上传文件,就是创建、写操作集合。无论是 VFS 还是 PathFS,那么读写,都会调用融合写和融合读接口,那么下面我们来看下融合读和融合写的流程设计。

2.1 融合写流程

  1. 按 inode 找到对应文件上下文,然后通过 offset 和 data 长度获得 Chunk 固定逻辑块集合。

  2. 检查 Chunk 固定逻辑块是否有可复用的 Blob,如果存在,那么直接使用;如果不存在,那创建新的 Blob。

  3. 将 Blob 偏移 offset 和 data 内容拷贝到对应的 Block 对象存储块中。

  4. 数据信息拷贝完成后,更新元信息中的长度。异步写请求可以向 FUSE 返回写成功。

  5. 上传 Block 对象块到数据存储服务中。

  6. 提交 Blob 和更新 inode 长度/修复时间,也是版本号。

97f63cd71289902fcfcc72cf0bfd0ae9.png


2.2 融合读流程

  1. 按 inode 找到对应文件上下文,然后根据 data 长度和 offset 获得 Chunk 固定逻辑块集合。

  2. 获取每个 Chunk 对应的获取 Blob 列表。优化从缓存中获取,如果之前没有缓存会从RDS中获取,并进行缓存。

  3. 构建每个 Chunk 对应的 Blob,重叠部分新的覆盖旧的。

  4. 根据每个 Chunk 对应的 Blob、offset 读取长度,构建对象存储块列表 Blocks 。

  5. 根据对象存储块列表 Blocks 去数据存储服务中获取每块 Block 内容。若开启缓存会优先查询本地缓存中的对象,存在则可读缓存信息,没有则需要向多云数据存储服务发送读请求。如果本地缓存空间足够,那么会缓存本次数据,并通过 LRU 淘汰缓存。

  6. 获取到的 Block 内容写入到 Data 中,所有的数据拷贝完成后,向 FUSE 返回读成功。  

016c1dd939e567a7c27ba067bdce485a.png


3. 云原生技术

为了能在 K8S 中使用 OrangeFS 数据湖存储,我们基于 fuse 的开发一套文件系统客户端,完全兼容 Posix 协议。为了适应不同的业务,我们提供两类网络盘:一类为数据盘,专门用于存储数据。另一类为日志盘,专门用于日志。网络盘和日志盘最大区别是日志盘支持弱化同步、黑洞、自动超时等特性,出现严重故障可自动降级,保证不卡业务主流程。

3.1 OFS-CSI插件

为了实现 csi node-driver 的无感升级,我们拆分了node-driver 的功能,将OFS-CSI 呈给super-agent托管,与 provisioner 和 kubelet 均采用宿主机 Unix Domain Socket 进行交互,有效地避免 node-driver 升级带来的现有挂载点失效。

3.2 OFS-Posix客户端

在大多数操作系统中,文件系统可以在内核态(Kernel Mode)和用户态(User Mode)两个不同的权限级别上运行。

内核态文件系统是操作系统核心的执行环境,具有更高、更广泛的访问权限,但也有安全风险高、开发和调试难度高等缺点,一旦出现一个错误的实现可能会导致系统崩溃或数据损坏。

用户态是普通应用程序运行的环境,性能比内核态稍差、权限受到限制。但它的优点是实现从内核态转移到用户态,允许开发人员在用户空间编写文件系统的逻辑而不需要修改操作系统内核。这样做的目的是为了简化文件系统的开发和调试过程,增加文件系统的灵活性,并减少由于文件系统错误导致整个系统崩溃的风险。著名的用户态文件系统实现包括 FUSE(Filesystem in Userspace)在 Linux上,MacFUSE 在 MacOS 上,以及 WinFsp 在 Windows 上。这些用户态文件系统实现为开发人员提供了在用户态运行自定义文件系统的接口和框架。

FUSE 的主要工作原理是通过内核模块(kernel module)和用户态库(userspace library)之间的通信,将文件系统的请求从内核传递到用户态进程,然后在用户态进程中处理这些请求,并将结果返回给内核。这种设计允许用户态进程处理文件系统操作,而无需直接访问内核数据结构或硬件设备。具体如下图所示:

684535e6e85bd3c639926e73c27efda2.png

为了保证系统稳定性、降低安全风险和开发调试难度,OrangeFS 选择在用户态权限级别上运行,整个系统共有三部分组成:OrangeFS-Posix、MDS 元信息存储服务、多云数据分片存储服务。总体架构如下图所示: 

7d16bbcf5f87010eaaa808c9665ae213.png

OrangeFS Posix:是基于 fuse 的文件系统客户端,完全兼容 Posix 协议。

  • 接收与处理 FUSE 的操作请求,与 MDS Cluster 交互实现文件元信息的增删改查及管控操作, 与自建 IDC 的 DFS 数据存储系统或公有云 OSS/S3/COS 等系统交互实现文件分片数据的增删改查。

  • 支持卷级的 QoS,包括:带宽、QPS、黑洞等能力。

  • 支持元信息缓存和数据缓存以提高性能.

3.2.1 超时机制

为了保证用户可用性,避免单个接口操作耗时长而夯主上层应用,但可能会有雪崩效应,例如:Read、Write、Flush、FSync、Fallocate 等重量级操作,我们支持超时机制。

启动 Goroutine 来做具体的 File OP 操作,Fuse 下发的主 IO 流程的 Goroutine 来接收 Interrupt、Timedout、Done 的信号。OFS内部所有的 Goroutine 使用G池来管理,重复利用G。

Interrupt信号返回 EINTER错误、Timedout 信号返回 EBUSY 错误。

3.2.2 黑洞机制

为了保证用户的可用性,容忍丢失少部分数据。Write 支持黑洞机制,如果开启了黑洞,在超时时间内没有写成功,那么直接返回OK。

对于日志场景,不允许夯住,但是可以少量丢失部分数据。如果开启了黑洞丢失了少量数据,那么丢失的数据在文件中的体现就是一块空洞。即用户可以根据文件空洞知道丢失了数据的 range。

主IO流程的G监听 Timedout 信号,如果在 Timedout 时间内没有处理完成,那么向 VFS 层返回成功,同时返回本应写入的字节数。

3.2.3 弱化Sync

大量小写可以延迟写入后端 S3 或 DFS 存储引擎,OFS 可以合并大量的小写,降低元数据量和避免后端 S3 或 DFS 存储引擎过多小文件。

OFS 支持弱化 Sync,在单个客户端读写的场景,开启了弱化 Sync,那么用户主动调用的 Flush、FSync 都会不起作用,依赖 OFS 自身每隔一段时间的 flush 机制来做 sync。

简单应用

我们实现的多协议融合,也就是分布式文件系统挂载卷的根目录,同时也是 S3 或 HDFS 根目录,具体的 OFS 多协议融合的应用如下:

  • 我们在容器或 Linux 下挂盘并查看列表。

/home/ofs/bin/orangefs posix mount -debug=true -log-dir=/home/ofs/log -rs-addr=10.0.0.1:8030 -rs-model=mds -volume-name=ofs2 -mount-point=/home/ofs/mount

6793506ba01b2c501dd941d07b0aaad4.png

  • 通过 S3 协议下载数据。

a012b2739d19d7ef722c226c4fb94ce0.png

  • 通过 S3 协议上传数据。  

89388b91e935fce684e98665f82b9fd5.png


  • 通过 Posix 协议挂盘查询文件及数据。

779e42d687d4927bb479144d521b6eef.png


  • 通过 HDFS 协议访问数据。

28a3de969af6f66017e00bd8cc313e7d.png

本文总结

本文介绍了滴滴为什么要开发数据湖存储的原因,解决方案思路、核心几个技术设计以及简单应用。整个存储已接入上百PB在线实时业务,其中 OrangeFS 产品,已成功应用于网约车日志、机器学习、金融、效能、服务发现、大数据等场景,总容量已超过十几PB。

后继我们会陆续推出针对数据湖存储元服务、多云数据存储、Posix 热升级等技术点文章,欢迎大家与我们交流。



云原生夜话

你们公司有落地数据湖存储吗?是如何实现的?欢迎在评论区留言,如需与我们进一步交流探讨,也可直接私信后台。

作者将选取1则最有意义的留言,送出滴滴定制多功能跨包,9月26日晚9点开奖。

466c8a6a8f680436e5e480a35ca394de.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1024357.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Java+SpringBoot+Vue的即可运动健身器材网站设计与实现

前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 👇🏻…

Spring Boot常见面试题

Spring Boot简介 Spring Boot 是由 Pivotal 团队提供,用来简化 Spring 应用创建、开发、部署的框架。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能,降低了复杂性,同…

ClickHouse进阶(十九):clickhouse管理与运维-权限管理

进入正文前,感谢宝子们订阅专题、点赞、评论、收藏!关注IT贫道,获取高质量博客内容! 🏡个人主页:IT贫道_大数据OLAP体系技术栈,Apache Doris,Kerberos安全认证-CSDN博客 📌订阅:拥抱…

MySQL数据库——索引(1)-概述以及B-Tree结构

目录 索引概述 介绍 优缺点 索引结构(1) 介绍 二叉树 B-Tree 索引这一个章节将分为以下几个部分来学习: 索引概述索引结构索引分类索引语法SQL性能分析索引使用索引设计原则 索引概述 介绍 索引(index)是帮助M…

基于SSM的星空游戏购买下载平台

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用JSP技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…

RocketMq(四)消息分类

一、普通消息 1、同步发送消息:指的是Producer发出⼀条消息后,会在收到MQ返回的ACK之后才发下⼀条消息。该方式的消息可靠性最高,但消息发送效率低。 二、顺序消息 三、延时消息

JAVAAndroid实现MQTT上位机软件功能-订阅主题与发布主题

一、前言 本文我们将介绍Android或JAVA程序作为MQTT客户端连接MQTT服务器并订阅主题报文并发布主题报文,由于我的Android使用的也是JAVA语言,因此下面我们将使用IDEA完成JAVA程序,以实现订阅主题和发布主题的功能,该程序也可在后期…

MQ - 08 基础篇_消费者客户端SDK设计(下)

文章目录 导图Pre概述消费分组协调者消费分区分配策略轮询粘性自定义消费确认确认后删除数据确认后保存消费进度数据消费失败处理从服务端拉取数据失败本地业务数据处理失败提交位点信息失败总结导图 Pre

Linux系统编程(会话和进程)

文章目录 前言一、会话的概念二、会话和终端的区别三、终端进程组标识四、创建会话总结 前言 本篇文章我们来讲解会话和进程的概念,会话大家可能比较少见,他的英文名称叫session。 一、会话的概念 在Linux中,会话(Session&…

9月15日上课内容 Zookeeper集群 + Kafka集群

Zookeeper 本章结构 Zookeeper 概述 Zookeeper 定义 *(了解) Zookeeper是一个开源的分布式的,为分布式框架提供协调服务的Apache项目。 Zookeeper 工作机制 *****(非常重要,需要掌握) Zookeeper从设计模式…

diffusers中DDPMScheduler/AutoencoderKL/UNet2DConditionModel/CLIPTextModel代码详解

扩散模型的训练时比较简单的 上图可见,unet是epsθ是unet。noise和预测出来的noise做个mse loss。 训练的常规过程: latents vae.encode(batch["pixel_values"].to(weight_dtype)).latent_dist_sample() latents latents*vae.config.scali…

QT连接Sqlite

使用QTCreator; 根据资料,Qt自带SQLite数据库,不需要再单独安装,默认情况下,使用SQLite版本3,驱动程序为***QSQLITE***; 首先创建项目;在 Build system 中应选中qmake,…

前端自定义导出PPT

1、背景 前端导出PPT,刚接触这个需求,还是比较懵逼,然后就在网上查找资料,最终确认是可行的;这个需求也是合理的,我们做了一个可视化数据报表,报表导出成PPT,将在线报表转成文档类型…

【数据库系统概论】关系数据库中的关系数据结构

前言关系关系模式关系数据库关系模型的存储结构感谢 💖 前言 上一篇文章【数据库系统概论】数据模型介绍了数据库系统中的数据模型的基本概念。其中提到了关系模型是最重要的一种数据模型。下面将介绍支持关系模型的数据库系统——关系数据库。 按照数据模型的三大…

蓝牙核心规范(V5.4)10.5-BLE 入门笔记之HCI

HCI全称:HOST Constroller Interface 主机控制器接口(HCI)定义了一个标准化的接口,通过该接口,主机可以向控制器发出命令,并且控制器可以与主机进行通信。规范被分成几个部分,第一部分仅从功能的角度定义接口,不考虑具体的实现机制,而其他部分定义了在使用四种可能的…

Mac 上如何安装Mysql? 如何配置 Mysql?以及如何开启并使用MySQL

前言: 有许多开发的小伙伴,使用的是mac,那么在mac上如何安装,配置Mysql,以及使用Mysql了,今天来一个系统的教程。 安装Mysql 使用mysql前,我们需要先下载mysql,并按照以下几个步骤…

【Oracle】Oracle系列之四--用户管理

文章目录 往期回顾前言1. 创建/删除用户(1)创建用户(2)修改口令(3)删除用户 2. 用户授权管理(1)对用户直接授权(2)通过角色对用户授权 往期回顾 【Oracle】O…

Nodejs 相关知识

Nodejs是一个js运行环境,可以让js开发后端程序,实现几乎其他后端语言实现的所有功能,能够让js与其他后端语言平起平坐。 nodejs是基于v8引擎,v8是Google发布的开源js引擎,本身就是用于chrome浏览器的js解释部分&#…

day43 数据库

SQL分类 DDL:Date definition Language 数据定义语言 主要针对的是数据库对象进行创建修改删除的操作 包括:create, alter, drop, show, desc truncate DML:Data Manipulation Language 数据操作语言 对数据库中数据进行增加,修…

3D成像技术概述

工业4.0时代,三维机器视觉备受关注,目前,三维机器视觉成像方法主要分为光学成像法和非光学成像法,这之中,光学成像法是市场主流。 飞行时间3D成像 飞行时间成像(Time of Flight),简称TOF,是通过给目标连续发送光脉冲,然后用传感器接收从物体返回的光,通过探测光脉…