Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30969
  • 博文数量: 11
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 140
  • 用 户 组: 普通用户
  • 注册时间: 2007-04-10 14:34
文章分类

全部博文(11)

文章存档

2017年(11)

我的朋友

分类: 大数据

2017-12-06 20:02:45

写在前面的话

Hdfs采用分布式架构,为上层的应用和用户提供可扩展、高吞吐、高可靠的数据存储服务。在整个Hadoop生态系统中,hdfs处于最底层,也是最无可替代的一个基础设施。从2008hadoop-0.10.1版本开始到现在的hadoop-3.0.0-beta1hdfs已经走过了近10个年头,其架构和功能特性也发生了巨大的变化。特别是hdfs3.0.0系列,和hdfs2.x相比,增加了基于纠删码(erasure encoding)的容错方式,与传统的副本方式相比,在同等可用性的情况下, 能大幅节省一半以上的空间,这也是自hdfs诞生近这十年来,数据可靠性机制上的一个重大变化(之前一直都是副本容错方式)。此外hdfs3.0.0还增加了其它的一些特性,例如在Namenode HA中支持3Namenode,可以容忍2Namenode失效,而hdfs2.x只能容忍1Namenode失效。

本文以的方式,在“”上记录自己使用hadoop-3.0.0-beta1hdfs的点点滴滴,包括从零开始搭建分布式hdfs3.0,如何动态扩展hdfs节点、如何使用hdfs3.0的纠删码容错等等。不当之处,请大家发邮件aishuc@126com给艾叔,谢谢!

 

本节我们将演示如何使用hdfs3.0的纠删码功能,纠删码是hdfs3.0新加入的功能,之前的hdfs都是采用副本方式容错,默认情况下,一个文件有3个副本,可以容忍任意2个副本(datanode)不可用,这样提高了数据的可用性,但也带来了2倍的冗余开销。例如3TB的空间,只能存储1TB的有效数据。而纠删码则可以在同等可用性的情况下,节省更多的空间,以rs-6-3-1024K这种纠删码策略为例子,6份原始数据,编码后生成3份校验数据,一共9份数据,只要最终有6份数据存在,就可以得到原始数据,它可以容忍任意3份数据不可用,而冗余的空间只有原始空间的0.5倍,只有副本方式的1/4,因此,可以大大节约成本。

由于编码出来的数据,要分布到多台datanode上,例如rs-6-3-1024K,就需要至少6+3=9datanode,我们目前只有2datanode,因此还需要扩充7datanode。下面的的操作就是,先扩充datanode,然后演示如何进行纠删码操作。

6.1 复制datanode节点、并动态加入 

由于纠删码要用到多个节点,我们复制dn1,构建10datanode,分布从dn2~dn9,每个datanode的内存配置为256MBIP地址从192.168.182.13~192.168.182.20

A. 每个datanode上要做的事情

1. 修改虚拟机名、主机名

2. 修改网络配置

3. 添加hosts解析

 

4. 清除datanode存储目录下的文件

5. 虚拟机内存调整位256MB

注意:打开虚拟机时,一定要选择I copied it

 

B. nn1上要做的事情

1. 添加hosts解析

2. workers文件中添加所有的datanode主机名

 

C. dn1上要做的事情

1. 添加hosts解析

 

这是最终启动的虚拟机nn1,dn1~dn9

6-1 hdfs3.0纠删码演示环境虚拟机

每个datanode的内存是256MB

6-2 Vmware workstation虚拟机内存配置

每个节点的hosts文件

127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4

::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

192.168.182.11 nn1

192.168.182.12 dn1

192.168.182.13 dn2

192.168.182.14 dn3

192.168.182.15 dn4

192.168.182.16 dn5

192.168.182.17 dn6

192.168.182.18 dn7

192.168.182.19 dn8

192.168.182.20 dn9

动态加入后的hdfs3.0如下

6-3 hdfs3.0 web信息界面

 

6.2 纠删码基本操作

1. 查看当前支持的纠删码策略

命令如下

[user@nn1 ~]$ 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=DISABLED]

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=DISABLED]

目前hadoop-3.0.0beta1共支持5种纠删码策略,分别是:

RS-10-4-1024k:使用RS编码,每10个数据单元(cell),生成4个校验单元,共14个单元,也就是说:这14个单元中,只要有任意的10个单元存在(不管是数据单元还是校验单元,只要总数=10),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576

RS-3-2-1024k:使用RS编码,每3个数据单元,生成2个校验单元,共5个单元,也就是说:这5个单元中,只要有任意的3个单元存在(不管是数据单元还是校验单元,只要总数=3),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576

RS-6-3-1024k:使用RS编码,每6个数据单元,生成3个校验单元,共9个单元,也就是说:这9个单元中,只要有任意的6个单元存在(不管是数据单元还是校验单元,只要总数=6),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576

RS-LEGACY-6-3-1024k:策略和上面的RS-6-3-1024k一样,只是编码的算法用的是rs-legacy,应该是之前遗留的rs算法。

XOR-2-1-1024k:使用XOR编码(速度比RS编码快),每2个数据单元,生成1个校验单元,共3个单元,也就是说:这3个单元中,只要有任意的2个单元存在(不管是数据单元还是校验单元,只要总数=2),就可以得到原始数据。每个单元的大小是1024k=1024*1024=1048576

RS-6-3-1024k为例,6个数据单元+3个校验单元,可以容忍任意的3个单元丢失,冗余的数据是50%。而采用副本方式,3个副本,冗余200%,却还不能容忍任意3个单元丢失。因此,RS编码在相同冗余度的情况下,会大大提升数据的可用性,而在相同可用性的情况下,会大大节省冗余空间。

 

2. 设置纠删码策略

纠删码策略是与具体的路径(path)相关联的。也就是说,如果我们要使用纠删码,则要给一个具体的路径设置纠删码策略,后续,所有往此目录下存储的文件,都会执行此策略。

例子如下

首先在/下创建目录rs-6-3,然后查看其是否设置了纠删码策略,结果显示没有指定策略(新建的目录不会指定策略)

[user@nn1 ~]$ hdfs dfs -mkdir /rs-6-3

[user@nn1 ~]$ hdfs ec -getPolicy -path /rs-6-3

The erasure coding policy of /rs-6-3 is unspecified

接下来,给此目录设置纠删码策略RS-6-3-1024k,此策略名是从前面list策略中查到的。可以看到已经设置成功。

[user@nn1 ~]$ hdfs ec -setPolicy -path /rs-6-3 -policy RS-6-3-1024k

Set erasure coding policy RS-6-3-1024k on /rs-6-3

注意

RS-6-3-1024k可以直接设置成功,其它的策略需要enable后,才能设置:

设置RS-3-2-1024k,这个需要先enablePolicy

[user@nn1 hadoop-3.0.0-beta1]$ hdfs ec -enablePolicy  -policy RS-3-2-1024k

Erasure coding policy RS-3-2-1024k is enabled

[user@nn1 hadoop-3.0.0-beta1]$ hdfs ec -setPolicy -path /rs-3-2 -policy RS-3-2-1024k

Set erasure coding policy RS-3-2-1024k on /rs-3-2

验证

[user@nn1 hadoop-3.0.0-beta1]$ hdfs ec -getPolicy -path /rs-3-2

RS-3-2-1024k

设置RS-10-4-1024k,如果不enablePolicy,会报错

[user@nn1 hadoop-3.0.0-beta1]$ hdfs dfs -mkdir /rs-10-4

[user@nn1 hadoop-3.0.0-beta1]$ hdfs ec -setPolicy -path /rs-10-4 -policy RS-10-4-1024k

报错了

RemoteException: Policy 'RS-10-4-1024k' does not match any enabled erasure coding policies: [RS-3-2-1024k, RS-6-3-1024k]. An erasure coding policy can be enabled by enableErasureCodingPolicy API.

 

3. 上传文件,查看文件编码情况

下面我们上传一个文件看一下,这里提示我们没有使用ISA-L支持的编码器(这个编码器和CPU优化相结合,效率更高,需要重新编译和配置,我们后续再讲)

[user@nn1 ~]$ hdfs dfs -cp /profile /rs-6-3/

2017-11-30 10:24:29,620 WARN erasurecode.ErasureCodeNative: ISA-L support is not available in your platform... using builtin-java codec where applicable

查看profile编码后的分布

[user@nn1 ~]$ hdfs fsck /rs-6-3/profile  -files -blocks -locations

输出

Connecting to namenode via %2Frs-6-3%2Fprofile

FSCK started by user (auth:SIMPLE) from /192.168.182.11 for path /rs-6-3/profile at Thu Nov 30 10:57:12 EST 2017

/rs-6-3/profile 1872 bytes, erasure-coded: policy=RS-6-3-1024k, 1 block(s):  OK

0. BP-529485104-192.168.182.11-1511810134643:blk_-9223372036854775792_1065 len=1872 Live_repl=4  [blk_-9223372036854775792:DatanodeInfoWithStorage[192.168.182.11:9866,DS-da58ee3e-adcc-4f6c-8488-c2a0b742d8b9,DISK], blk_-9223372036854775786:DatanodeInfoWithStorage[192.168.182.20:9866,DS-c36de658-0f5a-42de-8898-eab3b04c7016,DISK], blk_-9223372036854775785:DatanodeInfoWithStorage[192.168.182.14:9866,DS-a3569982-de52-42b5-8543-94578f8b452a,DISK], blk_-9223372036854775784:DatanodeInfoWithStorage[192.168.182.19:9866,DS-71be9468-c0c7-437c-8b59-ece27593b4c2,DISK]]

 

查看block文件的信息,可以看到nn1block的大小正好是1872。这是因为1872<1024k,因此无法分割,直接整体编码。

[user@nn1 ~]$ ls dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775792 -l

-rw-rw-r--. 1 user user 1872 Nov 30 10:24 dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775792

Live_repl=4的解释,表示此文件共有4个副本,其中1个是原始数据,3个是校验数据,因此,这里的策略是rs_6_3,要保证冗余3个校验单元,原始数据1872<1024k,只能构成1个数据单元,再加上3个校验单元,就是4个副本了。

1 block(s)的解释:blocks是指数据单元在datanode的存储而言,1872<1024k,只有1个数据单元,因此只能分配到1datanode,对于每个datanode,其block默认大小是256MBhdfs3.0256MBhdfs2.x128MB),1872远小于256MB,当然只有1block了,如果单个datanode上多个数据单元之和>256MB,这时才会生成新的block

再看一个

hdfs dfs -cp file:///home/user/jdk1.8.0_152/lib/ant-javafx.jar /rs-6-3/

此文件的大小是1224175>1024k,但是<2*1024k,也就是可以构成2个数据单元,加上3个校验单元,推测最终编码出来一共是5个副本。

查看下

[user@nn1 ~]$ hdfs fsck /rs-6-3/ant-javafx.jar  -files -blocks -locations

果然是

/rs-6-3/ant-javafx.jar 1224175 bytes, erasure-coded: policy=RS-6-3-1024k, 1 block(s):  OK

0. BP-529485104-192.168.182.11-1511810134643:blk_-9223372036854775776_1066 len=1224175 Live_repl=5  [blk_-9223372036854775776:DatanodeInfoWithStorage[192.168.182.11:9866,DS-da58ee3e-adcc-4f6c-8488-c2a0b742d8b9,DISK], blk_-9223372036854775775:DatanodeInfoWithStorage[192.168.182.18:9866,DS-2dc5d603-ad42-4558-bfda-c9a597f88f06,DISK], blk_-9223372036854775770:DatanodeInfoWithStorage[192.168.182.14:9866,DS-a3569982-de52-42b5-8543-94578f8b452a,DISK], blk_-9223372036854775769:DatanodeInfoWithStorage[192.168.182.20:9866,DS-c36de658-0f5a-42de-8898-eab3b04c7016,DISK], blk_-9223372036854775768:DatanodeInfoWithStorage[192.168.182.13:9866,DS-118ae8da-f820-447c-9d97-dbe4f33bff39,DISK]]

查看第一个block的大小(nn1),可以看到正好是按照1024k来切分的

[user@nn1 ~]$ ls dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775776 -l

-rw-rw-r--. 1 user user 1048576 Nov 30 10:30 dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775776

查看第二个block的大小(nn7),其大小是175599

[user@dn7 ~]$ ls dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775775 -l

-rw-rw-r--. 1 user user 175599 Nov 30 11:54 dfs/share/datanode/current/BP-529485104-192.168.182.11-1511810134643/current/finalized/subdir0/subdir0/blk_-9223372036854775775

第一个block 1048576 + 第二个block 175599 = 1224175,正好是ant-javafx.jar的大小。

为什么第二个block没有补齐1024k呢?因为补齐的话,也是填0,没有必要。

第三个block~第五个block是校验数据。

 

4. 数据恢复验证(datanode dead的时间间隔是10m

我们以ant-javafx.jar为例,它有5个副本,分布在:

192.168.182.11

192.168.182.18

192.168.182.14

192.168.182.20

192.168.182.13

其中2个原始数据单元、3个校验数据单元,意味着可以容忍任意3个数据单元的丢失。

下面,我们关闭后3个节点上的datanode

192.168.182.14

192.168.182.20

192.168.182.13

然后从/rs-6-3目录中复制ant-javafx.jar到本地/tmp目录,并和本地的ant-javafx.jar比较,正确,说明数据没有问题。

[user@nn1 ~]$ hdfs dfs -cp /rs-6-3/ant-javafx.jar file:///tmp/

2017-11-30 13:12:36,493 WARN erasurecode.ErasureCodeNative: ISA-L support is not available in your platform... using builtin-java codec where applicable

[user@nn1 ~]$ diff jdk1.8.0_152/lib/ant-javafx.jar /tmp/ant-javafx.jar

再关掉一个节点,在下面的节点

192.168.182.18

运行

[user@dn7 ~]$ hdfs --daemon stop datanode

nn1上再次复制

报错,因为丢失的数据单元个数>3

cp: 4 missing blocks, the stripe is: Offset=0, length=175599, fetchedChunksNum=0, missingChunksNum=4

dn3上启动datanode,再次复制

发现还是报错,说192.168.182.18上数据丢失,这是为什么呢?

查看HDFS状态,发现刚才关闭的dn3 dn9 dn2 dn7仍然是live的,这是因为datanode的状态有一个刷新的间隔,这个间隔默认是10m600s),只有10m没有收到datanode的消息,namenode才认为此datanodedead的。

因此,等待10m后,可以看到HDFSlive nodes变成了7

 

6-4 hdfs3.0 web datanode信息界面

这个时候,再次复制,DFSClient就知道dn7dead,就不会再选择dn7了,转而选择其它的live节点,因此复制成功。

[user@nn1 ~]$ hdfs dfs -cp /rs-6-3/ant-javafx.jar file:///tmp/

2017-11-30 13:26:35,241 WARN erasurecode.ErasureCodeNative: ISA-L support is not available in your platform... using builtin-java codec where applicable

cp: `file:///tmp/ant-javafx.jar': File exists

dn2dn7dn9恢复,启动datanode,再次查看

[user@nn1 ~]$ hdfs fsck /rs-6-3/ant-javafx.jar  -files -blocks -locations

Connecting to namenode via %2Frs-6-3%2Fant-javafx.jar

FSCK started by user (auth:SIMPLE) from /192.168.182.11 for path /rs-6-3/ant-javafx.jar at Thu Nov 30 13:29:30 EST 2017

/rs-6-3/ant-javafx.jar 1224175 bytes, erasure-coded: policy=RS-6-3-1024k, 1 block(s):  OK

0. BP-529485104-192.168.182.11-1511810134643:blk_-9223372036854775776_1066 len=1224175 Live_repl=5  [blk_-9223372036854775776:DatanodeInfoWithStorage[192.168.182.11:9866,DS-da58ee3e-adcc-4f6c-8488-c2a0b742d8b9,DISK], blk_-9223372036854775770:DatanodeInfoWithStorage[192.168.182.14:9866,DS-a3569982-de52-42b5-8543-94578f8b452a,DISK], blk_-9223372036854775769:DatanodeInfoWithStorage[192.168.182.19:9866,DS-71be9468-c0c7-437c-8b59-ece27593b4c2,DISK], blk_-9223372036854775768:DatanodeInfoWithStorage[192.168.182.16:9866,DS-c32fdd4e-aa34-4b65-b192-643ade06d71b,DISK], blk_-9223372036854775775:DatanodeInfoWithStorage[192.168.182.18:9866,DS-2dc5d603-ad42-4558-bfda-c9a597f88f06,DISK]]

发现数据单元的分布发生了变化

192.168.182.11

192.168.182.14

192.168.182.19

192.168.182.16

192.168.182.18

其中绿色部分,应该是在这些节点关闭后,hdfs重新启动译码和编码,将原来丢失的数据补到了dn8dn5上。而dn8没有去掉,可能是还没来得及。

总之,如果编码后的stripe中,有数据丢失,hdfs自动启动恢复工作

 

上一篇:

原创文章,转载请注明: 转载自

本文链接地址

阅读(1943) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~