ceph存储池
存储池是由一个一个OSD组成的 将对象数据存放在OSD中
纠删码存储池
将数据对象划分为K个数据块、M个编码块 然后再存放在OSD存储池
纠删编码函数将对象内容划分为3个数据块和2个编码块 然后将这些数据块分别存储在不同的OSD上 假设数据块1 ABC存放在OSD5上 数据块2 DEF存放在OSD2上 数据块3 GHI存放在OSD1上 编码块1 YXY存放在OSD3上 编码块2 GQC存放在OSD4上
读取对象
从纠删码存储池读取NAYN对象
正常情况下 读取数据块1和2和3就可以得到该对象的完整内容 如果数据2所在的OSD2是最慢的 那么这一部分数据就没有读到 只读取数据块1和3 那么缺失的数据块2的数据通过编码块来恢复 如果编码块5所在OSD4出局了 那么就可以通过编码块4和数据看1和3解码得到数据块2 进而得到完整的对象数据
谁来做编解码的动作?
a、主OSD对对象内容做编码操作然后将分片数据发送到对应的OSD b、也做解码操作将数据分片从各个OSD获取整合得到完整对象 c、主OSD也记录着归置组的日志
假设一个对象已被存储进了存储池
D1v1表示对象版本1的数据块1 写入了OSD1 D2v1表示对象版本1的数据块2 写入了OSD2 C1v1表示对象版本1的编码块1 写入了OSD3 各OSF归置组日志都相同 1,1表示版本1 epoch为1
此时写入该对象的版本2
WriteFull 完全取代 非部门覆盖
最新的日志版本为2
上面是正常情况 再考虑下意外情况
OSD1挂了 OSD2写了一部分还没有写完 OSD3写了一块 即丢失了两块:D1v2 和 D2v2
1、在K=2,M=1的情况下 至少需要1个数据块和一个编码块才能恢复对象完整数据 2、OSD4成为主的OSD 它发现该对象版本1的数据是可用的 那么它就会认为版本1是最新的数据 3、OSD3发现它于主OSD的日志版本有分歧 它将会忽略且包含的C1v2块的文件也被删除 4、D1v1块的数据将在数据清洗期间通过解码函数重建 并存储在OSD4上