温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。
Fayson的github:
https://github.com/fayson/cdhproject
提示:代码块部分可以左右滑动查看噢
1.文档编写目的
Fayson在前面的文章中介绍过《什么是HDFS的纠删码》,当时详细介绍了什么是纠删码,纠删码的实现原理,以及一些Benchmark的结果比较。
纠删码是CDH6/Hadoop3新加入的功能,之前的HDFS都是采用副本方式容错,默认情况下,一个文件有3个副本,可以容忍任意2个副本(DataNode)不可用,这样提高了数据的可用性,但也带来了2倍的冗余开销。例如3TB的空间,只能存储1TB的有效数据。而纠删码则可以在同等可用性的情况下,节省更多的空间,以rs-6-3-1024K这种纠删码策略为例子,6份原始数据,编码后生成3份校验数据,一共9份数据,只要最终有6份数据存在,就可以得到原始数据,它可以容忍任意3份数据不可用,而冗余的空间只有原始空间的0.5倍,只有副本方式的1/4,因此,可以大大节约成本。本文Fayson主要是介绍如何在CDH6.0中使用纠删码。
- 内容概述
1.通过CM启用纠删码
2.纠删码策略介绍
3.纠删码基本操作
4.纠删码实操
5.总结
- 测试版本
1.CM和CDH版本为6.0
2.Redhat7.4
3.集群已启用Kerberos
2.通过CM启用纠删码
1.通过Cloudera Manager搜索HDFS服务“erasure”,勾选“cloudera.erasure_coding.enabled”配置项,保存后退出需要重启HDFS服务,重启过程略。
2.如果不在Cloudera Manager中设置该选项,在后台使用命令行在启用纠删码的某一个策略时,会报错,如下所示。
[root@ip-172-31-6-83 311-hdfs-NAMENODE]# hdfs ec -enablePolicy -policy XOR-2-1-1024k
RemoteException: enableErasureCodingPolicy is not allowed because cloudera.erasure_coding.enabled=false
(可左右滑动)
3.这里顺便解释一下Cloudera Manager中关于纠删码的几个参数。
CM中参数名:DataNode Striped Read Timeout
参数:dfs.datanode.ec.reconstruction.stripedread.timeout.millis
描述:DataNode的条带读取超时,默认是5000ms。即如果超过5s没从DataNode上读取到条带数据,则会在DataNode上启动后端的重建数据的线程。
CM中参数名:DataNode Striped Read Threads
参数:dfs.datanode.ec.reconstruction.threads
描述:在后台重建数据工作期间DataNode用于读取条带块的线程数。
CM中参数名:Erasure Coding Reconstruction Weight
参数:dfs.datanode.ec.reconstruction.xmits.weight
描述:EC后台恢复任务使用的资源的相对权重,EC模式下恢复数据需要读取多个块,比如在RS-6-3-1024k的情况下为6,而如果是以前的副本复制方式只需要读取单个副本即可。这个权重值越高,可以同时运行的重建任务越少。需要读取以完成恢复的块乘以该权重以确定恢复任务的总权重。这些权重会计入dfs.namenode.replication.max-streams参数所设置的限制。
CM中参数名:Default Policy when Setting Erasure Coding
参数:dfs.namenode.ec.system.default.policy
描述:默认的纠删码编码策略,这里可以看到是RS-6-3-1024k。在后台依旧还是可以单独对目录进行设置。
CM中参数名:Erasure Coding Enabled
参数:cloudera.erasure_coding.enabled
描述:是否启用纠删码,默认为关闭状态,如果要使用纠删码功能,需要勾选。
3.纠删码策略介绍
首先我们查看一下系统中具体支持的纠删码策略类型。
[root@ip-172-31-6-83 ~]# hdfs ec -listPolicies
Erasure Coding Policies:
ErasureCodingPolicy=[Name=RS-10-4-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=10, numParityUnits=4]], CellSize=1048576, Id=5], State=DISABLED
ErasureCodingPolicy=[Name=RS-3-2-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=3, numParityUnits=2]], CellSize=1048576, Id=2], State=DISABLED
ErasureCodingPolicy=[Name=RS-6-3-1024k, Schema=[ECSchema=[Codec=rs, numDataUnits=6, numParityUnits=3]], CellSize=1048576, Id=1], State=ENABLED
ErasureCodingPolicy=[Name=RS-LEGACY-6-3-1024k, Schema=[ECSchema=[Codec=rs-legacy, numDataUnits=6, numParityUnits=3]], CellSize=1048576, Id=3], State=DISABLED
ErasureCodingPolicy=[Name=XOR-2-1-1024k, Schema=[ECSchema=[Codec=xor, numDataUnits=2, numParityUnits=1]], CellSize=1048576, Id=4], State=ENABLED
(可左右滑动)
可以看到一共有5种纠删码策略,这里具体解释一下:
1.RS-10-4-1024k:使用RS编码,每10个数据单元(cell),生成4个校验单元,共14个单元,也就是说:这14个单元中,只要有任意的10个单元存在(不管是数据单元还是校验单元,只要总数=10),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576B。
2.RS-3-2-1024k:使用RS编码,每3个数据单元,生成2个校验单元,共5个单元,也就是说:这5个单元中,只要有任意的3个单元存在(不管是数据单元还是校验单元,只要总数=3),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576B。
3.RS-6-3-1024k:使用RS编码,每6个数据单元,生成3个校验单元,共9个单元,也就是说:这9个单元中,只要有任意的6个单元存在(不管是数据单元还是校验单元,只要总数=6),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576B。
4.RS-LEGACY-6-3-1024k:策略和上面的RS-6-3-1024k一样,只是编码的算法用的是rs-legacy,应该是之前遗留的rs算法。
5.XOR-2-1-1024k:使用XOR编码(速度比RS编码快),每2个数据单元,生成1个校验单元,共3个单元,也就是说:这3个单元中,只要有任意的2个单元存在(不管是数据单元还是校验单元,只要总数=2),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576B。
以RS-6-3-1024k为例,6个数据单元+3个校验单元,可以容忍任意的3个单元丢失,冗余的数据是50%。而采用副本方式,3个副本,冗余200%,却还不能容忍任意的3个单元丢失。因此,RS编码在相同冗余度的情况下,会大大提升数据的可用性,而在相同可用性的情况下,会大大节省冗余空间。
4.纠删码基础操作
纠删码策略是与具体的路径(path)相关联的。也就是说,如果我们要使用纠删码,则要给一个具体的路径设置纠删码策略,后续,所有往此目录下存储的文件,都会执行此策略。
1.首先我们在HDFS中建立一个目录。
[root@ip-172-31-6-83 ~]# hadoop fs -mkdir /ec_xor
(可左右滑动)
2.使用命令获取该目录的纠删码策略,提示未指定,说明新建目录不会被默认增加纠删码策略属性。
[root@ip-172-31-6-83 ~]# hdfs ec -getPolicy -path /ec_xor
The erasure coding policy of /ec_xor is unspecified
[root@ip-172-31-6-83 ~]#
(可左右滑动)
3.我们先启用XOR-2-1-1024k策略。
[root@ip-172-31-6-83 ~]# hdfs ec -enablePolicy -policy XOR-2-1-1024k
Erasure coding policy XOR-2-1-1024k is enabled
[root@ip-172-31-6-83 ~]#
(可左右滑动)
注意Fayson集群启用了Kerberos,要先使用hdfs的keytab登录,否则会报没权限。如下所示:
[root@ip-172-31-6-83 ~]# hdfs ec -enablePolicy -policy XOR-2-1-1024k
AccessControlException: Access denied for user fayson. Superuser privilege is required
[root@ip-172-31-6-83 ~]# kinit -kt hdfs.keytab hdfs/ip-172-31-6-83.ap-southeast-1.compute.internal@FAYSON.COM
(可左右滑动)
4.给目录设置纠删码策略
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor -policy XOR-2-1-1024k
Set erasure coding policy XOR-2-1-1024k on /ec_xor
[root@ip-172-31-6-83 ~]# hdfs ec -getPolicy -path /ec_xor
XOR-2-1-1024k
(可左右滑动)
5.这里再测试一下给目录设置另外一些没启用的纠删码策略
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor -policy RS-10-4-1024k
RemoteException: Policy 'RS-10-4-1024k' does not match any enabled erasure coding policies: [XOR-2-1-1024k]. An erasure coding policy can be enabled by enableErasureCodingPolicy API.
[root@ip-172-31-6-83 ~]#
(可左右滑动)
报错,说明在使用某个纠删码策略是,需要先启用。
6.我们启用策略RS-6-3-1024k,然后再给/ec_xor目录set策略。同时往这个目录写入数据。
[root@ip-172-31-6-83 ~]# hdfs ec -enablePolicy -policy RS-6-3-1024k
Erasure coding policy RS-6-3-1024k is enabled
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor -policy RS-6-3-1024k
Set erasure coding policy RS-6-3-1024k on /ec_xor
[root@ip-172-31-6-83 ~]# hadoop fs -put ec_test.txt /ec_xor
put: File /ec_xor/ec_test.txt._COPYING_ could only be written to 3 of the 6 required nodes for RS-6-3-1024k. There are 3 datanode(s) running and no node(s) are excluded in this operation.
(可左右滑动)
发现启用纠删码策略,设置目录策略都可以成功,但是在往目录丢数据的时候会报错,这是因为RS(6,3)策略需要6份原始数据,3份校验校验,至少需要9台DataNode,但是Fayson的环境比较屌丝总共4个节点,只有3个数据节点。所以接下来的章节,Fayson会基于XOR-2-1-1024k策略来进行实操,因为XOR(2,1)只需要2份原始数据,1份校验数据,3台DataNode可以进行操作。
5.纠删码实操
1.在HDFS中建立以下三个目录,并都设置为XOR-2-1-1024k策略。
[root@ip-172-31-6-83 ~]# hadoop fs -mkdir /ec_xor_s
[root@ip-172-31-6-83 ~]# hadoop fs -mkdir /ec_xor_m
[root@ip-172-31-6-83 ~]# hadoop fs -mkdir /ec_xor_l
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor_s -policy XOR-2-1-1024k
Set erasure coding policy XOR-2-1-1024k on /ec_xor_s
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor_m -policy XOR-2-1-1024k
Set erasure coding policy XOR-2-1-1024k on /ec_xor_m
[root@ip-172-31-6-83 ~]# hdfs ec -setPolicy -path /ec_xor_l -policy XOR-2-1-1024k
Set erasure coding policy XOR-2-1-1024k on /ec_xor_l
[root@ip-172-31-6-83 ~]#
(可左右滑动)
2.准备3个数据文件,一个小于cell的默认大小1024k,一个大于1024k但是小于2048k,一个是1个GB多的超大文件,并分别put到上一步准备好的3个目录。
3.查看/ec_xor_s编码后block的分布
[root@ip-172-31-6-83 generatedata]# hdfs fsck /ec_xor_s -files -blocks -locations
(可左右滑动)
通过该命令查看block的文件信息。在EC中这里列出来的每一条block信息,与之前三副本的方式有一点区别,这里是指一个block group。
- 首先只有一个block group,因为该测试文件只有49.7K,远远小于HDFS的block size,已经没办法再被拆分。
- Live_repl=2,表明此数据块有2个副本,一个是原始数据,一个是校验数据,这里我们选择的纠删码策略是XOR(2,1),按道理应该是2个数据块,但是因为原始数据只有太小只有49.7K,小于纠删码策略的cell默认大小1024k,所以没办法再被拆分,只有一个cell。
- 我们通过Live_repl的block ID也可以在DataNode上找到这2个副本进行确认。根据之前fsck打印出来的信息其实也可以知道blk_-9223372036854775680在DataNode(172.31.12.142)上,blk_-9223372036854775678在DataNode(172.31.4.105)上。
- 接下来我们在这2台DataNode上分别查看这2个block
注意到2台DataNode上存储的block数据包括内容和大小其实是一样,其中一个是数据块,一个是校验块。即当原始数据文件太小,无法拆分再被cell的1MB拆分的时候,类似XOR(2,1)策略的一个数据块一个校验块其实就是类似副本的方式。
4.查看/ec_xor_m编码后block的分布
[root@ip-172-31-6-83 shell]# hdfs fsck /ec_xor_m -files -blocks -locations
(可左右滑动)
- 首先只有一个block group,因为该测试文件只有1.2MB,远远小于HDFS的block size,已经没办法再被拆分。
- Live_repl=3,表明此数据块有3个副本,2个是原始数据,1个是校验数据,这里我们选择的纠删码策略是XOR(2,1),与策略一致。注意这里与上面那个49K文件的测试不一样的地方,因为这次的文件大于一个cell大小1MB,却又小于2个cell的大小2MB,刚好原始数据可以被拆分为2个cell也即2个原始数据块。
- 我们通过Live_repl的block ID也可以在DataNode上找到这3个副本进行确认。根据之前fsck打印出来的信息其实也可以知道blk_-9223372036854775664在DataNode(172.31.4.105)上,blk_-9223372036854775663在DataNode(172.31.12.142)上,blk_-9223372036854775662在DataNode(172.31.9.113)。
- 分别在3台DataNode上查看这3个block文件。
说明原始文件被拆分成2个cell分别保存在172.31.4.105和172.31.12.142,而172.31.9.113上保存的是校验数据块,直接用命令查看为乱码。
5.查看/ec_xor_l编码后block的分布
[root@ip-172-31-6-83 shell]# hdfs fsck /ec_xor_l -files -blocks -locations
(可左右滑动)
- 首先只有5个block group,因为该测试文件只有约1.2GB,每个block group保存2份原始数据,按默认的block size为128MB,计算2个数据文件为256MB,所以一共5个block group,最后一个block group不够256MB。
- Live_repl=3,表明此数据块有3个副本,2个是原始数据,1个是校验数据,这里我们选择的纠删码策略是XOR(2,1),与策略一致。只是这里原始文件大很多,每个副本为128MB,包含128个1MB的cell。
- 以第一个block group为例,我们来具体看看每个block的情况。blk_-9223372036854775648在172.31.12.142上,blk_-9223372036854775647在172.31.4.105上,blk_-9223372036854775646在172.31.9.113上。
- 分别在3台DataNode上查看这3个block文件。
说明每个block group里的保存2份原始数据,这2份原始数据均为HDFS的默认block size大小128MB,分别保存在172.31.4.105和172.31.12.142,而172.31.9.113上保存的是校验数据块,也为128MB,直接用命令查看为乱码。
6.总结
1.CDH6中默认没有开启纠删码,需要在Cloudera Manager中进行设置,启用后需要重启HDFS服务。
2.目前默认的纠删码策略一共有5种,包括RS-10-4-1024k,RS-3-2-1024k,RS-6-3-1024k,RS-LEGACY-6-3-1024k和XOR-2-1-1024k。
3.默认纠删码策略都是disable状态,需要使用hdfs用户才能启用这些策略,否则会报权限不足。启用后的纠删码策略,你才能设置给某个目录,否则会报错无法为目录设置该纠删码策略。
4.纠删码是以目录为单位的,一旦某个纠删码策略被启用后,你就可以为某个目录设置策略,为目录设置策略不需要高级用户,普通用户即可。一旦目录设置了某个策略,写入该目录的文件都会被编码拆分为原始数据块,以及校验数据块。
5.纠删码策略对DataNode的数量有要求,比如RS-6-3-1024k即RS(6,3),需要6个数据块,3个校验块,你至少需要9台DataNode,因为Fayson的环境只有3台DataNode,所以本文使用的策略是XOR-2-1-1024k。
6.使用纠删码后保存的文件,跟之前三副本的方式有区别,会以block group组为单位,每个block group里都会保存原始数据块和校验数据块(具体比例取决于你选择的纠删码策略),group中的数据块才是真正以前的HDFS block。
7.校验数据块也是以HDFS block为单位保存在DataNode上的,直接用cat命令查看为乱码。
8.Fayson在本文的实操部分选择了3种场景,1个文件非常小,小于策略默认的cell大小1024K,另一个文件大于策略默认的cell大小1024K,却小于2*1024K,最后一个文件非常大1.2G,大约可以被拆分为5个256MB。对于第一个场景虽然选择的策略是XOR(2,1),但因文件太小,没办法被cell的size拆分,所以只有一个原始数据块,一个校验数据块,这2个数据块属于同一个block group。第二种情况因为可以被cell的size拆分,所以按照策略XOR(2,1),有2个原始数据块,一个校验数据块,3个数据块都属于一个block group。第三种情况原始数据特别大,被拆为5个256MB的block group,每个group都包含2个原始数据块(均为128MB每个),同时包含1个校验数据块(也为128MB)。
参考:
http://bigdatastudy.net/show.aspx?id=458&cid=8
https://hadoop.apache.org/docs/r3.0.0/hadoop-project-dist/hadoop-hdfs/HDFSErasureCoding.html
https://www.cloudera.com/documentation/enterprise/latest/topics/admin_hdfs_deployec.html
http://itxx00.github.io/blog/2017/08/20/hadoop3-ec-test/?hmsr=toutiao.io&utm_medium=toutiao.io&utm_source=toutiao.io
https://www.cnblogs.com/basenet855x/p/7889994.html
https://www.jianshu.com/p/9f99cc9630cd
提示:代码块部分可以左右滑动查看噢
为天地立心,为生民立命,为往圣继绝学,为万世开太平。
温馨提示:如果使用电脑查看图片不清晰,可以使用手机打开文章单击文中的图片放大查看高清原图。
推荐关注Hadoop实操,第一时间,分享更多Hadoop干货,欢迎转发和分享。
来源:CSDN
作者:Hadoop_SC
链接:https://blog.csdn.net/Hadoop_SC/article/details/104376127