强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Btrfs 文件系统运维完全教程 / 第 6 章:数据压缩

第 6 章:数据压缩

6.1 Btrfs 压缩概述

Btrfs 支持透明压缩(Transparent Compression),数据在写入磁盘前自动压缩,读取时自动解压,对应用程序完全透明。

压缩的工作原理

应用程序写入数据
       │
       ▼
  Btrfs 文件系统
       │
       ▼
  压缩引擎(zstd/lzo/zlib)
       │
       ▼
  压缩后写入磁盘
  
  
磁盘读取数据
       │
       ▼
  Btrfs 文件系统
       │
       ▼
  解压引擎
       │
       ▼
  返回原始数据给应用程序

支持的压缩算法

算法说明内核要求
zstdZstandard,Facebook 开发,压缩率和速度平衡4.14+(级别支持 5.15+)
lzoLempel-Ziv-Oberhumer,极快但压缩率较低所有版本
zlib与 gzip 相同算法,压缩率高但较慢所有版本
no不压缩

6.2 压缩算法详解

6.2.1 zstd(推荐)

zstd(Zstandard)是目前 Btrfs 推荐的压缩算法:

压缩级别压缩速度解压速度压缩率适用场景
1极快极快中等实时压缩,低延迟
3(默认)极快较好通用推荐
5中等存储优先
9很好归档数据
15很慢极好长期存储
19极慢中等最佳极限压缩
# 使用 zstd 默认级别(3)
mount -o compress=zstd /dev/sdb1 /mnt

# 指定压缩级别
mount -o compress=zstd:1 /dev/sdb1 /mnt  # 快速
mount -o compress=zstd:3 /dev/sdb1 /mnt  # 默认
mount -o compress=zstd:9 /dev/sdb1 /mnt  # 高压缩
mount -o compress=zstd:15 /dev/sdb1 /mnt # 归档

# 查看 zstd 压缩比
btrfs filesystem df /mnt

6.2.2 lzo

LZO 速度极快,但压缩率低于 zstd:

特性说明
压缩速度极快(比 zstd 快 2-3 倍)
解压速度极快
压缩率较低(约 2:1)
CPU 占用极低
适用场景低延迟要求、实时压缩
# 使用 lzo 压缩
mount -o compress=lzo /dev/sdb1 /mnt

6.2.3 zlib

zlib 与 gzip 使用相同算法,压缩率最高但最慢:

特性说明
压缩速度
解压速度中等
压缩率高(约 3:1)
CPU 占用
适用场景冷数据、归档存储
# 使用 zlib 压缩
mount -o compress=zlib /dev/sdb1 /mnt

6.2.4 算法对比

指标zstd:3lzozlib
压缩速度★★★★★★★★★★★
解压速度★★★★★★★★★★★★★
压缩率★★★★★★★★★★★★
CPU 开销
内存开销
推荐场景通用实时/低延迟归档

6.3 压缩配置

6.3.1 挂载选项

# 启用压缩(默认算法和级别)
mount -o compress /dev/sdb1 /mnt

# 指定算法和级别
mount -o compress=zstd:3 /dev/sdb1 /mnt

# 强制压缩所有数据
# 默认情况下 Btrfs 会跳过不可压缩的数据(如已压缩的视频)
# compress-force 会尝试压缩所有数据
mount -o compress-force=zstd:3 /dev/sdb1 /mnt

compress vs compress-force

行为compresscompress-force
可压缩数据压缩压缩
已压缩数据(视频等)跳过仍然尝试压缩
性能影响较小可能较大
推荐场景通用混合数据类型

6.3.2 压缩级别与内核版本

# 查看内核是否支持压缩级别
uname -r
# 5.15+ 支持 zstd 级别
# 5.19+ 支持 zstd 所有级别 (1-15)
# 6.2+ 支持 zstd 最高级别 (1-19)

# 验证压缩设置
mount | grep /mnt
# /dev/sdb1 on /mnt type btrfs (rw,relatime,compress=zstd:3)

6.3.3 按文件扩展名选择性压缩

Btrfs 会根据文件内容自动判断是否压缩,但也可以通过文件属性控制:

# 禁用某个文件的压缩
chattr +m /path/to/video.mp4

# 强制压缩某个文件
chattr +c /path/to/textfile.txt

# 查看文件属性
lsattr /path/to/file

📝 注意: chattr +m 禁用压缩,chattr +c 启用压缩。但 Btrfs 的实际行为取决于挂载选项和内核版本。

6.3.4 永久配置

# /etc/fstab 中配置压缩
UUID=xxx /data btrfs defaults,compress=zstd:3,noatime,space_cache=v2 0 0

# 对于根分区
UUID=xxx / btrfs subvol=/@,defaults,compress=zstd:1,ssd,discard=async 0 0

6.4 在线切换压缩

6.4.1 重新挂载切换

# 当前挂载(无压缩)
mount | grep /mnt
# /dev/sdb1 on /mnt type btrfs (rw,relatime)

# 在线启用压缩
sudo mount -o remount,compress=zstd:3 /mnt

# 验证
mount | grep /mnt
# /dev/sdb1 on /mnt type btrfs (rw,relatime,compress=zstd:3)

# 切换压缩算法
sudo mount -o remount,compress=lzo /mnt

# 禁用压缩
sudo mount -o remount,compress=no /mnt

📝 注意: 重新挂载只影响新写入的数据,已写入的数据保持原有压缩状态。要对已有数据重新压缩,需要使用 balance 操作。

6.4.2 对已有数据重新压缩

# 方法 1:使用 balance 重新压缩(推荐)
sudo btrfs balance start -dcompress -mcompress /mnt

# 指定压缩算法
sudo btrfs balance start -dcompress=zstd:3 -m /mnt

# 方法 2:复制文件触发重新压缩
sudo cp --reflink=never /mnt/largefile /mnt/largefile.tmp
sudo mv /mnt/largefile.tmp /mnt/largefile

6.5 监控压缩效果

6.5.1 查看压缩比

# 查看空间使用情况
sudo btrfs filesystem df /mnt

# 查看详细使用(包括压缩节省的空间)
sudo btrfs filesystem usage /mnt

# 查看特定目录的压缩效果
sudo compsize /mnt/data
# Processed 1000 files, 200 regular extents (200 refs), 800 inline.
# Type       Perc     Disk Usage   Uncompressed Referenced  
# TOTAL       45%      10.00GiB      22.00GiB    22.50GiB
# none       100%       2.00GiB       2.00GiB     2.10GiB
# zstd        37%       8.00GiB      20.00GiB    20.40GiB

compsize 工具详解:

# 安装 compsize
sudo apt install compsize    # Debian/Ubuntu
sudo dnf install compsize    # Fedora
sudo pacman -S compsize      # Arch

# 查看压缩统计
sudo compsize /mnt
# Type       Perc     Disk Usage   Uncompressed Referenced  
# TOTAL       45%      10.00GiB      22.00GiB    22.50GiB
# none       100%       2.00GiB       2.00GiB     2.10GiB  ← 未压缩数据
# zstd        37%       8.00GiB      20.00GiB    20.40GiB  ← zstd 压缩数据
字段说明
Type压缩算法类型
Perc压缩率百分比(越低越好)
Disk Usage磁盘实际使用空间
Uncompressed压缩前大小
Referenced引用的逻辑大小

6.5.2 单文件压缩信息

# 查看文件的物理布局
sudo filefrag -v /mnt/largefile

# 使用 btrfs 查看 extent 信息
sudo btrfs inspect-internal file-extent-map /mnt/largefile
# 或
sudo btrfs inspect-internal logical-resolve <logical_addr> /mnt

6.6 压缩性能调优

6.6.1 压缩级别选择指南

数据类型推荐级别原因
日志文件zstd:1 或 lzo低延迟写入
用户文档zstd:3好的压缩率
源代码zstd:3文本数据压缩效果好
虚拟机磁盘compress-force=zstd:3混合数据
数据库不压缩避免额外开销
视频/图片不压缩已压缩数据
备份归档zstd:9-15最大压缩率

6.6.2 SSD vs HDD 压缩策略

SSD:

# SSD 上使用较低压缩级别(减少 CPU 开销,SSD 速度已够快)
mount -o compress=zstd:1,ssd,discard=async /dev/sdb1 /mnt

HDD:

# HDD 上使用较高压缩级别(压缩可减少磁盘 I/O,弥补 CPU 开销)
mount -o compress=zstd:5 /dev/sdb1 /mnt

6.6.3 压缩对性能的影响

场景压缩影响
顺序读略有增加延迟(解压),但更少磁盘 I/O
顺序写增加 CPU 使用,但减少磁盘写入量
随机读压缩可能导致读放大
随机写COW + 压缩可能加剧碎片化
大文件压缩收益明显
小文件压缩开销可能超过收益

6.6.4 内存和 CPU 开销

# 查看压缩使用的内存
cat /proc/fs/btrfs/features
# 或
cat /sys/fs/btrfs/<uuid>/compression_stats

# 监控 CPU 使用
top -p $(pgrep btrfs)

6.7 业务场景实战

6.7.1 Web 服务器日志压缩

# /var/log 日志目录
mount -o compress=zstd:1,noatime /dev/sdb1 /var/log
# 日志写入频繁,使用最低压缩级别

6.7.2 虚拟机磁盘压缩

# 虚拟机镜像存储
mount -o compress-force=zstd:5 /dev/sdb1 /vms
# force 是因为虚拟机磁盘内可能有压缩数据

6.7.3 NAS 文件服务器

# NAS 共享存储
mount -o compress=zstd:3,noatime /dev/sdb1 /nas
# 通用压缩,平衡速度和压缩率

6.7.4 归档存储

# 冷数据归档
mount -o compress=zstd:15 /dev/sdb1 /archive
# 高压缩级别,存储优先

6.8 本章小结

操作命令
启用压缩mount -o compress=zstd:3 /dev/sdX /mnt
在线切换mount -o remount,compress=lzo /mnt
强制压缩mount -o compress-force=zstd /dev/sdX /mnt
禁用压缩mount -o remount,compress=no /mnt
查看压缩比compsize /mnt
重新压缩btrfs balance start -dcompress /mnt

关键要点

  1. 推荐使用 zstd,级别 1-5 适合大多数场景
  2. 压缩级别只影响新写入的数据
  3. compress-force 会压缩所有数据,包括已压缩的
  4. 使用 compsize 监控压缩效果
  5. SSD 使用低级别,HDD 可以用更高级别

扩展阅读