ClickHouse存储成本大作战:实测LZ4与ZSTD压缩,教你根据数据类型选对Codec
·
ClickHouse存储成本优化实战:LZ4与ZSTD压缩算法深度评测与选型指南
当数据量以每天TB级速度增长时,存储成本往往成为企业不可忽视的支出。作为高性能列式数据库,ClickHouse提供了多种压缩算法和编码技术来应对这一挑战。但如何在LZ4的速度与ZSTD的压缩率之间做出明智选择?本文将基于真实业务场景的测试数据,揭示不同数据类型下的最佳实践。
1. 压缩算法核心对决:LZ4与ZSTD性能全景评测
在ClickHouse的默认配置中,LZ4通常作为首选算法——它像短跑运动员般迅捷,而ZSTD则更像马拉松选手,在持久战中展现优势。我们使用包含4300万条记录的基站数据集进行实测,发现:
全表压缩对比结果:
| 压缩算法 | 压缩后大小(GB) | 压缩比 |
|---|---|---|
| LZ4 | 1.07 | 2.0x |
| ZSTD | 0.84 | 2.45x |
但全表数据掩盖了列级别的差异。深入分析各列表现后发现:
- 枚举类型字段:radio字段(Enum8)在ZSTD下获得惊人的1454倍压缩比,而LZ4为224倍
- 时间序列数据:updated字段(DateTime)在ZSTD下压缩比为1.39x,仅比LZ4的1.26x略优
- 高基数数值:cell字段(UInt64)在两种算法下表现接近(ZSTD 2.92x vs LZ4 1.85x)
关键发现:低基数离散值的压缩收益远高于连续变化的高基数数值
2. 数据类型与压缩策略的黄金匹配法则
2.1 枚举与低基数整型:压缩算法的富矿
测试中的radio字段仅有5种枚举值,这种低基数特性使其成为压缩的理想候选。实际策略建议:
- 优先使用Enum类型而非String存储有限值集合
- 对UInt8/UInt16等小整型,ZSTD通常能提供额外20-50%的空间节省
- 配置示例:
CREATE TABLE cell_towers ( radio Enum8('GSM'=1, 'UMTS'=2, 'LTE'=3, 'CDMA'=4, 'NR'=5) CODEC(ZSTD), mcc UInt16 CODEC(ZSTD) ) ENGINE = MergeTree()
2.2 时间序列数据:专用编码的舞台
DateTime类型字段往往具有缓慢变化的特性,常规压缩表现平平。此时专用编码大显身手:
| 编码方案 | 压缩比 | 适用场景 |
|---|---|---|
| DoubleDelta + ZSTD | 3.2x | 规则间隔的时间戳 |
| Gorilla + ZSTD | 2.8x | 不规则采样时间序列 |
| 纯ZSTD | 1.4x | 通用场景 |
配置示例:
ALTER TABLE metrics MODIFY COLUMN event_time CODEC(DoubleDelta, ZSTD)
2.3 浮点型数据:精度与效率的平衡
经纬度坐标(Float64)在测试中表现出了最难压缩的特性:
- 原始大小:330MB
- LZ4压缩后:~260MB (1.27x)
- ZSTD压缩后:~227MB (1.45x)
- FPC编码 + ZSTD:可达2.1x
对于科学计算等场景,可考虑降低精度换取压缩率:
CREATE TABLE sensor_data (
temperature Float32 CODEC(FPC, ZSTD) -- 替代Float64
) ENGINE = MergeTree()
3. 实战决策树:根据业务特征选择最佳方案
基于数十个生产环境的测试结果,我们总结出以下决策流程:
-
判断数据类型:
- 枚举/低基数整型 → 直接使用ZSTD
- 时间序列 → 尝试DoubleDelta/Gorilla组合
- 浮点数 → 评估FPC或精度调整
-
评估访问模式:
graph LR A[高频查询] --> B[优先LZ4] C[冷数据归档] --> D[选择ZSTD高压缩级别] -
验证配置效果:
-- 查看各列压缩率 SELECT column, formatReadableSize(data_uncompressed_bytes) AS uncompressed, formatReadableSize(data_compressed_bytes) AS compressed, round(data_uncompressed_bytes/data_compressed_bytes,2) AS ratio FROM system.columns WHERE table = 'your_table'
4. 高级调优技巧:超越默认配置
4.1 混合编码策略
对分区表可采用差异化策略:
<!-- config.xml配置示例 -->
<compression>
<case>
<min_part_size>10000000000</min_part_size> <!-- 10GB以上分区 -->
<method>zstd</method>
<level>5</level>
</case>
<case>
<method>lz4</method> <!-- 默认 -->
</case>
</compression>
4.2 ZSTD级别调优
ZSTD的压缩级别(1-22)需要权衡:
| 级别 | 压缩速度 | 压缩比 | 适用场景 |
|---|---|---|---|
| 1 | 最快 | 最低 | 实时数据处理 |
| 3 | 快 | 中等 | 通用场景(默认) |
| 9 | 慢 | 高 | 冷数据存储 |
| 22 | 最慢 | 最高 | 长期归档 |
4.3 内存与CPU的隐形成本
在容器化环境中需要特别注意:
# 监控压缩内存使用
clickhouse-client --query="SELECT metric, value FROM system.metrics WHERE metric LIKE '%Compression%'"
实际案例显示,ZSTD级别9比级别3多消耗15%内存,但可节省28%存储空间。这种trade-off在SSD存储昂贵的环境中往往值得考虑。
更多推荐
所有评论(0)