hadoop-3.0.0-beta1運維手冊(011):HDFS Erasure Coding糾刪碼使用

寫在前面的話

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 http://nn1:9870/fsck?ugi=user&files=1&blocks=1&locations=1&path=%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 http://nn1:9870/fsck?ugi=user&files=1&blocks=1&locations=1&path=%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自動啓動恢復工作

 

上一篇:hadoop-3.0.0-beta1運維手冊(010):hdfs3.0.0基本操作-hdfs動態加入節點(2)》

原創文章,轉載請註明: 轉載自大數據學習網,作者:艾叔

本文鏈接地址http://www.bigdatastudy.net/show.aspx?id=458&cid=8

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章