别再一把梭哈了:聊聊文件格式里的压缩取舍——Snappy 和 Zstd 到底怎么选?

举报
Echo_Wish 发表于 2025/12/27 20:02:46 2025/12/27
【摘要】 别再一把梭哈了:聊聊文件格式里的压缩取舍——Snappy 和 Zstd 到底怎么选?

别再一把梭哈了:聊聊文件格式里的压缩取舍——Snappy 和 Zstd 到底怎么选?

作者:Echo_Wish


做大数据这些年,我发现一个特别有意思的现象👇

大家都在拼算力、拼集群、拼调度,但真正悄悄烧钱的,往往是“文件格式 + 压缩算法”这种底层细节。

很多同学在建 Hive 表、写 Spark 任务、上湖仓的时候,压缩格式基本是这么选的:

  • Parquet + Snappy(默认)
  • ORC + Snappy(还是默认)
  • 为啥?
    👉 因为别人也这么用

直到有一天,账单一出来,S3 / OBS / HDFS 成本飙升,CPU 却没怎么跑满,才开始怀疑人生。

今天这篇文章,我不想跟你讲教科书定义,而是从真实生产视角,聊聊 Snappy 和 Zstd 这两个“老熟人”,以及它们背后真正的性能与成本博弈


一、先说结论:压缩算法,本质是“拿什么换什么”

很多人把压缩算法当成一个技术选项,其实它更像是一个资源交换器

你想省的 你要付出的
存储空间 CPU
IO 带宽 解压时间
网络流量 计算复杂度

所以,不存在“最优压缩算法”,只有“最合适场景的压缩算法”

接下来我们就用 Snappy 和 Zstd 这对老对手,掰开揉碎聊。


二、Snappy:快,就是它最大的信仰

1️⃣ Snappy 是干嘛的?

一句话总结:

Snappy 不是为了“压得小”,而是为了“解得快”。

它的设计目标非常明确:

  • 压缩比:一般
  • 压缩速度:快
  • 解压速度:非常快
  • CPU 消耗:低

这也是为什么它能成为 Hadoop / Spark / Hive 的默认选项

2️⃣ Snappy 的典型使用场景

我在生产中看到 Snappy 被大量用在这些地方:

  • 明细层(ODS / DWD)
  • 高频 Scan 表
  • 实时 / 准实时计算
  • CPU 紧张但磁盘还算富裕的集群

因为它的特性很“工程化”:
👉 你几乎不用为它操心


3️⃣ 用代码感受一下 Snappy(Python 示例)

import snappy
import time

data = b"A" * 10_000_000  # 10MB 模拟数据

start = time.time()
compressed = snappy.compress(data)
print("Snappy 压缩耗时:", time.time() - start)

start = time.time()
decompressed = snappy.decompress(compressed)
print("Snappy 解压耗时:", time.time() - start)

print("原始大小:", len(data))
print("压缩后大小:", len(compressed))

你会发现几个特点:

  • 压缩比可能只有 1.5~2 倍
  • 但压缩、解压都非常快
  • 解压速度几乎可以忽略

这就是 Snappy 能活这么久的原因。


三、Zstd:更“聪明”的新一代选手

如果说 Snappy 是“老实人”,那 Zstd 就是那种:

会动脑子、但吃点 CPU 的狠角色

1️⃣ Zstd 到底强在哪?

Zstd(Zstandard)是 Facebook(Meta)开源的压缩算法,它最大的优势只有一个:

在相同甚至更低 CPU 成本下,压缩比远高于 Snappy

核心特性:

  • 压缩比高(2~5 倍很常见)
  • 支持压缩等级(1~22)
  • 解压速度依然很快
  • 非常适合云对象存储

2️⃣ Zstd 的“隐藏价值”:省钱

我在云上项目里,最直观的感受是:

Zstd 是为“账单敏感型系统”而生的

举个很现实的例子:

  • 数据规模:100 TB
  • Snappy 压缩后:≈ 60 TB
  • Zstd 压缩后:≈ 35 TB

你不用我算,也知道对象存储一年能省多少钱。


3️⃣ 用代码体验 Zstd(Python 示例)

import zstandard as zstd
import time

data = b"A" * 10_000_000  # 10MB 模拟数据
cctx = zstd.ZstdCompressor(level=3)

start = time.time()
compressed = cctx.compress(data)
print("Zstd 压缩耗时:", time.time() - start)

dctx = zstd.ZstdDecompressor()
start = time.time()
decompressed = dctx.decompress(compressed)
print("Zstd 解压耗时:", time.time() - start)

print("原始大小:", len(data))
print("压缩后大小:", len(compressed))

你会明显感觉到:

  • 压缩稍慢一点
  • 但压缩比明显更高
  • 解压速度依然很能打

四、真正该怎么选?别再“默认 Snappy”了

这是我自己踩坑之后,总结的一套实战选择策略👇

✅ 优先选 Snappy 的情况

  • 实时 / 准实时计算
  • 高频全表 Scan
  • CPU 成本比存储更贵
  • 本地 HDFS,磁盘不差钱

👉 一句话:性能第一,钱第二


✅ 优先选 Zstd 的情况

  • 离线数仓
  • 冷数据、历史分区
  • 云对象存储(S3 / OBS / OSS)
  • 大宽表、重复字段多

👉 一句话:能省钱,就多算点 CPU


五、我的一个真实建议:分层用,不要二选一

这是我个人非常认可的一种做法:

同一个数仓,用不同压缩策略

比如:

层级 压缩策略
ODS Snappy
DWD Snappy
DWS Zstd
ADS Zstd
历史归档 Zstd(level=6+)

这样做的好处是:

  • 热数据不拖慢计算
  • 冷数据最大化省钱
  • 技术不是非黑即白,而是服务业务

六、写在最后:技术选型,其实是价值观

说点不那么“技术”的话。

我越来越觉得:

一个成熟的工程师,选技术不是看“谁更先进”,而是看“谁更合适”。

Snappy 没有过时,
Zstd 也不是银弹。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。