GlusterFS纠删码原理与实践应用

浏览02018-03-05 23:41:00 2757

(作者:陈力@TaoCloud) 

1 前言

分布式文件存储系统通常支持副本(Replication)和纠删码(Erasure Code)两种数据冗余方式,用以满足各种不同场景应用的复杂需求。

副本(Replication)方式一般是将原始数据(或数据块)复制到另一存储区域,当原始数据(或数据块)损坏后数据仍可用并能通过副本数据恢复原始数据(或数据块)。

纠删码(Erasure Code,简称EC)方式一般是根据特定算法,将原始数据(或数据片)进行编码,加入(或生成)校验数据,当有数据片损坏后可以根据现有数据(或数据片)解码出原始文件。

本文介绍了Glusterfs EC纠删码的编码原理及文件分布流程,重点介绍了Glusterfs在实践应用中的volume创建规则及brick的组合方法,旨在使读者对Glusterfs EC纠删码有更深入的认识,有助于实际生产环境中的应用。

2 Glusterfs EC纠删码

Glusterfs早期版本支持使用副本方式来保证数据安全,副本数越多,数据的可靠性就越高。副本方式不涉及编、解码运算,读写效率高。但由于一份数据需要至少大于两倍的空间来存储,磁盘利用率低,硬件成本和运营成本随之增加,存储效率降低。

虽然副本方式存在性能优势,但相比于副本冗余策略,纠删码具有更高的存储效率。

Glusterfs在3.6版本中增加了基于Erasure Code进行数据冗余保护的新类型Dispersed volumes 和Distributed Dispersed volumes,用户可以根据不同的业务需求进行灵活配置。

2.1 EC 纠删码编码原理

Dispersed volumes基于Erasure Code技术,使用RS(Reed-Solomon)码算法对原始数据进行编码,在原始数据中加入redundancy,之后将编码文件分片存储到volume中的相应bricks中。

RS(Reed-Solomon)码有两个参数n和m,记为RS(n,m),n代表原始数据块个数,m代表校验块个数。RS编码以word为编码和解码单位,大的数据块拆分成固定字长(一般为8位或16位)的word进行编码。

如图1所示,左边是编码矩阵,矩阵的上部是单位阵(n行n列),下部是vandermonde(范德蒙德)矩阵(m行n列)。

输入数据向量D=(D1,D2,...Dn)和编码矩阵相乘,得到编码后数据向量(D1,D2,...Dn,C1,C2,..Cm),其中变量Ci,Di均代表一个word。

1.png

图1

 

对于Distributed Dispersed volumes,将有多个bricks集合(即subvolumes)来存储数据,相对于Dispersed volumes,其编码原理相同。

2.2 EC 纠删码的文件分布流程

Glusterfs文件系统模块化的通过各种Translator(一种强大的文件系统扩展机制)链接起来实现各种功能,各Translator在需要运行时通过动态库的方式加载。其中Cluster translator 是Glusterfs实现存储功能的核心,实现了DHT、AFR、EC等重要功能。

图2示例中给出了Type为n*(2+1)的Distributed Dispersed volumes,其中n为subvolumes个数,即n个Dispersed Set,用于确定文件的分布位置,(2+1)表示最终的纠删卷编码方式。


2.png

图2

注:示例中通过posix接口挂载ec纠删卷,展示EC纠删码的文件分布流程,其他 nfs、cifs挂载方式的文件分布流程类似。

1)Client端的各种数据请求、交互均经过mount translator的fuse功能层进行传输;

2)Client端数据到达Cluster translator后,此translator的DHT功能层通过已知的文件路径和文件名计算出文件的最终落点(落到哪个subvolumes);

3)之后Cluster translator 的EC功能层对接收到的数据使用RS码进行编码;

4)编码完成后,按照Volume Type将编码文件分成3份存储到对应subvolumes的每个brick中。

 

存储在每个brick上面的分片文件的文件名和原始文件的文件名一致,所有分片文件的总大小等于原始文件编码后的大小。

如图3,原始文件dd10GB大小为10GB,按照Type为n*(2+1)的方式存储,经过编码后的编码文件大小为15GB,之后分片存储到了三个brick当中,分片文件的文件名和原始文件名均为dd10GB,分片文件大小总和为15GB,等于编码文件大小。

3.png

图3

3 EC 纠删码卷的应用

在创建Dispersed volume时有一个 redundancy值需要被定义,这个值决定了volume的可用空间,同时也决定了多少bricks失联而不影响volume的正常使用。

3.1 卷的可用空间

通过配置redundancy值来提高数据可靠性,在保证数据安全的的同时,提升物理存储介质的空间利用率。

<Usable size> = <Brick size> * (#Bricks - Redundancy)

其中,#Bricks表示每个Dispersed Set中的brick总数,例如:

1)3 bricks,创建Dispersed Type为1*(2+1),存储磁盘空间利用率66.7%;

2)10bricks,创建Dispersed Type为2*(4+1)的卷,存储磁盘空间利用率为80%。

3.2 redundancy规则

在创建Dispersed volume时,如若redundancy值设置为0,则Dispersed volume等同于分布式卷,若redundancy设置为#Bricks/2,则Dispersed volume等同于复制卷,因此,在创建Dispersed volume时,redundancy值的设定应遵循以下公式:

 

0< redundancy<#Bricks /2

3.3 EC 纠删码卷的创建

3.3.1 Dispersed volume创建简介

Dispersed volume可以通过gluster volume create命令进行创建,详细的命令如图4所示:

4.png

图4

volume创建命令参数:

disperse:每个Dispersed Set的bricks总数,如若未指定,则volume创建命令中列出的所有bricks同属于一个Dispersed Set;

    redundancy:为冗余度,决定多少brick可以interrupting,并且也决定卷的可用空间,当redundancy未指定时,默认为1;

    glusterfs volume创建命令中存在disperse-data参数,为卷的创建提供了更加灵活的方式,与前两者关系为:

disperse-data =disperse - redundancy

 

如图5所示,disperse设置为3,redundancy未指定,缺省为1,最终的使用6个brciks创建的dispersed volume type为3*(2+1)

5.png

图5

 

3.3.2 创建性能更佳的卷

在进行Dispersed volume创建时,如图6所示,glusterfs源代码中cli-cmd-parser.c文件内的cli_cmd_create_disperse_check函数会对disperse-data的值进行判断,判断disperse-data的值是否为2的次幂。

6.png

图6

通常3、5、6等非2的次幂都是不推荐的,使用gluster volume create命令创建卷时,如图7示例,当disperse-data的值为5的时,会有非最优配置的提示:

7.png

图7

 

    Glusterfs EC纠删码在编码时引入stripe(stripe = 512*(#bricks-redundancy)bytes)的概念,EC纠删码每次按照一个整条带大小进行编码,如果接收的数据少于一个条带大小则填充0到满足一个条带大小再编码,追加写时需要读取上次填充有0的条带,合并他们,并重新计算编码块,再写最终的结果,因此,当Dispersed volume配置不合理时,存在RMW(Read-Modify-Write)操作。

    RMW操作的出现,引起了无用的读写操作,增加了有效写延时,从而导致性能的降低。因此在配置Dispersed volume的时候应该注意到此问题。

如图8所示, Type为 1*(2+1)的Dispersed Volume,stripe大小为512*(3-1)=1KB, 图示文件A的一次写IO块大小为4096bytes,每次IO块写入时整条带编码、写入,fileA的一次写IO块分4次写入,均未出现RMW。

 

8.png

图8

 

如图9所示, Type为 1*(3+1)的Dispersed Volume,条带大小为512*(4-1)=1.5KB,图示文件 A的一次写IO块大小为文件4096bytes,编码后写入磁盘,其中stripe1和stripe2满条带写入,stripe3则填充了0.5KB的0值,文件A的下一次写IO块写入时需要先读出stripe3合并到此次写操作当中,如此重复,除了第一次写IO,往后的每次写IO均会出现RMW操作,多次触发“写惩罚”,影响性能。

 9.png

图9

 

3.3.3 测试验证

为了验证上节理论的合理性,使用4台存储节点,每台3块硬盘,分别配置4*(2+1)和3*(3+1)两种类型的Distributed Dispersed volumes,进行性能测试对比。

测试工具采用业界通用的文件系统benchmark工具iozone,测试命令如下:

9-1.png

其中IO块大小为4KB,测试数据大于后端存储节点物理内存两倍。

iozone测试结果:

9-2.png

通过测试,使用4KB块IO进行读写,相同配置下,Type为(2+1)的volume写性能高于Type为(3+1)的volume,验证了disperse-data的推荐为2的次幂的正确性。

通常,应用程序的IO块大小为2的幂次,如4k、64k、1M等,建议在进行volume 创建时,disperse-data值的配置为2的次幂,与业务的IO块大小相匹配,避免RMW操作的出现,从而提升存储系统性能。

3.4 EC卷brick的容错

Glusterfs文件系统所有节点完全对等、高效容错,通过配置副本或纠删码不同的冗余方式,即使多块硬盘或整个存储节点出现故障,数据仍可安全访问而不受影响。

Glusterfs EC卷支持多种高可用配置方法,可以根据磁盘和存储节点不同的保护需求,合理搭配出支持不同故障域的组合配置。

以下根据各种诸多内部测试,客户方案实施方案,对基本的Glusterfs EC卷的各种搭配组合、故障允许情况进行详细说明。

3.4.1 纠删码冗余

Glusterfs高可用冗余策略可根据公式M+N:B进行灵活配置,其中M代表可用硬盘数量,N代表故障硬盘数量,B代表故障节点数量,根据每台存储节点上硬盘分布数量的不同,允许的硬盘和存储节点损坏的数量也不同。

如图10所示,列出了常用基本的EC纠删码卷的高可用配置方式及相关允许的故障情况:

10.png

图10

注:硬盘对应glusterfs中的一个brick,节点指存储节点


1)如图11示例,Type为2+1、4+1,8+1的Dispersed volume,允许损坏一块硬盘而不影响数据安全。

由于每块硬盘分布于不同的存储节点,因此最多也允许仅1台存储节点损坏。

11.png

图11

 

2)如图12示,Type为4+2的Dispersed volume,允许同时损坏两块硬盘而不影响数据安全。

当6块硬盘分布于不同存储节点,匹配冗余模式4+2:2,为保证数据安全,最多允许损坏两台存储节点;

当6块硬盘分布于3台存储节点,每台存储节点上面两块硬盘,匹配冗余模式4+2:1,则允许最多损坏1台存储节点。

12.png

图12

 

3)如图13示,Type为为8+2的Dispersed volume ,允许同时损坏两块硬盘而不影响数据安全。

当10块硬盘分布于不同存储节点,匹配冗余模式8+2:2,为保证数据安全,则最多允许损坏两台存储节点;

当10块硬盘分布于5台存储节点,每台存储节点上面两块硬盘,匹配冗余模式8+2:1,则允许最多损坏1台存储节点。

13.png

图13

 

4)如图14示,Type为为8+4的Dispersed volume ,允许最多损坏4块硬盘而不影响数据安全。

当12块硬盘分布于不同存储节点,匹配冗余模式8+4:4,则最多允许损坏4台存储节点;

当12块硬盘分布于6台存储节点,每台存储节点上面两块硬盘,匹配冗余模式8+4:2,则允许最多损坏2台存储节点;

当12块硬盘分布于3台存储节点,每台存储节点上面4块硬盘,匹配冗余模式8+4:1,则允许最多损坏1台存储节点。

 

14.png

图14


3.4.2 空间利用率

Glusterfs EC卷提供了多种灵活的配置方式,在提升存储有效使用空间的同时,支持不同级别的冗余策略,保证数据的安全可用。

如图15示,在保证数据安全的前提下,不同的M+N:B组合配置,需要的存储节点最小数量和存储磁盘的空间利用率各不相同:

15.png

图15

注:存储节点最小数量可以简单通过公式[(M+N)/(N/B)]计算;空间利用率可以通过公式M/(M+N)计算。

 

通常较高级别的保护策略相比低级别的保护策略通常需要消耗更多的磁盘空间,在实际生产当中,需要根据业务需求和硬件情况综合考虑,通过设置合理的冗余模式来平衡存储空间和保护需求。

3.4.3 应用实践

以上是对基本Glusterfs EC纠删码卷的创建配置进行阐述,往往实际生产环境中的环境更为复杂。

以公司已有某客户生产环境为例,实际配置12台存储节点,每台存储节点20块6TB sata盘,要求采用最强容错机制,并满足以下指标:

1)容许同时发生故障硬盘数不低于2块,且位于不同存储节点;

2)容许同时发生故障的存储节点数不低于2台;

3)整套存储系统的可用空间不少于1PB。

 

由于客户采购的12台存储节点均配置raid卡(不支持no-raid功能),因此综合数据安全、存储可用空间、方案可行性等诸多因素,最终确定:

1)每台存储节点20块6TB sata盘做一组raid5,划分5个LUN,每个LUN容量大小为22.8TB;

2)存储节点的每个LUN对应glusterfs一个brick,总共60个brick,创建Type为6*(8+2)的 Distributed Dispersed volumes,提供用户最终使用的卷的可用容量为1094TB(22.8TB*60*(8/10)),大于项目指标指定的1PB。

最终的实施方案如图16所示,使用6种不同颜色标识出最终创建的volume 的6个subvolumes在12台存储节点上的分布位置,当任意2块硬盘或2台存储节点损坏,均不会影响到存储的正常使用,满足项目数据安全的指标。

16.png

图16

 

参考文献

1. http://docs.gluster.org/en/latest/

2. Red_Hat_Storage-3.1-Administration_Guide-en-US.pdf

3.黄健忠,曹强等.纠删码存储集群系统设计与优化.科学出版社.2016.1

4.TaoCloud,GlusterFS企业级功能之EC纠删码

5.刘爱贵. XDFS EC 常用模式


发表评论

全部评论(0)