【产品调研】TiFlash 压缩率调研,对 TiFlash 的爱恨情仇都可以在这里说!参与即可获得100积分

亲爱的 TiDB 用户,如果你有在使用 TiFlash,并且觉得还行(或者还可以拯救一下),现在可以来帮助它变得更好啦~

问题背景

我们(TiFlash 的研发)最近在斟酌一个具体的问题:TiFlash 的压缩率是不是不够好。可能有些同学会注意到,同一张表,同步了 TiFlash 副本之后,TiFlash 1 副本的数据量可能会比 TiKV 1 副本的数据量要大。

说好的列存压缩率更高的,怎么比行存还差???

确实是 …… 咱们工作不到位 Orz。这里边其实有两个原因:

  1. TiFlash 的逻辑分裂造成数据空间浪费。

TiFlash 的存储层,会对数据进行物理分片(Segment)存储,Segment 过大之后,需要进行分裂。然后我们在早期的研发过程中,为了减少 Segment 的分裂造成的写放大,所以使用了逻辑分裂。简单来说,它不是真正的分裂,只是分裂出来的新的两个 Segment 分别引用了旧的文件(类似文件系统的 hard link)。这似乎很机智,因为分裂不用做文件重写了。但是带来一个问题:如果后续有只有一个 Segment 更新了它的文件,那么另外一个 Segment 就引用了两份数据,这两份数据其中有一份是无用的。在极端情况下,会有 50% 的数据是无效数据,即空间浪费。

在 6.0 之后,TiFlash 默认不使用逻辑分裂。并且经过各种测试,发现除了写放大系数变高了一点,大概增加了 10% 的 IO 量,其他各项性能指标没有明显变化。反而其中一个 读+写 的场景,读 QPS 有 10% 以上提升。你说气不气?我们研究了一下,读+写 场景的性能提升的主要原因是,减少了无效数据的读取,并且避免了逻辑分裂带来的复杂逻辑。

6.0 的之前版本,可以通过设置以下配置 来禁用逻辑分裂,来达到一样的效果。

[profiles.default].dt_enable_logical_split = false 
  1. TiFlash 使用的压缩算法的压缩率没有 TiKV

TiFlash 默认是用 lz4 -1 压缩算法,而 TiKV 主要使用 zstd -3。虽然对不同数据集有不同的效果,但是后者通常有更好的压缩率,具体可以看这里 https://github.com/facebook/zstd

但是 TiFlash 选择 lz4 也是有苦衷的啊!解压缩效率要够快,查询才能跑的快呀!

asynccode

所以,即使我们已经把逻辑分裂关闭了,在某些场景(比如 ch-benchmark)也还是观察到 TiFlash 副本的数据量比 TiKV 要大。那 TiFlash 如果换成其他的压缩算法,表现会如何呢?来测试一波:

asynccode

聪明的你应该看出来我们的纠结了。 压缩率越高,数据量越小,性能越差 。所以选哪个呢?好吧,咱都要!

从 6.0 开始,TiFlash 会增加以下参数,支持配置不同的压缩算法,目前支持

[profiles.default].dt_compression_method = lz4 #  压缩算法,支持 lz4、lz4hc 和 zstd,
[profiles.default].dt_compression_level = 1 # 压缩等级,需要参考各自压缩算法的等级规则

调研内容

虽然我们可以通过修改配置来自定义压缩算法来适配不同的场景。但是作为一个有追求的数据库,希望能有一个最合适的默认配置。

希望路过的各位,如果咱们 TiDB 集群有开启 TiFlash 副本,帮忙回答几个问题:

  1. 打开 TiDB 的 Grafana 监控,然后选择 PD 监控,Statistics - balance / Size amplification 面板,选择 store number 最小的那个,然后把数据记录下来。比如下面可以获得 tikv_compress_ratio: 3.18。

asynccode

  1. 打开 mysql-client 连接上你的集群,把下面的 SQL 的 chbenchmark 改成 TiFlash 副本的数据量最多的 数据库名 ,然后执行。SQL 只会读取元数据,不会影响线上性能。

SELECT TRUNCATE(sum(tikv_total_size), 0) AS tikv_total_size_MB,
       TRUNCATE(sum(tiflash_size_on_disk) * 1.1, 0) AS tiflash_total_size_on_disk_MB,
       TRUNCATE(sum(tiflash_waste_size_on_disk), 0) AS tiflash_total_waste_size_on_disk_MB,
       TRUNCATE((sum(tikv_total_size)/ sum(tiflash_size_on_disk * 1.1)), 2) AS tiflash_compress_ratio
FROM (WITH TiKV_T AS
        ( SELECT A.TABLE_ID TABLE_ID,
                            A.TABLE_SIZE tikv_total_size,
                                         B.REPLICA_COUNT REPLICA_COUNT
         FROM
           (SELECT *
            FROM information_schema.TABLE_STORAGE_STATS
            WHERE table_schema IN ('chbenchmark')) A
         JOIN
           (SELECT table_id,
                   REPLICA_COUNT
            FROM information_schema.tiflash_replica) B ON A.TABLE_ID = B.TABLE_ID ),
           TiFlash_T AS
        ( SELECT TABLE_ID,
                 ((8192 - avg(AVG_PACK_ROWS_IN_STABLE)) / 8192) * (sum(TOTAL_STABLE_SIZE_ON_DISK) / 1024 / 1024) AS tiflash_waste_size_on_disk ,
                 sum(TOTAL_STABLE_SIZE_ON_DISK) / 1024 / 1024 AS tiflash_size_on_disk
         FROM information_schema.tiflash_tables
         WHERE tidb_database IN ('chbenchmark')
         GROUP BY TABLE_ID )
      SELECT TiKV_T.tikv_total_size AS tikv_total_size,
             TiFlash_T.tiflash_size_on_disk / TiKV_T.REPLICA_COUNT AS tiflash_size_on_disk,
             TiFlash_T.tiflash_waste_size_on_disk / TiKV_T.REPLICA_COUNT AS tiflash_waste_size_on_disk
      FROM TiKV_T
      JOIN TiFlash_T ON TiKV_T.TABLE_ID = TiFlash_T.TABLE_ID) B \G

执行结果长这样:

         tikv_total_size_MB: 252119
   tiflash_total_size_on_disk_MB: 93279
tiflash_total_waste_size_on_disk_MB: 4546
       tiflash_compress_ratio: 2.97
  1. 然后把上面的结果整理一下,并回复本帖子。如果你有多个数据集那就更好了!可以写多几份。示例:
数据库名(选填):chbenchmark
TiDB 版本:5.4.0
运行环境: 本地部署   # 选项:本地部署,阿里云、aws 等)
tikv_total_size_MB: 252119
tiflash_total_size_on_disk_MB: 93279
tiflash_total_waste_size_on_disk_MB: 4546
tiflash_compress_ratio: 2.97
tikv_compress_ratio (从Grafana 获取): 3.18
你希望的 TiFlash 默认压缩算法和等级: zstd --fast=1 # 选项:lz4 -1, zstd --fast=1, zstd -1 或者你建议的其他算法
你最期待 TiFlash 优化的点,或者新功能: xxxx # 来都来了,多提点要求吧……

参与调研回复的内容包含

【TiDB 版本】
【运行环境】本地部署 / 云环境
【tikv_total_size_MB】
【tiflash_total_size_on_disk_MB】
【tiflash_total_waste_size_on_disk_MB】
【tiflash_compress_ratio】
【tikv_compress_ratio (从Grafana 获取)】
【你希望的 TiFlash 默认压缩算法和等级】 zstd --fast=1 # 选项:lz4 -1, zstd --fast=1, zstd -1 或者你建议的其他算法
【你最期待 TiFlash 优化的点或者新功能】

(如果不方便把数据放在帖子里,可以私信我)

参与调研奖励

100 经验值&积分。

感谢支持!

7 个赞

TiDB 版本:5.4.0
运行环境: 本地部署
tikv_total_size_MB:138111
tiflash_total_size_on_disk_MB:5170
tiflash_total_waste_size_on_disk_MB:320.0
tiflash_compress_ratio:26.71
tikv_compress_ratio:15.72
你希望的 TiFlash 默认压缩算法和等级:lz4 -1
你最期待 TiFlash 优化的点,或者新功能:能够可以选择作为独立引擎存在,脱离tikv独立读写

4 个赞

希望尽快解决集群中有多副本tiflash时候,在用br备份进行集群恢复时导致失败的问题ε(*・ω・)_/゚:・☆

4 个赞

迫切需求开源

6 个赞

TiDB 版本:5.4.0
运行环境: 本地部署
tikv_total_size_MB:246000
tiflash_total_size_on_disk_MB:91033
tiflash_total_waste_size_on_disk_MB: 4319
tiflash_compress_ratio: 2.54
tikv_compress_ratio:3.31
你希望的 TiFlash 默认压缩算法和等级:zstd --fast=1
你最期待 TiFlash 优化的点,或者新功能: 不断提高性能吧;多暴露一些参数,让用户自己去选择

3 个赞

TiDB 版本:5.4.0
运行环境: 本地部署
*************************** 1. row ***************************
                 tikv_total_size_MB: 2761002
      tiflash_total_size_on_disk_MB: 381998
tiflash_total_waste_size_on_disk_MB: 81982
             tiflash_compress_ratio: 7.22

tikv_compress_ratio (从Grafana 获取):  1副本:3.47 , 2副本: 3.50
2 个赞

@halleyshx
hi,恢复失败的问题,有相关的帖子吗?求个传送门

1 个赞

哪个状况下的恢复失败,说的我有点蒙

1 个赞

请问AVG_PACK_ROWS_IN_STABLE是啥含义,为什么是8192减去他。
还有sum(tiflash_size_on_disk) * 1.1这里的1.1是怎么得到的。

2 个赞

TiDB 版本:5.3.0
运行环境: 本地部署
tikv_total_size_MB:330894
tiflash_total_size_on_disk_MB:11407
tiflash_total_waste_size_on_disk_MB:2567.0
tiflash_compress_ratio:29.00
tikv_compress_ratio:8.32
你希望的 TiFlash 默认压缩算法和等级:lz4 -1
你最期待 TiFlash 优化的点,或者新功能:能够可以选择作为独立引擎存在,脱离tikv独立读写

3 个赞

Magic!

TiFlash 存储引擎中,按 8192 行数据分块。没有数据浪费的情况下,AVG_PACK_ROWS_IN_STABLE 是接近 8192 的。而如果存在数据浪费,那么 AVG_PACK_ROWS_IN_STABLE 这个值的统计会参数误差,所以我们刚好可以利用这个误差来反向推算出空间浪费率。
1.1 是个估算值。因为 tiflash 目前只统计了 stable 的在磁盘上的数据,而 delta 数据占比不超过 10%,所以就直接用 10% 来算了。:upside_down_face:

4 个赞

剧透一点6.0的进展吧

2 个赞

TiDB 版本:5.4.0
运行环境: 本地部署
tikv_total_size_MB:17044705
tiflash_total_size_on_disk_MB:2150263
tiflash_total_waste_size_on_disk_MB:553621
tiflash_compress_ratio:7.92
你希望的 TiFlash 默认压缩算法和等级:lz4 -1
你最期待 TiFlash 优化的点,或者新功能: 指定列同步至tiflash

3 个赞

@数据小黑
@Myth
@magongyong
@Kongdom
@TiDBer_wTKU9jv6
@LI-ldc
感谢你们参与调研,积分已为你们完成授予!

1 个赞

我在试用tiflash 的时候,我们有每月自动将昂数据分表的操作,此时呢,就需要每月把新的表手动创建一次TiFlash副本,有时候忘了就非常的不方便了,TiFlash是不是可以优化一下这个:smiley:

1 个赞

6.0 和 TiFlash 开源已经很近了,大家可以期待一下~

另外看来大家对独立 TiFlash 存储的呼声也不小,这个我们会慎重评估的哈

TiDB 后续会正式支持分区表(目前还不太完善),是否可以解决“每月分表” 的问题?

正式支持分区表什么意思? 现在不是支持hash range分区吗?另外list分区和分区动态裁剪什么版本能上生产

还有个需求,mpp增加对分区表的支持。

mpp 目前对分区表的支持并不好,后续版本会解决这个问题,“正式支持” 也是这个意思。