关于TiDB数据压缩的疑问?

【 TiDB 使用环境】 测试/ Poc
【 TiDB 版本】v7.5.0
【复现路径】检查TiDB数据库单表大小
【遇到的问题:通过sysbench导入一张单表,验证TiDB实际存储空间使用量,我看文档说TiDB是有压缩比例的,但测试单表发现对比MySQL并未发现数据被压缩(TiDB的单表大小为597M,MySQL单表大小为459M),请问是否正常? 请大佬解惑?

问题重现:

  1. 分别通过sysbench导入一张200万条记录的表到TiDB V7.5和MySQL V5.12
    sysbench --db-driver=mysql
    –mysql-host=10.xx.xx.150
    –mysql-port=3308
    –mysql-user=root
    –mysql-password=XXXXX
    –mysql-db=sbtest
    –table_size=2000000
    –tables=1
    –events=0
    oltp_read_write prepare

  2. 分别计算大小
    TiDB的单表大小为597M,MySQL单表大小为459M。
    TiDB表大小截图

MySQL表大小截图

还有一个疑问,information_schema.tables视图中说明 * DATA_LENGTH:数据长度。数据长度 = 统计信息中的行数 × 元组各列存储长度和,这里尚未考虑 TiKV 的副本数。
如果是三副本那么表的实际占用大小,是否就是DATA_LENGTH乘以3?
我在网上找了脚本,里面计算的597M表大小的磁盘空间为1243M,计算结果好像也不是DATA_LENGTH X 3,那么问题是如何准确计算表的磁盘空间实际使用大小?
image

TiDB的tikv节点实用的RocksDB,RocksDB的默认压缩算法为:[no:no:lz4:lz4:lz4:zstd:zstd]
RocksDB6层的压缩为:[no:no:lz4:lz4:lz4:zstd:zstd]

表示 level0 和 level1 不压缩;

level2 到 level4 采用 lz4 压缩算法;

level5 和 level6 采用 zstd 压缩算法。

no 表示没有压缩,lz4 是速度和压缩比较为中庸的压缩算法,zlib 的压缩比很高,对存储空间比较友好,但是压缩速度比较慢,压缩的时候需要占用较多的 CPU 资源。

原文链接:TiDB的tikv节点的压缩算法_tidb 压缩算法-CSDN博客

1 个赞

SELECT
db_name,
table_name,
ROUND(SUM(total_size / cnt), 2) Approximate_Size,
ROUND(SUM(total_size / cnt / (SELECT
ROUND(AVG(value), 2)
FROM
METRICS_SCHEMA.store_size_amplification
WHERE
value > 0)),
2) Disk_Size
FROM
(SELECT
db_name,
table_name,
region_id,
SUM(Approximate_Size) total_size,
COUNT(*) cnt
FROM
information_schema.TIKV_REGION_STATUS
WHERE
db_name = @dbname
AND table_name IN (@table_name)
GROUP BY db_name , table_name , region_id) tabinfo
GROUP BY db_name , table_name;

store_size_amplification 表示集群压缩比的平均值。除了使用 SELECT * FROM METRICS_SCHEMA.store_size_amplification; 语句进行查询以外,你还可以查看 Grafana 监控 PD - statistics balance 面板下各节点的 Size amplification 指标来获取该信息,集群压缩比的平均值即为所有节点的 Size amplification 平均值。
Approximate_Size 表示压缩前表的单副本大小,该值为估算值,并非准确值。
Disk_Size 表示压缩后表的大小,可根据 Approximate_Size 和 store_size_amplification 得出估算值。

因为我的测试环境数据量小,所以还没到压缩的层级?

感觉是没有到达一定的阈值

information_schema.tables中的data_length是根据统计信息得到的吧,想真正测试压缩率,建议搞大点数据,最后看文件系统使用的对比,这样最真实

看了下官方文档,感觉是和数据量太小有关系,
当 level1 的数据量大小达到 max-bytes-for-level-base 限定的值的时候,会触发 level1 的
sst 和 level2 种有 overlap 的 sst 进行 compaction。
黄金定律:max-bytes-for-level-base 的设置的第一参考原则就是保证和 level0 的数据量大致相
等,这样能够减少不必要的 compaction。例如压缩方式为"no:no:lz4:lz4:lz4:lz4:lz4",那么
max-bytes-for-level-base 的值应该是 write-buffer-size 的大小乘以 4,因为 level0 和
level1 都没有压缩,而且 level0 触发 compaction 的条件是 sst 的个数到达 4(默认值)。在 level0 和 level1 都采取了压缩的情况下,就需要分析下 RocksDB 的日志,看一个 memtable 的压 缩成一个 sst 文件的大小大概是多少,例如 32MB,那么 max-bytes-for-level-base 的建议值就应
该是 32MB * 4 = 128MB。
max-bytes-for-level-base = “512MB”

改天把测试环境数据导进来再试试

oltp_read_write里面有delete之类操作,单测insert比较公平,而且要尽量多的行数 :thinking:

我只是prepare数据,还没测试性能

压缩之后1/3,然后三副本差不多大小一样了吧。。。sysbench准备的数据mysql和tidb大小对比是这样的。

查看一下默认的压缩算法和压缩级别