大多数数据都以易于读取的文件格式存储,以便于应用程序互操作。虽然图像、视频和声音压缩有广泛使用的格式,但大多数其他数据都以文本形式存储,如 JSON、CSV 或其他类似的基于文本的格式。
Parquet、Avro 和 ORC 等格式具有可选的压缩功能,因此通常这些格式在存储时已经被压缩。视频和图像通常还使用特定领域的算法进行压缩,这些算法提供比通用格式更好的压缩效果。
但是,对于自定义数据,最好以不复杂的格式保存数据,其中不包括访问的解压缩步骤。我们希望提供一个选项,在将数据存储到磁盘之前对其进行压缩。
MinIO 压缩的开发目的是在不影响系统整体性能的情况下实现透明压缩。
MinIO 使用基于Snappy 的压缩方法,称为 S2。它与 Snappy 内容兼容,但具有两种格式扩展。首先,它允许比 Snappy 流允许的 64KB 块更大的块。这极大地提高了压缩率。其次,它添加了“重复偏移”,主要针对机器生成的数据(例如日志文件、JSON 和 CSV)提供压缩改进。它还允许对长度超过 64 字节的匹配进行有效编码,这是 Snappy 的痛点。
当输入速度快于单个核心可以吸收的速度时,S2 还允许同时压缩多个块。这对于保持个人请求的响应能力非常重要。实际上,16 个以上核心的限制将是内存速度。
一些设备供应商在计算每 TB 成本时会承诺甚至假设给定的压缩比。对于压缩,不保证比率高于 1:1。不同的数据类型产生不同的压缩比,我们认为没有有意义的方法来提供任何平均压缩比。压缩比永远不应该在真空中评估——它们应该始终与压缩速度配对,因为实际压缩是这两个因素的权衡。
让我们比较单个数据类型以观察差异。我们比较了这些算法在 AMD64 平台上的 Go 实现,最多使用 16 个内核。
首先,横轴是截断的压缩比,从未压缩的大小实现的缩减。正确的是更好。为了提供参考,已包含单线程 gzip 级别 5。
压缩机 | 速度MB/秒 | 尺寸 | 减少 | 十月 MB/秒 |
---|---|---|---|---|
S2 默认 | 15148 | 1043196283 | 83.37% | 2378 |
S2 更好 | 11551 | 954430842 | 84.79% | 2300 |
S2最佳 | 680 | 832855431 | 86.73% | 2572 |
LZ4最快 | 5645 | 1280414160 | 79.59% | 2680 |
LZ4最佳 | 第1552章 | 1091826460 | 82.60% | 2694 |
活泼 | 第946章 | 1525176492 | 75.69% | 1828 |
压缩L5 | 206 | 942726276 | 84.97% | 第557章 |
尽管 S2 提供并发解压,但解压速度是使用单核。
对于此数据,Snappy 比 Gzip 参考值低约 10%。由于我们处理的是减少百分比,这也意味着 Snappy 占用的空间大约是 Gzip 压缩数据的 1.6 倍。这忽略了 Snappy 解压缩速度比 Gzip 快大约 4 倍的事实。
LZ4 通常被认为优于 Snappy。允许在多个内核上进行压缩的 LZ4 实现也使这一点变得更加清晰。但基础压缩更好。 LZ4 Best(有时也称为 LZ4-HC)提供接近 gzip 的压缩,但即使解压缩速度很快,压缩也无法达到交互速度。
S2提供三种压缩级别; S2 Default 是最快的,在单核使用方面可以被视为 Snappy 的直接竞争对手。对于这种数据类型,它的性能优于任何 LZ4 级别,吞吐量显着提高。 MinIO 将这种模式用于无法使用程序集实现的平台。
S2 Better 允许用一点 CPU 来换取更高的压缩率。这里的压缩可与 Gzip 相媲美,但解压速度要快得多。 MinIO 在可进行汇编的平台(目前是 AMD64)上使用此模式。
S2 Best 是 S2 在当前格式下可以实现的最佳压缩。这可以用于压缩速度/资源不是最重要的情况,但仍然需要快速解压缩。目前 MinIO 不使用此模式,但可能将其实现为一段时间未更改的对象的生命周期选项。
为了进行比较,以下是其他数据类型的一些比较:
现代压缩的一个重要特征是它对预压缩数据表现良好。传统上,预压缩数据一直是压缩算法的一个问题。当遇到不可压缩的数据时,压缩器通常会不合理地减慢速度。
因此,许多人本能地知道重新压缩已经压缩的数据是不好的。然而,许多现代实现现在能够在合理的程度上快速跳过不可压缩部分。
对于上述压缩器,以下是 2GiB(2,147,483,647 字节)不可压缩数据的速度:
压缩机 | 速度MB/秒 | 尺寸 | 减少 |
---|---|---|---|
S2 默认 | 13045 | 2147487753 | 0.00% |
S2 更好 | 9894 | 2147487753 | 0.00% |
S2最佳 | 3938 | 2147487753 | 0.00% |
LZ4快速 | 6400 | 2147485710 | 0.00% |
LZ4最佳 | 12488 | 2147745841 | -0.01% |
活泼 | 6564 | 2147745801 | -0.01% |
Gzip(执行)L5 | 63 | 2148139030 | -0.03% |
Gzip(替代)L5 | 5535 | 2147647512 | -0.01% |
这里我们还包含了 Go 标准库中的 gzip 作为这种“不良”行为的代表。另一种 gzip 实现不会出现此问题。在所有其他情况下,内容的处理速度都非常快,并且他们会通过。
这意味着 MinIO 有望很好地处理预压缩数据。
压缩的一个典型缺点是失去了在文件内跳跃的能力。解决方案是独立压缩块并保留一个索引,该索引将许多未压缩偏移量映射到可以开始解压缩的压缩偏移量。
压缩独立块会稍微降低压缩率,但对于较大的块,压缩率会降低。 Snappy/S2 按设计将流压缩为独立块。
对于 MinIO,这是相关的,因为 S3 GetObject 请求可以包含要检索的可选范围。这允许检索对象的一部分,我们希望它尽可能高效。
从RELEASE.2022-07-13T23-29-44Z开始,我们现在为上传的每个大于 8MB 的文件部分生成一个索引。然后索引在内部附加到元数据。这使我们能够有效地向前跳过并仅解码返回请求数据所需的对象部分。
索引通常为 16 字节 + 每 MB 数据大约 3 字节。这使得 MinIO 能够以与检索第一个字节相同的速度提供压缩文件中的任何字节。
默认情况下,MinIO 需要一个额外的参数来压缩磁盘上要加密的数据。这是为了确保您了解这一点的含义。
压缩数据时,您会得到两个数字;未压缩和压缩后的大小。如果不进行压缩,任何获取您数据的人都只能看到其中之一——未压缩的大小。
虽然这仍然无法让您访问压缩文件中的任何数据,但它确实提供了一些有关数据的提示。它可以告诉您某些不可能的数据类型。如果您看到压缩率为 50% 的文件,则它极不可能包含 MP4 压缩视频。
类似地,压缩为仅几个字节的文件可能包含非常简单的重复序列。无法判断顺序是什么,但它减少了可能性。 RELEASE.2022-07-13T23-29-44Z中的 MinIO 会将压缩输出填充为 256 字节的倍数。此填充不会在任何地方记录。我们不认为这完全解决了该问题,但它大大降低了泄露的大小信息对对手的有用性。
这是 MinIO 不向客户端返回任何有关压缩大小的信息的主要原因。因此,任何有关此的信息都需要访问后端存储或后端网络通信。
有了这些信息,您现在就具备了足够的知识来确定启用压缩和加密是否安全。
MinIO 上不可能进行CRIME式攻击,因为我们不允许修改或附加到任何压缩流。我们也不跨对象版本进行重复数据删除/压缩,因为这会泄漏太多有关文件的信息。
默认情况下,MinIO 中禁用磁盘压缩。可以随时启用或禁用磁盘压缩。要启用磁盘压缩,请使用mc admin config set myminio compression enable=on
。
这将为预设数量的扩展名和 MIME 类型启用压缩。默认情况下,这些将包括:
扩展 | 哑剧类型 |
---|---|
.txt.log.csv.json.tar.xml.bin | 文本/*应用程序/jsonapplication/xmlbinary/八位字节流 |
您可以使用mc admin config get myminio compression
检查当前设置。
您可以随时通过修改以下内容来修改此列表:
mc admin config set myminio compression \ extensions=.txt,.log,.csv,.json,.tar,.xml,.bin \ mime_types=text/*,application/json,application/xml,binary/octet-stream
默认情况下,MinIO 强制排除通常不可压缩数据的扩展名,例如 gzip、音频、视频、图像文件。
通过将扩展名列表和 mime 类型设置为空,可以对除排除对象之外的所有对象启用压缩:
mc admin config set myminio compression enable=on extensions= mime_types=
最终设置是allow_encryption=on
,它甚至允许对要加密的对象进行压缩。仅当您阅读了上面的部分并理解其含义后才设置此项。
MinIO 提供一流的压缩方案,允许对磁盘上的数据进行完全透明的压缩。在许多情况下,只需启用压缩即可降低存储成本。
当启用压缩时,GET 和 PUT 性能在所有情况下都应保持接近相同。事实上,在性能受到磁盘读取速度限制的情况下,压缩可以提供额外的性能,因为需要读取的数据更少。
我们将不断添加新功能。我们目前正在评估存储桶/前缀级别配置选项以及通过生命周期压缩,这将在文件达到一定年龄时对其进行压缩。
如果您对这些功能感兴趣,请下载 MinIO并亲自尝试。如果您有任何疑问或想告诉我们您正在使用 MinIO 构建的出色应用程序,请通过[email protected]联系我们、加入Slack 社区、关注我们的博客或订阅我们的时事通讯。
也发布在这里。