想了解 ClickHouse 为何能如此高效地压缩数据,我们建议阅读这篇文章。简而言之,我们的列式数据库按列顺序写入值。对这些值进行排序后,相同的值会彼此相邻,而压缩算法能够利用数据中连续出现的模式。除此之外,ClickHouse 还提供 编解码器 和更细粒度的数据类型,让你能够进一步轻松优化压缩效果。ClickHouse 中的压缩会受到 3 个主要因素的影响:
- 排序键
- 数据类型
- 使用了哪些 编解码器
选择合适的数据类型来优化压缩
posts 表在以下 schema 下的压缩统计信息:
posts- 未做类型优化,且没有排序键的 schema。posts_v3- 经过类型优化的 schema,为每一列都选择了合适的类型和位宽,并使用排序键(PostTypeId, toDate(CreationDate), CommentCount)。
posts 的大小。
关于 compact 和 wide parts 的说明
关于 compact 和 wide parts 的说明
如果你看到
compressed_size 或 uncompressed_size 的值为 0,这可能是因为
parts 的类型是 compact 而不是 wide (请参阅 system.parts 中 part_type 的说明) 。
part 格式由设置 min_bytes_for_wide_part
和 min_rows_for_wide_part 控制。这意味着,如果插入的
数据生成的 part 没有超过上述设置的阈值,那么该 part 就会是 compact,
而不是 wide,因此你将看不到 compressed_size 或 uncompressed_size 的值。下面演示这一点:查询
响应
上述查询依赖系统数据库中的 columns 表。该数据库由 ClickHouse 管理,堪称一个信息宝库,其中包含从查询性能指标到后台 cluster 日志等大量实用信息。对于想进一步了解的读者,我们推荐阅读 “System Tables and a Window into the Internals of ClickHouse” 及其配套文章[1][2]。
如果要汇总表的总大小,我们可以将上面的查询简化为:
posts_v3 (采用了优化后数据类型和排序键的表) 重复执行此查询后,可以看到未压缩大小和压缩后大小都明显减小。
Body、Title、Tags 和 CreationDate 这些列的存储空间可显著减少。
选择合适的列压缩编解码器
更多选项请参见这里。
下面我们为
Id、ViewCount 和 AnswerCount 指定 Delta 编解码器,假设它们与排序键线性相关,因此应能从 Delta 编码中受益。
ClickHouse Cloud 中的压缩
ZSTD 压缩算法 (默认值为 1) 。这种算法的压缩速度会随压缩级别而变化 (级别越高,速度越慢) ,但它的优势在于解压速度始终很快 (波动约 20%) ,并且还支持并行处理。我们过往的测试还表明,这种算法通常已经足够高效,甚至可能优于结合 codec 使用的 LZ4。它对大多数数据类型和数据分布都很有效,因此是一个合理的通用默认选择,这也是为什么即使不做优化,我们的初始压缩效果也已经非常出色。