Clobotics 计算机视觉场景存储实践:多云架构、 POSIX 全兼容、低运维的统一存储

Clobotics 是一家将计算机视觉和机器学习技术应用于风电以及零售行业的企业。在风电行业,Clobotics 利用无人机对风力发电机叶片进行检查,显著降低了对人工作业的依赖。在零售领域,公司通过分析捕获的包装商品图像来提供基于实时数据的洞察,以增加销售额并减少运营成本。

存储方面,Clobotics 原本直接使用云 SDK,而部分系统则使用了内部的封装器,没有形成统一的存储层,同时还面临多云架构、海量小文件、兼容性方面的挑战。改造存储层的过程中, Clobotics 对 Ceph、SeaweedFS 和 JuiceFS 等文件系统方案进行了比较,最终选择使用 JuiceFS。

JuiceFS 支持接入几乎所有主要公有云平台,并能有效处理大量小文件的存储问题。其完全的 POSIX 兼容性允许我们在 JuiceFS 上实现整个数据流程,显著降低技术工程的工作量和成本。

目前,在 Clobotics 内部,风电和零售两个业务场景都已经接入 JuiceFS,涉及到业务访问,数据标注和模型训练场景,后续仍在扩展新的场景接入。

01 Clobotics 业务架构以及存储需求

Clobotics 有两大业务模块,风电与零售。 下图是我们的技术架构图,在基础设施层面,我们采用了标准化的服务组件,包括配置中心(如 Apollo)、服务注册中心(如 Nacos)、以及监控、日志与告警系统等,这些系统主要依赖于业界广泛认可的开源组件,如利用 Elasticsearch 与 Grafana 进 行日志与监控数据的可视化展示,以及 Prometheus 作为监控指标的收集工具。

进一步向上,是通用服务层,其核心在于对各类资产数据的集中管理,涵盖了多领域,如风电行业的风机、零售行业的门店与超市,以及我们自有资产如无人机、零售用冷柜等。此外,IAM(身份认证与访问管理)系统负责用户权限的分配与管理,确保系统安全。

针对数据处理过程中不可避免的实时、准实时及批处理需求,我们设计并实施了统一的工作流与调度中心。此中心融合了 Apache Airflow 等开源组件,以应对批处理场景;同时,针对 Airflow 无法完全覆盖的特定需求,我们自行开发了定制化的服务以增强调度能力。在公共服务层面,我们特别抽离了 AI 模型服务,旨在实现 AI 能力的共享与复用。

计算机视觉场景的数据特点

我们的核心数据类型包括各类采集的图片,这些图片在规格、像素清晰度上差异显著。每月新增约 5000 万张原始采集图片,涵盖风电与零售两大领域,数据特点如下:

海量小文件: 风电场景下的图片原始文件可达十余兆,即便经过压缩处理,其体积依然不容忽视。此类图片在标注过程中需逐一细致查看,考虑到网络传输效率与标注工作的流畅性,我们采取了"Tile Image"技术,即将大图切分为类似地图瓦片的小图,以提高加载速度与查看效率。然而,这一方法也导致了文件数量的激增,特别是最底层的小图,其体积虽小但数量庞大。零售场景,我们每月需处理约 200 至 300 万个切图命令,高峰时可达 500 个以上。

二十多种类型模型训练:涵盖通用与垂直领域,迭代周期各异(周、月、季度),确保模型能够适应不同场景的需求。

元数据性能要求高:如 CSV 和 JS 文件,它们是 AI 模型训练过程中不可或缺的数据输入格式。此外,模型文件作为线上服务的关键组成部分,需频繁更新与迭代,且体积较大,对存储性能提出了更高要求。

针对新增数据的管理:随着新站点的不断加入,需定期更新或刷新这些数据,这一过程中会产生额外的 I/O 操作。同时,报告生成后需临时存储在特定位置,以便用户后续下载或分享。

版本管理:这是是我们不可忽视的一环,特别是针对原数据和图片数据集。在零售场景中,客户需求的快速变化要求我们对数据集进行精细化的版本控制。而在风电场景中,为实现对不同叶片叶形的精细化管理,数据集的切分与版本管理亦需更加细致

多云架构对存储层建设的挑战

我们采用了多云存储解决方案,包括 Azure Blob Storage、阿里云 OSS、Google Cloud Storage(GCS)、Amazon S3,以及单机版或小集群模式的 MinIO。主要是源于不同客户环境的适应性需求。

由于不同客户所选择的云服务商各异,我们需要不断进行适配工作,以支持不同技术栈(如.NET、Go、Python、C++、Java等)下的数据访问需求,这无疑增加了架构的复杂性与运维的挑战。除此以外,由于风电与零售等业务平台在功能与场景上的差异性,我们不得不面对一定程度的重复开发工作,这对初创企业的研发资源构成了不小的压力。

再者,跨云架构,在进行数据标注、模型训练等操作时,需从多个云存储服务中拉取数据,这不仅增加了数据迁移的复杂性,还可能因频繁的数据读取而产生不必要的成本。因此,如何在保证数据一致性与安全性的同时,优化跨云数据存储与访问策略,成为我们亟待解决的问题。

02 文件存储选型:POSIX、云原生、低运维

鉴于我们场景的数据特点和以及多云架构给数据存储带来的挑战,我们重新审视并思考如何构建一个更为轻量、灵活的存储层架构。这一架构需要灵活应对不同业务场景下的数据存储需求,同时确保在引入新的云存储服务时,能够以极低的成本甚至无成本的方式实现快速接入

在最初的选型过程中,我们充分考量了市场上主流及开源的存储解决方案。经过深入调研,我们首先将 HDFS 排除在外,尽管它在国内众多公司中被广泛应用。但针对我们的需求,其设计初衷更偏向于处理大数据量高吞吐的场景,而非我们面临的文件数量众多且需定期清理数据的情况。HDFS 的 NameNode 在文件数量激增时会承受巨大压力,且数据删除操作成本较高,加之其 POSIX 兼容性不足,因此不符合我们的要求

Name POSIX-compatible CSI Driver Scalability Operation Cost Document
HDFS No No Good High Good
Ceph Yes Yes Medium High Good
SeaweedFS Basic Yes Medium High Medium
GlusterFS Yes Not mature Medium Medium Medium
JuiceFS Yes Yes Good Low Good

随后,鉴于当前多数公司倾向于在 Kubernetes 上进行服务部署与运维,CSI Driver 成为了我们评估存储解决方案时的必要考量因素。我们当前的数据量仅为 700TB,并以较低的增长率增长,因此可扩展性并非我们的首要关注点。运维成本却是我们必须严格控制的,作为一家创业公司,我们希望在基础设施上尽量减少人力投入,以便集中资源于核心业务。

在评估 Ceph 时,我们发现其安装与部署相对简便,但运维成本较高,特别是在容量规划与扩容方面存在挑战,Ceph 的文档虽然丰富,但组织有一些杂乱,增加了上手难度。

SeaweedFS 作为一个表现不俗的开源项目,因同事有相关的运维经验而进入我们的视野,但最终还是因其运维成本较高及文档完善度不足而被放弃;GlusterFS 则因其轻量级的运维与扩容特性获得了一定关注,尽管自建存储层会带来一定的运维成本上升,但总体仍在可接受范围内。

最终,我们选择了 JuiceFS。JuiceFS 以其完全的 POSIX 兼容性和对云原生环境的支持吸引了我们的注意。在运维成本方面,JuiceFS 主要依赖于轻量级的元数据引擎,如 MySQL 或 Redis,这些均是我们现有技术栈中的组成部分,无需额外引入新组件,从而大大降低了运维复杂度。此外, JuiceFS 的文档清晰易懂,对于新手而言也能快速上手。

03 JuiceFS 应用实践

在选定 JuiceFS 作为我们的存储层解决方案后,我们的整体存储架构已逐步构建并优化至当前形态。在此我仅聚焦于我们实际应用的几个关键环节进行详细说明。

首先,在模型训练环节, FUSE 模块发挥着核心作用。模型训练需处理大量数据,且这些数据通常存储于云端,我们利用高性能的实体机搭配充足显卡资源,以满足模型训练的计算与调度需求。而所有模型训练任务均集中于单一高性能机器上执行。因此,我们采用 Fuse 挂载的方式,将云端不同存储源的数据同步至本地目录,形成本地可访问的存储空间。这一过程中,我们处理的最大单个训练数据集达到百万级别,数据稳定性高,主要用于零售场景下的快速识别模型训练。

其次,在资源管理与访问控制环节, CSI Driver 的应用则主要体现在以 Mount Pod方式进行。此方式简化了部署流程与Pod的组织结构,同时,通过内部调度器的精细控制,有效避免了不同Pod 间资源访问的冲突与并发读写问题。初期虽偶有死锁现象,但通过优化数据集管理与访问调度策略,现已实现高效的并发控制。

至于 S3 Gateway,其意外地成为我们选型 JuiceFS 后的又一重要收获。原本我们计划构建独立的文件服务以共享内部文件,但需面对复杂的权限与时效性问题。而 S3 Gateway 不仅提供了基于角色的权限控制,满足了我们的基本需求,还通过 Security Token 机制实现了对共享链接时效性的精细管理,有效防止了数据被恶意抓取的风险。

使用 JuiceFS 后所获得的收益如下:

  1. 统一存储层:首先,JuiceFS 实现了我们最初选型的核心目标,即提供了一个统一的存储层。这一层不仅简化了数据存储的管理,还提升了整体的数据访问效率。
  2. 云存储接入的灵活性:随着业务发展,我们能够更轻松地接入新的云存储服务或类型,无需对现有架构进行大规模调整,增强了系统的可扩展性和适应性。
  3. 简化权限管理:通过 JuiceFS 内置的 ACL 机制,我们能够满足大多数场景下的权限管理需求。虽然对于特别庞大或复杂的业务环境,这一功能可能需要额外扩展,但对于我们而言,已经足够满足日常需求。
  4. 跨云存储版本管理:JuiceFS 允许我们有效管理不同云存储服务上的数据版本,确保数据的一致性和可追溯性,为业务决策提供了坚实的数据支持。
  5. 性能监控与优化:借助 JuiceFS,我们能够收集并分析存储层的性能指标,从而更准确地评估和优化系统性能。这一能力在裸用云存储时难以实现,因为云存储的原数据管理对普通用户而言通常是不透明的。
  6. 元数据管理透明化:JuiceFS 使我们能够更容易地获取和管理文件的原数据,如写入时间和更新时间等,这对于数据修复、分层存储等高级操作至关重要。
  7. POSIX 兼容性:JuiceFS 的 POSIX 兼容性意味着无论使用何种编程语言或技术栈,开发人员都可以利用标准的文件 API 进行操作,无需额外学习成本,提高了开发效率和系统兼容性。
  8. 简化运维:JuiceFS 的运维相对简单,主要关注 Redis 或 MySQL 等元数据服务的健康状态即可。这一特点降低了运维难度,减少了因系统维护不当导致的停机风险。
  9. 成本节约:最为意外的收获是,通过 JuiceFS 的有效数据集管理,我们显著减少了重复数据的上传和存储。这一改进不仅降低了存储成本,还通过减少不必要的数据拷贝节省了运营成本。此外,对重复数据的清理也进一步提高了存储效率。

在使用 JuiceFS 时,我们采取了以下几点策略以优化数据存储和管理:

  1. 独立实例架构便于数据隔离与合并:我们优先采用独立的实例架构,使用不同的元数据引擎来精确管理各种数据存储需求。这种方法比构建统一的大型存储集群更能减少复杂性和管理难题。考虑到不同客户数据间的隔离需求和不同通用场景下的数据合并挑战,我们将数据根据特性和用途分配到各自独立的实例中。这不仅便于针对特定领域如实验数据进行快速访问,也降低了数据恢复的难度和成本。在模型训练中,增加冗余节点和重试机制帮助快速恢复训练,减少对训练周期的影响。

  2. 数据集版本管理与隔离:我们通过多层目录结构和特定命名规范来管理数据版本,以应对零售等场景中商品包装频繁更新的挑战;并通过统一编码的前缀管理系统,确保在模型训练或数据读取时能够迅速定位到所需数据集的特定版本;同时,采用多层目录下的子节点排列组合,实现对不同数据集版本的高效管理与快速组合,提高了数据处理的灵活性和效率。

04 未来规划

优化数据预热流程:目前,我们采取的方法是将 JuiceFS 挂载至本地,并通过拷贝方式将数据转移至模型训练的本地目录中,这一方式在初期实施时即被识别为效率较低。鉴于 JuiceFS 已提供诸如 caching 和 prefetch 等高级功能,我们计划深入调研并充分利用这些内置功能,以实现数据的智能缓存,从而更有效地管理数据集,提升数据访问速度。

跨地域数据访问的优化:在特定场景下,我们需访问位于欧洲的数据,而由于数据保护政策限制,这些数据不得被传输至欧洲以外地区。然而,临时访问是被允许的。当前,我们采用内部部署的 CDN 解决方案来应对这一需求,以控制成本并避免使用可能不够经济的原厂 CDN 服务。展望未来,我们期望能够利用 JuiceFS 的缓存机制,实现短时数据的共享与高效访问,以进一步优化跨地域数据处理的流程。

部署多个 JuiceFS 实例:我们将进行深入的调优与优化工作。通过精细调整配置参数、优化资源分配以及监控性能表现,我们旨在进一步提升系统的整体效能与稳定性,确保 JuiceFS 能够持续高效地支持我们的业务需求。