如何计算和优化追加写引擎中GC的写放大

名词解释

  • append写
    一种基于journal的顺序追加写的数据记录方式,类似ZFS的ZIL,ext4的journal.

  • GC
    garbage colletion 是指在append写过程中对覆盖写产生的垃圾数据的回收过程。

GC过程中写放大的计算

不同层次的写放大

  • journal级别
    统计前端用户有效数据的写入量total_user_io,和包含了这部分数据且对接了分布式一致性协议、支持索引而设计的journal 的写入总量total_journal_io,计算 total_journal_io/total_user_io 。这里主要的开销是封装用户IO,把它组织成相应日志而添加的journal 头尾的开销。

  • 存储引擎级别

统计前端用户有效数据的写入量total_user_io,和经过存储引擎对外写入的总量total_engine_io,计算 total_enigne_io/total_user_io 。这里主要的开销包括:

  1. 存储引擎GC的开销;
  2. 索引数据落盘的开销;
  • 磁盘级别
    统计前端用户有效数据的写入量total_user_io,和为了记录这些数据,host端发往磁盘的写请求的总量total_host_io,计算 total_host_io/total_user_io。total_host_io可以通过ioutil工具或/proc/diskstat文件获取。在分布式场景下,这里主要的开销除了上面的开销之外还包括:

    1. 基于分布式一致性协议,所有索引信息定期落盘的开销;
    2. 记录逻辑卷和复制组映射关系的元数据落盘的开销;
  • SSD级别
    统计前端用户有效数据的写入量total_user_io,和SSD内部发往NAND的吸入总量total_nand_io,计算 total_nand_io/total_user_io 。这里主要的开销除了上面的开销之外,还包括 SSD 内部写放大的开销。后者可以通过nvmecli或者其原生库统计到。

GC设计的考虑因素

GC的优化点主要目的就是提供给用户尽可能多的有效IO,同时降低IO延迟。上面各个层次的写放大统计值是衡量存储引擎设计的一个重要指标。实际GC的设计需要考虑当前可用容量大小、数据碎片化程度、SSD磨损程度静态因素,还需要兼顾用户IO模式、SSD内部任务调度等动态因素。下面假设其他调节不变的情况下,逐一考虑每个影响因素。

当前可用容量

在大规模分布式系统中,可用容量在不同的层次有不同的设计考量。

  • 集群级别
    如果集群整体可用容量充足可以减缓GC;反之尽快GC。针对个别节点可用空间不足,这些节点应该尽快通过节点间的容量均衡去释放空间,而不应该加速GC。因为在空间不足的情况下,做GC的写放大相当大。

  • 主机/磁盘级别
    同样,如果容量充足可以在GC过程中高优做碎片整理,反之GC应该尽快释放空间。

数据碎片化程度

基于索引可以统计出磁盘内所有区间的数据碎片化程度。越零碎的区域越应该在GC过程中先做碎片整理。

用户IO模式

用户的覆盖写越多,越应该避免GC过程中搬数据,而应该让用户的覆盖写自己无效掉之前的数据,然后删去。

用户的随机写越多,越应该做碎片整理。

在可用容量充足的情况下:当前用户的请求越多,越应该避免GC,把带宽让给用户;反之,可用积极GC,错峰利用磁盘带宽。

SSD磨损程度

极端情况下,如果SSD磨损得很厉害了,尽量避免搬数据;反之,可以根据需要做GC。

SSD内部任务调度

因为SSD内部总的可用带宽是一定的,因此GC可以尽量避开SSD内部周期任务执行的时机。

GC的优化方法

这个在其本人的其他博客有讨论,参考:http://xiaqichao.cn/wordpress/?p=172
这里简单归纳几点。

GC通常基于切片去做,通常需要考虑选取哪些切片做GC,以及如何做GC。

选取策略

可以考虑下面几个因素综合考虑哪些切片需要做GC:

  • 切片内有效数据的比例

  • 切片内数据的新旧程度

  • 切片内数据做过GC的历史(次数)

  • 切片内数据的碎片化程度
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章