从 CephFS 到 JuiceFS:同程旅行亿级文件存储平台构建之路

随着公司业务的快速发展,同程旅行的非结构化的数据突破 10 亿,在 2022 年,同程首先完成了对象存储服务的建设。当时,分布式文件系统方面,同程使用的是 CephFS,随着数据量的持续增长,CephFS 的高复杂性和运维难度逐渐成为瓶颈。考虑到可观测性、稳定性和管理效率等维度,同程最终决定转向 JuiceFS。

目前,同程已在 JuiceFS 上构建了一个企业级存储平台,平台规模涵盖了超过 20 个文件系统和 2000 多个客户端挂载点,能够高效管理亿级文件和百 TiB 级别的数据量。值得一提的是,整个存储平台的日常运维工作仅需一人。该平台主要应用于多个场景,包括 AI 应用、容器云环境以及应用级共享存储需求。

01 文件系统选型:从 CephFS 到 JuiceFS

在使用 JuiceFS 之前,同程内部使用的是 Ceph 来提供对象存储和分布式文件存储服务。然而,Ceph 的技术栈复杂度较高,掌握难度大,对使用经验和运维经验都有较高要求。同时,在可运维性和生态建设方面也存在一定不足,对日常稳定性保障构成了较大挑战。

相比之下,JuiceFS 具有诸多优势。JuiceFS 设计上实现了元数据和数据分离,这与我们内部已有的成熟对象存储系统和分布式数据库系统高度契合。凭借已有的技术经验,能够自主进行问题排查和性能分析。此外,JuiceFS 的工具链和生态建设相对成熟,具备良好的 POSIX 兼容性和云原生支持。特别是其 CSI 功能,提供了多种挂载模式,使我们能够灵活选择。中文的用户社区也使得我们在使用过程中的沟通更为顺畅。

选择 JuiceFS 的另一个原因是它能够与我们现有的技术栈良好融合。简要介绍一下我们现有的基础系统:我们自建了一个基于开源 Seaweed 构建的 S3 集群,并搭建了 S3 代理,兼容 Seaweed、Ceph 以及腾讯 COS 等公有云S3服务。S3 集群具备主从机制,可以在代理层实现从主集群切换到从集群。此外,我们的 DCDB 是一个内部使用的分布式数据库系统,语法兼容 MySQL,基于百度的 BaikalDB 构建。

02 JuiceFS 在同程旅行的平台化建设

在平台化建设过程中,系统的可观测性、应用接入与部署以及数据安全性是至关重要的要素。为了确保平台的高效运行,我们在多个维度上进行了精心设计和优化,以实现全面的监控和高效的服务管理。

在可观测方面,我们构建了一系列监控大盘,以全面监控关键指标。同时,我们接入了公司内部的监控告警系统,为容量、接口耗时等重要指标配置了告警规则。为了更高效地接入内部监控系统,我们开发了一个挂载点自动发现程序。该程序从元数据引擎中获取当前的客户端列表,并实时将客户端列表的更改信息推送给我们内部的监控采集系统。

在应用接入与部署方面,我们提供了一系列易用工具,以支持应用的快速接入和部署。这些工具不仅简化了操作流程,还降低了运维难度。此外,我们高度重视数据安全性,对重要的文件系统都实现了全面备份,以确保数据的完整性和可用性。

在监控告警的具体内容方面,我们主要关注服务端的情况,特别是元数据与 S3 服务的平均时延、请求成功率以及异常情况等关键指标。这些指标对于评估系统性能和稳定性至关重要。

高可用 JuiceFS 服务集群:单中心闭环

它解决的一个典型场景是 Kubernets 单中心集群。 Kubernets 本身并非跨中心集群,而是每个中心都部署独立集群,即单中心闭环架构。在这种架构下 Kubernets 的各类资源和服务依赖通常限制在同一数据中心内,以避免跨数据中心通信带来的延迟、带宽消耗和网络复杂性。JuiceFS 在 Kubernets 中,主要解决的是持久化的需求,而不是数据共享的需求。

另外,一些对于性能要求较高的应用,流量也需要保持在同一数据中心内,以避免跨中心传输带来的延迟和带宽消耗。因此,在这些场景中,会采用单中心闭环的方案,将 JuiceFS 相关服务在每个 IDC 部署为独立集群,以确保数据存储和计算任务在同一中心内进行,最大化性能并降低延迟。

这种方式适用于内部 Kubernets 集群等场景,主要解决有状态应用的持久化存储问题。同时,通过将流量闭环在同一 IDC 内,避免了跨机房传输带来的性能瓶颈,从而保证系统的稳定性和性能。

高可用 JuiceFS 服务集群:跨中心闭环

这种部署方式主要应对的是那些本身跨机房部署且存在共享数据需求的应用场景。这类应用不仅需要访问同一个文件系统,而且对高可用性的要求也相对较高。若某个机房的服务出现故障,不可能要求所有应用都切换到其他中心,因此,我们采用了跨中心部署的后端服务集群方案。

在此方案中,对象存储,如 S3 集群以及 DCDB 等关键组件均实现了跨中心部署。具体而言,S3 的 Master 节点会在每个 IDC 都部署一个,以确保服务的全局可达性。同时,数据副本也会存储在多个中心,以提高数据的可靠性和容错性。DCDB 同样采用了跨中心部署策略,其服务在每个中心都有部署,数据副本则通过其内置的复制机制在多个中心间同步。

为了优化流量路径并减少跨中心传输带来的延迟和成本,我们在正常情况下将客户端请求限制在本地机房,流量通过负载均衡转发到本机房的 S3 服务节点。这不仅保证了性能,还减少了不必要的跨机房流量。由于跨中心集群内部的数据同步和复制需求,集群内部仍然会有跨中心流量。

在出现故障的情况下,例如某个中心的 S3 服务出现问题,我们可以将流量入口切换到其他中心。这一故障切换机制进一步保障了集群的高可用性。

03 落地 JuiceFS 收益

JuiceFS 的架构与我们内部已有的对象存储系统和分布式数据库系统高度兼容,使得集成过程非常顺利,整个项目仅投入了 2 人力,从选型到原理研究,再到最终落地的实施,仅用了半年的时间完成了从 CephFS 到 JuiceFS 的切换。基于 JuiceFS,我们成功构建了一个企业级存储平台,显著提升了存储系统的可观测性、稳定性与管理效率。

从 CephFS 切换到 JuiceFS 后的主要收益:

  • 扩展性和灵活性
    • 可以无缝扩展存储容量,并轻松应对数据量的快速增长,无需停机或影响现有业务。
    • 更好地适配云计算和容器化环境,便于企业在多云或混合云环境中运行。
  • 简化运维
    • 完善的可观测性功能,方便集成到企业内部系统。
    • 运维简单,能更好的支持稳定性保障工作。
  • 数据安全和可靠性
    • 更强的数据容错能力,能够自动进行故障恢复,确保数据的高可用性。
    • 提供强大的备份和灾难恢复能力,保证数据长期安全可靠。

目前,JuiceFS 已在多个场景中提供了强大的存储解决方案,满足了不同应用的需求:

  • 容器云平台:作为基础架构,JuiceFS 有效支持了云中心的持久化存储,尤其是通过容器存储接口(CSI)实现了有状态应用的数据持久化功能,解决了容器化环境中对持久存储的核心需求。
  • 大数据与 AI 平台:在大数据和 AI 应用中,JuiceFS 为海量数据存储提供了高效的支持,特别是在模型训练和数据处理过程中,显著提升了存储性能,解决了对大规模数据存储的需求。
  • 应用共享文件场景:JuiceFS 使多个应用实例能够便捷地共享文件资源,替代了传统的数据传输方案(如 SFTP),优化了应用间的数据交换和资源共享。
  • 数据冷备:尽管对象存储被广泛采用,但一些用户仍然偏好文件系统接口,JuiceFS 正是为这些场景提供了可靠的数据备份解决方案,确保了数据的长期可靠性与可访问性。

04 JuiceFS 使用中的挑战与优化实践

读写性能优化

首要挑战来自于一个关键业务场景——商品库业务。在该场景中,写服务负责数据的全量和增量更新,而读服务需要在更新完成后(通常为 10 分钟内)迅速加载数据。

在此过程中,我们观察到了一系列性能上的挑战。特别是在数据加载阶段,会产生大量的目录列表读取和文件操作,峰值带宽需求高达 20Gbps,同时元数据操作量也达到了 4 万次的高峰。为了应对这些挑战,我们对后端服务进行了针对性的优化,涵盖了资源存储和元数据管理两大方面。

在 S3 存储方面,我们进行了大量的链路对比测试。通过对比经过四层负载均衡(tvs)与直接连接 S3 的性能差异,我们发现了一些隐藏的链路节点存在较大的延时损耗。特别是在高带宽场景下,四层负载均衡的性能瓶颈尤为明显。为了解决这个问题,我们将负载均衡器升级到了采用高性能 DPDK 技术的版本,从而显著提升了链路性能。

元数据方面,我们深入调研了部署方案和元数据引擎的性能边界。尽管我们对 DCDB 进行了多项优化,如事务处理等,但由于其基于 Raft 协议,存在多次 RPC 请求的问题,即使经过极致优化,也只能达到毫秒级响应。对于跨中心集群部署而言,网络消耗和成本也是不可忽视的问题。因此,我们最终确定了将流量闭环在单个中心的方案,并选择了 Redis 作为元数据引擎,以确保元数据操作在 1 毫秒以内完成。

此外,通过将原始文件系统按照顶层目录拆分为多个子文件系统,我们成功地将整体流量分散到各个JuiceFS服务中。在进行了上述优化后,我们已经能够满足业务的性能要求。

我们还深入业务逻辑,协助业务方优化了代码流程,进一步降低了请求量,为系统创造了更多的性能提升空间。

低版本 FUSE 缓存同步 bug

这个bug的现象是当我们在一台机器上删除目录后再创建同名目录时,其他机器上看到的却是之前删除的目录内容。经过深入分析,我们发现这是 Linux 内核 2.6 版本中的一个已知 bug。该 bug 导致在删除目录后,Linux 的目录项缓存和 inode 缓存未能及时更新,从而在其他机器上产生了错误的目录视图。幸运的是,在 Linux 内核 3.10 版本及更高版本中,这个 bug 已经被修复。因此,我们建议大家在使用 JuiceFS 时,尽量使用 3.10 版本及以上的 Linux 内核,以避免类似的性能问题和 bug。

写入阻塞问题的排查与解决方案

在进行写入压测过程中发现偶尔应用写入会卡住,一段时间后应用写入报错 input/output error,查看挂载进程日志是访问 S3 403 鉴权失败

首先,由于问题偶发,我们可以排除密钥错误的可能性。通过直连 S3 测试,我们确认问题与中间链路节点有关,特别是与 Nginx 的交互存在问题。

为了深入了解问题根源,我们在 S3 端增加了日志记录,并发现 S3 在进行签名时使用了“Expect: 100-continue”请求头。这里需要解释一下,HTTP 协议中,“Expect: 100-continue”是一种机制,用于在上传大文件时,先发送 HTTP 请求头给服务器,服务器若接受,则返回 100 状态码,客户端再发送HTTP请求体。然而,在我们的案例中,打印日志发现 403 的请求不带有 Expect 头,但 S3 签名串用到了 “Expect:100-continue” 这引发了我们的进一步调查。

通过排查 JuiceFS 代码及 S3 SDK 发现是 S3 SDK 处理重试时,如果上传请求体大于 2M 时,会默认加上 “Expect:100-Continue”。然而,Nginx 在处理此类请求时,虽然遵循 HTTP 规范返回了 100 状态码,但在后续向 S3 转发请求时,却未保留该头部,S3 在收到请求后校验签名,由于没有收到 Expect 请求头,会使用默认的 “Expect:100-continue”,最终由于 Expect 请求头的值大小写不一致,导致签名校验失败,导致 juicefs mount 进程会重试阻塞。

针对此问题,我们提出了两种修复方案:

  • 一是将 SDK 中的“Expect: 100-Continue”头部修改为规范的小写形式;
  • 二是为 Nginx 添加一个不启用“Expect: 100-continue”的选项,这个选项是很必要的,可以减少一次网络交互。

这两种方案均能有效解决问题,我们向 S3 SDK 社区 JuiceFS 社区提交了 pr。

其他 Tips

文件权限

经常会出现在一批机器中,存在用户名相同但 uid 不相同的情况。针对这种情况,建议如果要做隔离,就在挂载时做好隔离,比如使用挂载子目录的方式来做隔离。同时,文件写入方负责文件权限的正确分配,确保其他文件使用方能有正确的权限。

元数据备份

当元数据数量庞大时,可能会遇到备份失败的情况。如果你的元数据引擎已经具备副本机制或者你已经实施了定时备份策略,那么可以考虑关闭元数据备份功能,以节省资源。

k8s-CSI

在使用 k8s-CSI 时,开可以选择禁用 format 选项。具体操作是,给 k8s-CSI只提供name和metaUrl两个参数即可。这样一来,在 k8s-CSI 运行过程中,就不会实际执行 format过程。这一做法能够带来两大好处:

首先,它能够保护我们的安全信息,如 S3 密钥等敏感数据不被泄露。由于format 过程中可能涉及文件系统的关键信息,禁用该功能能够减少信息暴露的风险。

其次,它允许存储提供方来管理文件系统的配置。在将JuiceFS交付给容器云平台之前,我们已经完成了文件系统的配置工作。这样一来,容器云平台就可以直接使用已经配置好的文件系统,无需再进行额外的配置或调整。

05 未来展望

分布式元数据引擎

我们注意到当前在某些场景中,对元数据性能的要求较高。针对这些场景,我们可能会考虑使用 Redis。然而,目前的 Redis 存在容量瓶颈问题,因为它为了保证事务的一致性,只使用了集群中的一个节点进行数据存储,无论集群中部署了多少个节点,实际上只有一个节点在运行,这导致了容量不能水平扩展。

此外,Redis 在运维方面也存在不便之处。因此,我们部门内部正在开发一个分布式的 KV 存储系统。在系统的调研阶段,我们已经与相关部门进行了多轮的沟通。

分布式缓存

通过引入分布式缓存,我们可以更有效地处理大数据场景下的数据存储和访问需求,进一步提升系统的整体性能和稳定性。

希望这篇内容能够对你有一些帮助,如果有其他疑问欢迎加入 JuiceFS 社区与大家共同交流。

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

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

相关文章

固定资产分类,提升资产盘活效益

固定资产是企业长期使用的重要资源,涵盖范围广、种类多,不同的资产需要针对性管理。通过科学的分类与高效的盘活策略,不仅可以优化资源配置,还能提升企业资产的利用效率和经济效益。以下将详细解析固定资产的分类方式和盘活效益的…

富途证券C++面试题及参考答案

C++ 中堆和栈的区别 在 C++ 中,堆和栈是两种不同的内存区域,它们有许多区别。 从内存分配方式来看,栈是由编译器自动分配和释放的内存区域。当一个函数被调用时,函数内的局部变量、函数参数等会被压入栈中,这些变量的内存空间在函数执行结束后会自动被释放。例如,在下面的…

【字符串匹配算法——BF算法】

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​💫个人格言:“没有罗马,那就自己创造罗马~” 文章目录 BF算法介绍及过程演示代码实现过程下节预告KMP算法利用next数组存储子串中j回退的位置(…

Linux 文件系统目录结构及其简要介绍

Hello! 亲爱的小伙伴们,大家好呀(Smile~)!我是 H u a z z i Huazzi Huazzi,欢迎观看本篇博客,接下来让我们一起来学习一下Linux 文件系统目录结构吧!祝你有所收获! 本篇博客的目录&a…

小米准备入局Nas?Nas究竟是啥?能干啥?

一开头就来了个三连问:小米准备入局Nas?Nas究竟是啥?Nas能干啥? 好像这段时间Nas这个词频频出现,但很多小伙伴都不知道这个是什么设备。首先咱们来解决一下名词Nas是什么意思。 什么是Nas? 为了尽可能解释…

基于Socket实现客户端和服务端的Tcp通信(C#)

0.前言 使用C#和Unity实现复刻Liar’s bar中的功能 软件开发大作业 本系列文章用于记录与分享开发过程中使用到的知识点,以及常见错误 本文主要描述有关网络编程的内容 目录 0.前言1.使用Socket搭建Server1.1Server端的Socket连接1.2 Server端接收Client的信息1.3…

【mysql】如何查看大表记录行数

目录 1. 使用 ANALYZE TABLE 和 SHOW TABLE STATUS2. 查询 INFORMATION_SCHEMA 表3. 使用索引统计信息4. 维护行数缓存5. 使用分区计数 1. 使用 ANALYZE TABLE 和 SHOW TABLE STATUS 1.ANALYZE TABLE 可以更新表的统计信息,然后使用 SHOW TABLE STATUS 来查看估算的…

文件断点续传(视频播放,大文件下载)

客户端每次请求取大文件部分数据。 浏览器播放mp4视频时,会首先传Range消息头,检测到206状态码,和Content-Range,Accept-Ranges 会自动请求余下数据。后端需要在文件任意偏移量取数据。 参考: springboot项目实现断…

游戏AI实现-寻路算法(A*)

A*(A-star)是一种图遍历和寻路算法,由于其完整性、最优性和最佳效率,它被用于计算机科学的许多领域。给定一个加权图、一个源节点和一个目标节点,该算法将找到从源到目标的最短路径(相对于给定的权重&#…

any/all 子查询优化规则的原理与解析 | OceanBase查询优化

背景 在通常情况下,当遇到包含any/all子查询的语句时,往往需要遵循嵌套执行的方式,因此其查询效率较低。Oceanbase中制定了相应的any/all子查询优化规则,能够能够识别并优化符合条件的any/all子查询,从而有效提升查询…

[HNOI2002] 营业额统计 STL - set集合

文章目录 [HNOI2002] 营业额统计题目描述样例输入 #1样例输出 #1 提示题解相关知识点set [HNOI2002] 营业额统计 STL - set解题 题目描述 Tiger 最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger 拿出…

汽车供应链 “剧变”开始,“智能感知潜在龙头”诞生

智能汽车产业链“剧变”已经开启,智能感知软硬件能力的权重正在不断被放大。 比如满足高阶泊车的第二代AK2超声波传感器、满足人机共驾场景需求的电子外后视镜(CMS)、iTOF 3D成像视觉感知(用于舱内监控)等新产品&…

Latex中表格添加底部文本注释并调整对齐

如何实现从第一个表到第三个表的转换, 其中主要涉及到两点: (1)底部脚注与表格自动对齐并缩进换行 (2)表格自适应页面宽度 底部脚注的对齐与换行缩进需要用到 \usepackage{threeparttable} \usepackage{…

SQL 查询方式比较:子查询与自连接

在 SQL 中,子查询和自连接是两种常见的查询方式,它们的功能虽然可以相同,但实现的方式不同。本文通过具体示例,深入探讨这两种查询方式,并配合数据展示,帮助大家理解它们的使用场景和差异。 数据示例 假设…

html基础-认识html

1.什么是html html是浏览器可以识别的的标记语言&#xff0c;我们在浏览器浏览的网页就是一个个的html文档 <!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>认识html</title> </head> <body><h1…

linux 无网络安装mysql

下载地址 通过网盘分享的文件&#xff1a;mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz 链接: https://pan.baidu.com/s/1qm48pNfGYMqBGfoqT3hxPw?pwd0012 提取码: 0012 安装 解压 tar -zxvf mysql-5.7.33-linux-glibc2.12-x86_64.tar.gz mv /usr/mysql-5.7.33-linux-glibc2.1…

利用高德API获取整个城市的公交路线并可视化(七)

本篇文章是对我们从高德拿到的公交/地铁的json文件的精细化处理的一个深入解析&#xff0c;通过对这些原始数据进行详细的清洗、转换和分析&#xff0c;我们通过对数据的质量和可用性的提升&#xff0c;来为后续的数据精细化处理和研究做基础数据的支撑&#xff0c;从而为后续的…

OGV格式如何转换成MP4格式?五款视频格式转换工具

在数字时代&#xff0c;视频已成为我们日常生活、工作和学习中不可或缺的一部分。而不同的设备和平台往往支持不同的视频格式&#xff0c;这就需要对视频进行格式转换。 OGV&#xff08;Ogg Video File&#xff09;是一种使用OGG开源格式的容器&#xff0c;用于存储带或不带音频…

番外篇 | Hyper-YOLO:超图计算与YOLO架构相结合成为目标检测新的SOTA !

前言:Hello大家好,我是小哥谈。Hyper-YOLO,该方法融合了超图计算以捕捉视觉特征之间复杂的高阶关联。传统的YOLO模型虽然功能强大,但其颈部设计存在局限性,限制了跨层特征的融合以及高阶特征关系的利用。Hyper-YOLO在骨干和颈部的联合增强下,成为一个突破性的架构。在COC…

C语言小练习-打印字母倒三角

编写一个程序&#xff0c;在用户输入某个大写字母后&#xff0c;产生一个金字塔图案。 #include <stdio.h>int main(int argc,char *argv[]) {char ch; loop:printf("请输入大写字母&#xff01;\n");scanf("%c",&ch);getchar();if(ch < A ||…