名词解释
-
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 。这里主要的开销包括:
- 存储引擎GC的开销;
- 索引数据落盘的开销;
- 磁盘级别
统计前端用户有效数据的写入量total_user_io,和为了记录这些数据,host端发往磁盘的写请求的总量total_host_io,计算 total_host_io/total_user_io。total_host_io可以通过ioutil工具或/proc/diskstat文件获取。在分布式场景下,这里主要的开销除了上面的开销之外还包括:- 基于分布式一致性协议,所有索引信息定期落盘的开销;
- 记录逻辑卷和复制组映射关系的元数据落盘的开销;
- 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的历史(次数)
- 切片内数据的碎片化程度
原文地址:https://blog.51cto.com/xiamachao/2484873