Ceph中EC的对齐
ErasureCode应用在存储中的是满足MDS性质的线性分组码,最常用的是Reed Solomon编码。 将一份数据切成K块数据块,然后编码成M块校验块,放到K+M个OSD上,可以容忍任意M块丢失。
Ceph的EC支持主要是Loïc Dachary实现的。具体的PG层逻辑,复用了ReplicatedPG,写数据前的准备工作,都是在主OSD完成。
编码的工作由对应的plugin完成,可以很灵活的实现自己的编码。Plugin的选用是在创建ecpool时的ecprofile中指定的,具体的设置可以参考官网。
已有的Plugin是Jerasure,Intel ISA,LRC,SHEL,前两者是采用硬件加速的编码库,后两者是基于RS改进的编码方案,主要改进了修复的效率和占用的资源。
目前Ceph不支持EC的偏移写,只能writefull,或者offset要满足是strip_width的倍数,且正好是原始对象的末尾,所以最终都会转换成一个AppendOp。
编码的流程
1 | // ECTransaction::TransGenerator |
其中,chunk_size也是每个osd上要存的数据量,就是一次要对齐的大小,再来看chunk_size是怎么来的。
ECBackend中有这样一个变量,ECUtil::stripe_info_t sinfo,sinfo包含变量stripe_width。
sinfo是在ECBackend构造的时候实例化的。
实例化过程
OSDMonitor::prepare_new_pool -> prepare_pool_stripe_width
1 | ErasureCodeInterfaceRef erasure_code; |
不同的ECPlugin会有不同的条带大小,下面主要分析下Jerasure为例。get_chunk_size的对齐过程
调用
alignment = get_alignment()返回ECPlugin实现的编码本身需要的对齐长度,就是一次矩阵运算需要的byte数然后根据对齐长度,使object_size满足为alignment的整数倍
如果per_chunk_alignment为true,会使每个chunk大小都是alignment的整数倍。默认false
详细代码
1 | ErasureCodeJerasure::get_chunk_size(int object_size) |
总结,不同的编码本身会有不同的编码要求,跟踪get_chunk_size和get_alignment函数可以得到,了解对齐原理后合理设置参数,才能使编码性能提高。
每次编码都会prepare逻辑,object_size过小,会频繁prepare,导致性能下降。