小甲师兄
目前涉及OpenStack、Ceph、k8s领域
希望能实现“made in 小甲”的23种设计模式,热爱技术和电影
容量的瓶颈
目前OpenStack后端存储广泛使用Ceph,而且一般使用的都是三副本,以空间换可靠性来保证存储数据的安全,由于数据冗余,真实可用容量最多也只能达到集群的1/3。不仅如此,Ceph集群有一个木桶效应,当某一个OSD容量达到full,会导致整个集群只能读不能写,此时Ceph集群的容量可能只使用了60%,系统已经提示不能再写入数据了。L版之后好像已经把影响范围缩小到pool级别。
小甲说WHY
WHY:
这里我们主要通过实验来验证一下Crush算法数据分布不均衡并做找出原因
那我们就开始分析吧~
实例环境
配置5台Centos物理机,每个host有12个osd,那一共60个osd的集群,副本数为3,创建一个pool池放数据
pg数量
按照官方文档,一个osd上面的pg在100左右,这个pool池中的pg应该设为:
pg_num =60*100/3=2000,由于pg数最好是2的正整数次幂,所以最后
pg_num = 2048。算上副本数,整个Ceph集群pg总数为2048*3=6144
实验结果
我们使用cosbench向这个池中写入1000000个10M的大小的对象
理论结果:
理论上如果Ceph数据均衡:
实验表明:
因为数据是以pg为单位,每个pg数据均衡,osd上pg不均衡导致最后osd数据不均衡
原因分析
通过分析我们可以发现这样一个规律
我们对象是1000000,pg数是2048,相差三个数量级,分布均衡
我们pg三副本后的总数是6144,我们host是5,相差三个数量级,分布均衡
我们假设均衡分布到host上面,那每一个host上面的pg是1228,我们每一个host上面的osd是12,相差两个数量级,分布不均衡
师兄总结:
因为Crush算法中使用哈希函数,哈希函数在较大输入输出范围的时候是均衡的,在较小输入输出范围的时候是不均衡的
Jenkins哈希算法的锅
Crush算法在hash上面普遍使用Jenkins哈希算法,这个哈希算法在较小的输入空间映射到较大的输出空间时,均衡性表现不好,这里所说的较小的输入空间映射到较大的输出空间指的是,我们在对pgid进行hash时。一般一个pool中pgid的范围不是很大,就像上面例子中是2048,而Jenkins算法的输出是一个32位的整数空间,也就是4G,这种pgid映射到4G是不均衡的。
crush中的四种bucketd算法,除了uniform,其他几种都主要考虑时间复杂度和数据迁移,对数据均衡分布没有充分考虑。
本文只是简单的分析一下pg分布不均衡,至于解决办法网上有很多,扩容、线下调权重等等,这里不班门弄斧了。
· END ·