小文件会给存储平台及其支持的应用程序带来大问题。在 Google 上搜索“小文件性能”会得到 200 多万个结果。这篇博文将深入探讨小文件问题,深入研究其根源并总结解决方案。
问题陈述
在本讨论中,小文件通常被认为是任何小于 64 KB 的文件。当我们与客户合作调整他们的集群时,我们发现越来越多(数十亿甚至万亿)的文件大小在 16 KB 到 1 MB 之间。这种小文件通常是保存机器生成的基于事件的流的结果。将小文件写入对象存储非常简单,但对其进行查询的速度会慢得多,甚至可能无法完成。查询许多小文件会产生读取元数据、执行非连续磁盘查找、打开文件、关闭文件并重复的开销。每个文件的开销只有几毫秒,但当您查询数千、数百万甚至数十亿个文件时,这些毫秒就会累积起来。
分析引擎难以对大量小文件运行查询。许多企业在处理来自物联网设备、服务器、网络设备和应用程序日志等流式源时面临这一挑战——所有这些都可能每秒生成数千个事件日志,每个日志都存储在一个单独的 JSON、XML 或 CSV 文件中。查询一天的日志可能需要数小时。
构建用于解决昨日大数据问题的技术无法应对大量小文件的挑战。旨在处理少量大文件的硬件和应用程序,不适合摄取、编目和查询大量小文件。系统在存储大量小文件的同时保持繁荣的能力的关键指标是 IOPS,即每秒的输入输出(读写)量。一个 IOP 包括寻道时间、读取时间和数据传输时间。对于机械介质(如硬盘驱动器),顺序读写明显快于随机读写。随机读取和写入单个文件的效率低于连续读取和写入多个文件。
元数据管理、跨节点和磁盘的数据分布、I/O 管理、缓存管理和网络开销会导致性能低下和存储效率降低。在针对大量小文件进行优化时,这些是需要关注的领域。优化需要全面了解系统工程,包括硬件和软件的组合和交互。由大量小文件引起的问题必须在多个层面进行解决,并且必须纠正瓶颈才能实现显著的优化。
特别是元数据管理,可能会削弱存储系统有效存储大量小文件的能力。在处理大型连续文件时,元数据操作开销会被更大的数据操作开销抵消。当小文件数量急剧增加时,元数据操作开始严重影响系统性能。
Hadoop 和小文件
特别是 Hadoop,受到了向小文件转变的严重冲击。Hadoop 适用于存储和处理少量大文件,而不是大量小文件。HDFS 的默认块大小现在为 128MB(以前为 64MB)。存储一个 128MB 的文件与存储一个 16KB 的文件一样,都需要一个 128MB 的块。此外,HDFS 中的每个文件、目录和块都将在元数据中跟踪,元数据在 NameNode 内存中的每个记录占用 150 到 300 字节。一亿个小文件将消耗数百 GB 的 namenode 内存,并且由于存储了大部分为空的块而浪费了超过 10 TB 的空间。随着越来越多的文件需要写入、映射和查询,节点之间通信量的增加进一步降低了效率。
SAN/NAS 和小文件
当涉及大量小文件时,SAN 和 NAS 解决方案也存在不足。这两种技术都旨在提供高 IOPS,但都没有为大量应用程序并发读取和数据源并发写入而设计。两者都依赖于 RAID 和复制来实现持久性和高可用性,这两者都会增加写入延迟并降低存储效率。SAN 提供非常低的延迟和高吞吐量,但仅限于直接连接到它的服务器。NAS 作为网络挂载卷,在存储大量小文件时面临块存储的低效率和文件系统的限制。但 NAS 的主要弱点在于它无法提供足够的规模性能,并且在面临大量并发请求时性能会下降。
使用传统数据库
对小文件问题的典型响应是将这些微小的数据写入传统的关联数据库。不幸的是,这也不能解决性能问题。它会在一段时间内有效,但没有哪个数据库可以在 PB 级的小文件上提供持久性和性能。是的,从历史上看,使用数据库来存储和查询小文件是一个好主意——数据库提供 ACID 事务、索引,并且可以对这些记录执行详细的查询,但当面临解决当今组织面临的大量小文件问题所需的庞大数量的记录时,它们无法快速地执行任何一项操作。
数据库在快速摄取大量小文件方面做得并不好,但这正是流式数据用例中所需的功能。表示数据记录、日志条目或设备遥测的小对象来自无数应用程序和设备,规模和速度都非常庞大。这些数据无法写入数据库。没有哪个数据库能够以支持实时分析所需的速度和规模运行。
架构正在远离传统的数据库和文件系统,转向存储和查询大量小文件。数据库是写入时模式、分区/分片、预先构建索引以加快查询速度的优秀工具,但所有这些在处理大量小文件时都不起作用。
数据湖仓用于小文件
数据湖仓一部分是数据仓库,一部分是数据湖,两部分都在后台使用对象存储进行存储。这为工程师在决定如何处理大量小文件时提供了选择。以 Parquet、AVRO 或 ORC 格式到达的文件可以轻松地摄取到数据湖仓的数据仓库端。其他文件可以发送到数据湖,在那里可以对其进行分析或转换,以便摄取到数据仓库中。

数据仓库不是普通的数据库,它基于开放式表格格式,提供诸如时间旅行、模式演变、分区演变、零拷贝分支、外部表和 ACID 事务等现代功能。关于小文件,值得特别注意的是,基于 OTF 的数据仓库是读取时模式,在摄取大量小文件时可以带来性能优势。
这是一种强大的新兴存储解决方案,它利用对象存储来存储结构化和非结构化数据。由于数据湖仓构建于分布式对象存储之上,因此可以轻松地扩展。此外,数据湖仓中的计算和存储是分离的,从而为处理用于查询数据仓库的 SQL 的处理引擎提供了进一步的优化。
MinIO 作为数据湖仓的存储层
MinIO 作为数据湖仓的存储层表现出色。在最近的性能基准测试中,我们测量的 PUT 吞吐量为 165 GiB/秒,GET 吞吐量为 325 GiB/秒。MinIO 将元数据和对象存储在线,无需查询外部元数据数据库。MinIO 可以上传后自动提取 .tar 文件并从 ZIP 归档文件中下载单个文件。
MinIO 的擦除编码实现是提升小对象性能、存储效率和功能的关键组成部分。快速的擦除编码允许以高规模捕获小对象,并将其与奇偶校验一起分布到多个驱动器和节点上,以立即保护持久性和高可用性。例如,使用最大擦除编码奇偶校验,您可以在 MinIO 集群中丢失一半的驱动器,但仍然可以保持持久性。
小文件解决方案
许多当今的工作负载(尤其是流式和日志分析)通过强迫应用程序和存储系统处理大量小文件,对它们提出了很高的要求。大数据很少意味着分析一个大文件。更常见的是,大数据意味着数百万或数十亿个小于 1 MB 的文件。数据库和文件系统无法扩展以提供实时分析所需的性能。
使用 MinIO 构建的数据湖仓是解决小文件问题的答案。业界领先的性能加快了摄取、查询和检索速度,而擦除编码则提供了持久性。永远不会丢失数据或导致查询超时。
如果您的系统难以(甚至无法)满足摄取、存储、查询和检索大量小文件的需求,那么请详细了解数据湖仓并立即下载 MinIO。
有问题?请随时在我们的Slack 频道上联系我们。