从 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.rhkb.cn/news/489454.html

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

相关文章

Ariba Procurement: Administration_Master data

采购主数据集成Procurement Master Data Integration 注意:并非所有元素都是必需的,数据元素的名称可能根据ERP的不同,有所不同。 Types of Master Data Accounting 在SAP Ariba中的各种会计元素字段中,填充有效值选择列表。建…

Hadoop一课一得

Hadoop作为大数据时代的奠基技术之一,自问世以来就深刻改变了海量数据存储与处理的方式。本文将带您深入了解Hadoop,从其起源、核心架构、关键组件,到典型应用场景,并结合代码示例和图示,帮助您更好地掌握Hadoop的实战…

#思科模拟器通过服务配置保障无线网络安全Radius

演示拓扑图: 搭建拓扑时要注意: 只能连接它的Ethernet接口,不然会不通 MAC地址绑定 要求 :通过配置MAC地址过滤禁止非内部员工连接WiFi 打开无线路由器GUI界面,点开下图页面,配置路由器无线网络MAC地址过…

定时器里使用QTextEdit在界面上刷新数据,过一会就停止刷新

问题 使用QTextEdit在界面上刷新数据过一会(不到1分钟)就自动停止,但是当鼠标在QTextEdit内移动后,又开始刷新。 原因 暂未查明。 解决办法 在定时器函数里增加下面一行代码,问题解决。

国产自主可控新征程:华为原生鸿蒙系统与鲲鹏认证

华为于今年10月22日在深圳正式发布了其原生鸿蒙系统HarmonyOS NEXT。这是我国首个实现全栈自研的操作系统,标志着中国在操作系统领域取得了突破性进展。HarmonyOS NEXT 5.0的发布,使得鸿蒙操作系统成为继苹果iOS和安卓系统之后的全球第三大移动操作系统&…

长沙理工大学《2024年825自动控制原理真题》 (完整版)

本文内容,全部选自自动化考研联盟的:《长沙理工大学825自控考研资料》的真题篇。后续会持续更新更多学校,更多年份的真题,记得关注哦~ 目录 2024年真题 Part1:2024年完整版真题 2024年真题

【漏洞复现】CVE-2024-34102 Magento Open Source XXE漏洞

目录 漏洞介绍 影响版本 环境搭建 查看版本 漏洞复现 手动复现 漏洞 poc Magento Open Source 是一个免费开源的电子商务平台,适合中小企业或开发团队通过自定义代码和插件创建在线商店。它由社区开发和支持,功能强大但需要更多的技术投入。Adobe…

html自带的input年月日(date) /时间(datetime-local)/星期(week)/月份(month)/时间(time)控件

年月日期控件 type"date" <input type"date" id"StartDate" valueDateTime.Now.ToString("yyyy-MM-dd") /> //设置值 $("#StartDate").val("2024-12-12"); //获取值 var StartDate$("#StartDate&quo…

【C++】递归填充矩阵的理论解析与实现

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 &#x1f4af;前言&#x1f4af;问题描述&#x1f4af;递归实现&#x1f4af;参数解析函数参数详解填充顺序分析递归终止条件 &#x1f4af;示例解析第一层递归第二层递归第三层递归最终输出 &#x1f4af…

Spark SQL 执行计划解析源码分析

本文用于记录Spark SQL执行计划解析的源码分析。文中仅对关键要点进行提及&#xff0c;无法面面具到&#xff0c;仅描述大体的框架。 Spark的Client有很多种&#xff0c;spark-sql&#xff0c;pyspark&#xff0c;spark- submit&#xff0c;R等各种提交方式&#xff0c;这里以…

Qt学习笔记第61到70讲

第61讲 记事本实现当前行高亮功能 实现策略&#xff1a; 获取当前行的光标位置&#xff0c;使用的信号和获取行列值是一样的&#xff0c;即通过ExtraSelection 来配置相关属性。 关键API&#xff1a; QList<QTextEdit::ExtraSelection> extraSelections; void setExtraSe…

使用CSS变量和JavaScript实现鼠标跟随渐变

实现鼠标跟随渐变效果的详细过程&#xff1a; 1. HTML 结构 我们在 HTML 中创建了一个 <div> 元素&#xff0c;用于展示渐变效果。这个元素的 ID 是 gradient-box&#xff0c;方便在 JavaScript 中进行操作。 2. CSS 样式 CSS 变量&#xff1a;在 :root 中定义了两个…

Wireshark如何查看数据包时间间隔

1.如果数据包量不大&#xff0c;抓包本身也不大&#xff0c;建议从绝对时间判断&#xff0c;打开wireshark软件&#xff0c;并点开相应要分析的抓包文件。 进入到最上方菜单<视图>,在弹出菜单选择时间显示格式&#xff0c;再在右侧菜单中选择自捕获经过的秒数。 这样就可…

Windows系统磁盘与分区之详解(Detailed Explanation of Windows System Disks and Partitions)

Windows系统磁盘与分区知识详解 在日常使用Windows操作系统的过程中,我们常常会接触到磁盘管理,磁盘分区等操作.然而,许多人可能并不完全理解磁盘和分区的运作原理以及如何高效管理它们. 本篇文章将探讨Windows系统中关于磁盘和分区的各种知识,帮助大家更好地理解磁盘以及分区…

【MySQL中多表查询和函数】

目录 1.多表查询 1.1 外键 1.2 链接查询 2.MySQL函数 内置函数简介 数值函数 字符串函数 时间日期函数 条件判断操作 开窗函数 1.多表查询 本质&#xff1a;把多个表通过主外键关联关系链接&#xff08;join&#xff09;合并成一个大表&#xff0c;在去单表查询操作…

如何理解html+css

上篇文章中&#xff0c;说道不会写代码能拥有自己的网站吗&#xff1f;答案当然是可以的。不过这就和住毛坯房的感觉是一样的&#xff0c;我要改一下房子的结构&#xff0c;要装修一下让房子变得更符合自己的气质就又不会了。所以呢了解下 前端html css是很有必要的。 1.html…

【原生js案例】如何让你的网页实现图片的按需加载

按需加载&#xff0c;这个词应该都不陌生了。我用到你的时候&#xff0c;你才出现就可以了。对于一个很多图片的网站&#xff0c;按需加载图片是优化网站性能的一个关键点。减少无效的http请求&#xff0c;提升网站加载速度。 感兴趣的可以关注下我的系列课程【webApp之h5端实…

Avalonia实战实例三:实现可输入框的ComboBox控件

文章目录 一、Avalonia中的ComboBox控件二、更改Template&#xff0c;并添加水印 接着上篇关闭按钮实现登录界面 实现一个可输入&#xff0c;可下拉的用户名输入框 一、Avalonia中的ComboBox控件 Avalonia中Fluent主题里ComboBox实现&#xff1a; <ControlTheme x:Key&q…

严蔚敏老师,一路走好

Hey&#xff0c;小伙伴们&#xff0c;今天我要和大家分享一个令人心痛的消息&#xff0c;但也是我们向一位伟大的学者致敬的时刻。&#xff1a;清华大学计算机教授、《数据结构》编著者严蔚敏 去世&#xff0c;享年 86 岁。她的离去&#xff0c;让无数学子和同行感到深深的哀痛…

【卷积神经网络】LeNet实践

模型建立 数据初始化根据模型搭建前向传播打印模型结构 前向传播数据初始化 def __init__(self):super(LeNet, self).__init__()# 第一层卷积层&#xff1a;# 输入&#xff1a;灰度图像 (1通道&#xff0c;大小 28x28)# 输出&#xff1a;6个特征图 (大小 28x28, 通过padding2保…