Skip to content

antony@notes:~/data-platform$ cat "Hadoop-實戰篇.md"

Hadoop 實戰篇

2022-06-10· data-platform ·資料科技平台

Hadoop 實戰篇

目錄

[TOC]

落地雲 應用套件包的系統需求

  1. 下載 VMware Workstation Player 軟體,下載網址如下:

    https://www.vmware.com/tw/products/workstation-player/workstation-player-evaluation.html

  2. 要執行高教落地雲,最低系統需求如下:

    • 4 核心 CPU (VT-x: i3,i5,i7,i9)
    • 至少 32 G 記憶體
    • 微軟 64 位元作業系統 (Windows 10/11)

落地雲 應用套件包下載與內容

  1. 在 Windows 系統, 啟動 Browser, 下載 CNT.2022.v4.zip
  2. 下載後, 請將 CNT.2022.v4.zip 解壓縮至 使用者家目錄, 例如 /user/rbean
C:\\Users\\rbean>dir CNT.2022.v4

.....

2022/01/29 下午 09:52  <DIR>  ALP.DT.ADM
2022/01/29 下午 09:53  <DIR>  ALP.K8S
2022/01/29 下午 09:53  <DIR>  ALP3
2022/01/29 上午 09:07   1,768 docker.bat
2022/02/02 下午 03:32   7,457 dt.bat
2022/02/02 下午 03:44   4,499 k8s.bat
2022/01/29 上午 09:07   1,769 podman.bat
2022/01/29 下午 09:53  <DIR>  system
2022/01/29 上午 09:07   115 vmrun.bat

認識 Alpine Linux

Alpine Linux 是一套由社群開發,以安全為導向的 Linux 作業系統,目前最新的版本 v3.6.2 在 2017-06-17 發布。

跟一般的 Linux 發行版不一樣的地方是 Alpine 是使用 musl libcbusybox 來減少系統需求容量(5 MB )和執行消耗資源。

比起其他輕量化 Image (如:Busybox,Image 大小為1.113MB), Alpine 的優勢在於多了像是 apt 之於 Ubuntu 這樣的套件管理工具 apk ,官方提供了大量的套件供開發者使用,可以透過網站或者直接下 apk 指令進行查詢或者安裝。

Alpine 的busybox 是 HardLink, 而不是 Softlink. Docker busybox image 沒有提供 套件安裝平台


80 年代大型主機實體架構

只要提到linux作業系統,他一定可以連接很多台終端機(Terminals),他沒有硬碟,只有螢幕跟鍵盤,讓操作者能夠打字看結果,在終端機裡面跑的程式叫做“貝殼程式”,有sh(輕量貝殼)、有bash(重量貝殼程式),只要在linux和unix系統裡面,跑貝殼程式,一定在終端機上面跑,讓人家可以打字,命令會透過RS-232這條線,傳到linux的主機去執行,執行完的結果會再透過RS-232傳回來到終端機的螢幕上。


建制資科平台

建立 資科平台 虛擬主機

在 Windows 系統的 cmd 終端機,執行以下命令

C:\\Users\\rbean>cd CNT.2022.v4 
C:\\Users\\rbean\\CNT.2022.v4> dt create
"DT\\alp.dta1\ (3072MB) ok"
"DT\\alp.dtm1\ (3072MB) ok"
"DT\\alp.dtm2\ (3072MB) ok"
"DT\\alp.dtw1\ (4096MB) ok"
"DT\\alp.dtw2\ (4096MB) ok"
"DT\\alp.dtw3\ (4096MB) ok"

[] dt.bat 會產生 6 個 虛擬主機, 並設定這 6 部虛擬主機的 記憶體, MAC 位址, 虛擬主機名稱, IP 位址 及 電腦名稱

啟動 資科平台 虛擬主機

C:\\Users\\rbean\\CNT.2022.v4> dt start

C:\\Users\\rbean\\CNT.2022.v4> dt list
[DT]
alp.a1
alp.m1
alp.m2
alp.w1
alp.w2
alp.w3

[VM runnig]
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.a1\\alpine64.vmwarevm\\alpine64.vmx
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.m1\\alpine64.vmwarevm\\alpine64.vmx
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.m2\\alpine64.vmwarevm\\alpine64.vmx
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.w1\\alpine64.vmwarevm\\alpine64.vmx
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.w2\\alpine64.vmwarevm\\alpine64.vmx
C:\\Users\\gbean\\CNT.2022.v1\\DT\\alp.w3\\alpine64.vmwarevm\\alpine64.vmx

資科平台 管理主機 啟動畫面


登入 資科平台 管理主機

# 利用SSH指令連線到dtal的主機,使用者為: bigred
C:\Users\rbean\CNT.2022.v4> ssh bigred@192.168.116.3
The authenticity of host '192.168.72.3 (192.168.116.3)' can't be established.
ECDSA key fingerprint is SHA256:Kkr7Pkjo+QclG7y4QqI3/saqgd8Su3u6H4DxHV3V3vU.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.116.3' (ECDSA) to the list of known hosts.
bigred@192.168.116.3's password: bigred

資科平台 系統準備

# 在家目錄,下載資科平台的建置包,並解壓縮
$ cd; wget http://www.oc99.org/zip/vmalpdt2022.zip; unzip vmalpdt2022.zip 

$ dir vmalpdt
total 20K
drwxr-sr-x 5 bigred bigred 4.0K Apr 25 10:13 .
drwxr-sr-x 7 bigred bigred 4.0K Apr 25 14:41 ..
drwxr-sr-x 2 bigred bigred 4.0K Mar 21 22:17 bin
drwxr-sr-x 5 bigred bigred 4.0K Apr 25 10:11 hdp210
drwxr-sr-x 5 bigred bigred 4.0K Apr 24 21:13 hdp33

$ cd ~/vmalpdt; dir hdp210
total 341M
drwxr-sr-x 5 bigred bigred 4.0K Apr 25 10:11 .
drwxr-sr-x 5 bigred bigred 4.0K Apr 25 10:13 ..
-rwxr-xr-x 1 bigred bigred 2.6K Apr 25 10:34 alpine.bash
drwxr-sr-x 2 bigred bigred 4.0K Mar 21 20:36 bin
drwxr-sr-x 7 bigred bigred 4.0K Apr 25 10:33 conf
-rw-r--r-- 1 bigred bigred  348 Apr 25 09:55 dlist
-rw-r--r-- 1 bigred bigred  889 Apr 25 10:36 environment
-rw-r--r-- 1 bigred bigred 341M Mar 21 20:42 hadoop-2.10.1.zip
drwxr-sr-x 2 bigred bigred 4.0K Apr 25 10:38 opt

補充 SHell

執行env,看環境變數,可以看到終端機的設定

bigred@dta1:~$ env
SHELL=/bin/bash   # 看哪個shell程式,這裡是bash(重裝貝殼程式)
...
TERM=xterm-256color # 讓終端機在運作時可以有顏色
...
SSH_TTY=/dev/pts/1 # 虛擬終端機,這個終端機是給SSH通訊協定用的,/dev的全名是device

下載 DT 套件檔

檢視 下載資科平台套件 清單檔
$ cat hdp210/dlist
https://dlcdn.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz
https://dlcdn.apache.org/pig/pig-0.17.0/pig-0.17.0.tar.gz
https://dlcdn.apache.org/spark/spark-3.2.1/spark-3.2.1-bin-hadoop2.7.tgz
https://dlcdn.apache.org/hbase/2.4.11/hbase-2.4.11-bin.tar.gz
https://dlcdn.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz

開始 下載資科平台套件 
$ ./bin/dtwget 210
apache-hive-3.1.3-bin.tar.gz ok
pig-0.17.0.tar.gz ok
spark-3.2.1-bin-hadoop2.7.tgz ok
hbase-2.4.11-bin.tar.gz ok
apache-zookeeper-3.6.3-bin.tar.gz ok
Hadoop-2.10.1 ok

[註] dtwget 主要是下載 DT 套件檔至 ~/vmalpdt/hdp33/opt 這目錄

複製 資料科技平台 套件檔

$ ./bin/dtcopy 210
dta1 /opt/ ok
dta1 alpine.bash ok
dta1 environment ok
dta1 /etc/hosts ok

dtm1 /opt/ ok
dtm1: /opt/bin ok
dtm1 alpine.bash ok
dtm1 environment ok
dtm1 /etc/hosts ok

dtm2 /opt/ ok
dtm2 alpine.bash ok
dtm2 environment ok
dtm2 /etc/hosts ok

......

[註] dtcopy 主要是覆製 dta1 主機 /home/bigred/vmalpdt/hdp33/opt 這目錄至 dta1, dtm1, dtm2, dtw1, dtw2, dtw3 這三部主機的 /opt 目錄

複製 資料科技 平台 設定檔

$ ./bin/dtconf 210
dta1: apache-hive-3.1.3-bin config ok
dta1: apache-zookeeper-3.6.3-bin config ok
dta1: hadoop-2.10.1 config ok
dta1: hbase-2.4.11 config ok
dta1: spark-3.2.1-bin-hadoop2.7 config ok
dta1 /etc/profile ok

dtm1: apache-hive-3.1.3-bin config ok
dtm1: apache-zookeeper-3.6.3-bin config ok
dtm1: hadoop-2.10.1 config ok
dtm1: hbase-2.4.11 config ok
dtm1: spark-3.2.1-bin-hadoop2.7 config ok
dtm1 /etc/profile ok

dtm2: apache-hive-3.1.3-bin config ok
dtm2: apache-zookeeper-3.6.3-bin config ok
dtm2: hadoop-2.10.1 config ok
dtm2: hbase-2.4.11 config ok
dtm2: spark-3.2.1-bin-hadoop2.7 config ok
dtm2 /etc/profile ok
.........

檢測 資料科技 平台

$ ./bin/dthdpchk 210
[dta1]
Hadoop 2.10.1
Native library checking:
hadoop:  true /opt/hadoop-2.10.1/lib/native/libhadoop.so
zlib:    true /lib/libz.so.1
snappy:  true /usr/lib/libsnappy.so.1
zstd  :  false
lz4:     true revision:10301
bzip2:   true /usr/lib/libbz2.so.1
openssl: true /usr/lib/libcrypto.so

[dtm1]
Hadoop 2.10.1
Native library checking:
hadoop:  true /opt/hadoop-2.10.1/lib/native/libhadoop.so
zlib:    true /lib/libz.so.1
snappy:  true /usr/lib/libsnappy.so.1
zstd  :  false
lz4:     true revision:10301
bzip2:   true /usr/lib/libbz2.so.1
openssl: true /usr/lib/libcrypto.so

格式化 HDFS 分散檔案系統

bigred@dta1:~$ sudo reboot

C:\Users\rbean\CNT.2022.v4> ssh bigred@192.168.116.3
bigred@192.168.116.3's password: bigred

bigred@dta1:~$ formathdfs
Are you sure ? (YES/NO) YES
formathdfs ok

啟動 資科平台

啟動分散式檔案系統

bigred@dta1:~$ starthdfs
dtm1: Name Node Started
dtm1: Secondary Name Node started
dtw1: Data Node started
dtw2: Data Node started
dtw3: Data Node started

啟動YARN

bigred@dta1:~$ startyarn
dtm2: Resource Manager started
dtm2: Job History Server started
dtw1: Node Manager started
dtw2: Node Manager started
dtw3: Node Manager started

測試 資科平台

測試資料科技平台有沒有問題,Hbase因為目前沒用到,所以沒啟動

bigred@dta1:~$ dtest
[HDFS]
Live datanodes (3):
Name: 192.168.61.6:50010 (dtw1)
Name: 192.168.61.7:50010 (dtw2)
Name: 192.168.61.8:50010 (dtw3)

[YARN]
Total Nodes:3
         Node-Id             Node-State Node-Http-Address       Number-of-Running-Containers
      dtw3:43493                RUNNING         dtw3:8042                                  0
      dtw1:40799                RUNNING         dtw1:8042                                  0
      dtw2:33379                RUNNING         dtw2:8042                                  0

[MapReduce]
Estimated value of Pi is 3.14400000000000000000

[Spark]
Pi is roughly 3.145160

[HBase]

關閉 資科平台

bigred@dta1:~$ stopyarn; stophdfs
dtw1: Node Manager stoped
dtw2: Node Manager stoped
dtw3: Node Manager stoped
dtm2: Job History Server stoped
dtm2: Resource Manager stoped
dtw1: Data Node stoped
dtw2: Data Node stoped
dtw3: Data Node stoped
dtm1: Secondary Name Node stoped
dtm1: Name Node stoped

關閉 資科平台基礎 虛擬主機

bigred@dta1:~$ exit

C:\Users\bigred\CNT.2022.v4>dt stop

Open Data 截取, 轉換及載入 (ETL)

取得機場、港口入出境人數統計資料集

Windows 系統的 CMD 視窗, 執行以下命令

透過SSH命令連到dta1主機
$ ssh bigred@<alp.dta1 IP>

建立目錄
$ mkdir -p ~/opendata/dip

用wget下載檔案,並且在家目錄命名為2016ip.zip
$ wget 'https://data.moi.gov.tw/MoiOD/System/DownloadFile.aspx?DATA=BC553073-6E98-47CC-92FA-6DB9720D9993' -O ~/2016dip.zip

--2022-04-28 13:18:48--  https://data.moi.gov.tw/MoiOD/System/DownloadFile.aspx?DATA=BC553073-6E98-47CC-92FA-6DB9720D9993
Resolving data.moi.gov.tw (data.moi.gov.tw)... 117.56.7.114
Connecting to data.moi.gov.tw (data.moi.gov.tw)|117.56.7.114|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 38004 (37K) [application/zip]
Saving to: '/home/bigred/2016dip.zip'

/home/bigred/2016dip.zip       100%[=================================================>]  37.11K  --.-KB/s    in 0.008s

2022-04-28 13:18:49 (4.36 MB/s) - '/home/bigred/2016dip.zip' saved [38004/38004]

   

> \[註\] -O   下載後儲存至 /tmp/2016dip.zip 檔,   入出境人數網址:https://data.gov.tw/dataset/12369

bigred@dta1:~$ mkdir /tmp/data; cd /tmp/data; unzip ~/2016dip.zip
Archive:  /home/bigred/2016dip.zip
  inflating: 2016-DailyImmigPort-All.csv
  inflating: file.csv
  inflating: manifest.csv
 extracting: schema-file.csv

bigred@dta1:/tmp/data$ dir
total 132K
drwxr-xr-x 2 bigred bigred 4.0K Apr 28 13:19 .
drwxrwxrwt 7 root   root   4.0K Apr 28 13:19 ..
-rw-r--r-- 1 bigred bigred 111K May  3  2018 2016-DailyImmigPort-All.csv
-rw-r--r-- 1 bigred bigred  545 May 24  2018 file.csv
-rw-r--r-- 1 bigred bigred   59 Jan 29  2018 manifest.csv
-rw-r--r-- 1 bigred bigred   49 Jan 29  2018 schema-file.csv

$ mv 2016-DailyImmigPort-All.csv ~/opendata/dip/
$ cd; rm -r /tmp/data 

檢視機場、港口入出境人數統計資料集
$ cd; head -n 3 opendata/dip/2016-DailyImmigPort-All.csv 

整理機場、港口入出境人數統計資料集

$ cat ~/opendata/dip/2016-DailyImmigPort-All.csv | wc -l
368


$ tail -n +3  ~/opendata/dip/2016-DailyImmigPort-All.csv | head -n 1
20160101,128447,22808,25372,48180,23050,24914,47964,96144,6376,5928,12304,1722,587,2309,1,2,3,8,85,93,0,0,0,0,0,0,0,0,0,128,177,305,0,0,0,3664,3867,7531,2751,2960,5711,20,237,257,0,158,158,9,2,11,0,0,0,1478,2021,3499,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,22,22,0,0,0,26,73,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,

移除前二行
$ tail -n +3 ~/opendata/dip/2016-DailyImmigPort-All.csv > 2016dip.csv
$ head -n 1 2016dip.csv 
20160101,128447,22808,25372,48180,23050,24914,47964,96144,6376,5928,12304,1722,587,2309,1,2,3,8,85,93,0,0,0,0,0,0,0,0,0,128,177,305,0,0,0,3664,3867,7531,2751,2960,5711,20,237,257,0,158,158,9,2,11,0,0,0,1478,2021,3499,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,22,22,0,0,0,26,73,99,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,,,
    wget -qO - http://www.oc99.org/dt/getcsv.sh | bash
    -q 代表靜音模式(不顯示指令輸出)
    -O 將檔案輸出(大寫的O)
    - 標準輸出裝置(利用螢幕作為輸出目標)
    | bash 把輸出的內容丟給 bash 執行
    結果:在螢幕裝置輸出,丟給 bash 執行,不會把程式下載下來,與顯示指令輸出
    
    standard input 標準輸入|代碼為 0 程式執行所需要的輸入資料
    standard output 標準輸出|代碼為 1、- 程式正常執行所產生的輸出資料
    standard error output 標準錯誤輸出|代碼為 2 程式出錯時通知使用者用的訊息,或是呈現程式狀態用的訊息
bigred@dta1:~$ echo ~
/home/bigred

家目錄能存的檔案有限

bigred@dta1:~$ hdfs dfs -ls /user
Found 1 items
drwxr-xr-x   - bigred bigboss          0 2022-04-28 13:11 /user/bigred

我們的第二個家,是在HDFS檔案系統裡面,也有一個家目錄,他能存放的檔案比較多

只要在linux系統裡面的家目錄,他的名字一定是/home,在HDFS檔案系統裡面,他的家目錄名字一定是/user

檢查JAVA程式狀態

bigred@dta1:~$ hls
[dtm1]
3544 SecondaryNameNode   ## 3544代表pid
3435 NameNode

[dtm2]
3500 ResourceManager
3550 JobHistoryServer

[dtw1]
4050 DataNode
4218 NodeManager

[dtw2]
4035 DataNode
4200 NodeManager

[dtw3]
4018 DataNode
4180 NodeManager

HDFS 操作命令 (一)

顯示使用者 HDFS 家目錄

$ pig -e 'pwd'  2>/dev/null   # -e 是執行後面的pwd
hdfs://dtm1:8020/user/bigred  # hdfs://dtm1:8020,代表dtm1的Name Node這個Java程式回答,port是8020

開啟pig模式,並且把pig的交談模式噴出的錯誤訊息和警告訊息丟到黑洞

bigred@dta1:~$ pig 2>/dev/null
grunt> ls
hdfs://dtm1:8020/user/bigred/.sparkStaging      <dir>
grunt> mkdir zzz                                     #建立zzz目錄
grunt> ls
hdfs://dtm1:8020/user/bigred/.sparkStaging      <dir>
hdfs://dtm1:8020/user/bigred/zzz        <dir>
grunt> rm zzz                                        #豬小弟的rm,可以直接刪目錄
grunt> ls
hdfs://dtm1:8020/user/bigred/.sparkStaging      <dir>

產生mydataset的目錄

$ hdfbigred@dta1:~$ hdfs dfs -mkdir mydataset
bigred@dta1:~$ hdfs dfs -ls
Found 2 items
drwxr-xr-x   - bigred bigboss          0 2022-04-28 13:12 .sparkStaging
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:13 mydatasets dfs -mkdir  mydataset

HDFS檔案系統是仿照linux檔案系統設計的,有些linux檔案系統的命令會沒有,例如tree

bigred@dta1:~$ head -n 2  ~/mycsv/customer.csv
4000001,Kristina,Chung,55,Pilot
4000002,Paige,Chen,74,Teacher

bigred@dta1:~$ hdfs dfs -put ~/mycsv/customer.csv  mydataset/  ## 把linux檔案系統的家目錄的檔案,搬到HDFS檔案系統下的mydataset目錄下

bigred@dta1:~$ hdfs dfs -ls  mydataset/  ## -ls 查看mydataset目錄下的子目錄和檔案
Found 1 items
-rw-r--r--   2 bigred bigboss        695 2022-04-29 10:16 mydataset/customer.csv

bigred@dta1:~$ hdfs dfs -cat mydataset/customer.csv  ##  -cat 看檔案內容
4000001,Kristina,Chung,55,Pilot
4000002,Paige,Chen,74,Teacher
4000003,Sherri,Melton,34,Firefighter
4000004,Gretchen,Hill,66,Computer hardware engineer
4000005,Karen,Puckett,74,Lawyer
4000006,Patrick,Song,42,Veterinarian
4000007,Elsie,Hamilton,43,Pilot
4000008,Hazel,Bender,63,Carpenter
4000009,Malcolm,Wagner,39,Artist
4000010,Dolores,McLaughlin,60,Writer
4000011,Francis,McNamara,47,Therapist
4000012,Sandy,Raynor,26,Writer
4000013,Marion,Moon,41,Carpenter
4000014,Beth,Woodard,65,
4000015,Julia,Desai,49,Musician
4000016,Jerome,Wallace,52,Pharmacist
4000017,Neal,Lawrence,72,Computer support specialist
4000018,Jean,Griffin,45,Childcare worker
4000019,Kristine,Dougherty,63,Financial analyst

[重要] 管理目錄, 記得目錄名稱最後要加上 “/”

練習

1.請在 HDFS 建立以下目錄架構 ?

mydataset

|--US

|--TW

答案:

bigred@dta1:~$ hdfs dfs -mkdir -p mydataset/{US,TW}
bigred@dta1:~$ hdfs dfs -ls mydataset
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:25 mydataset/TW
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:25 mydataset/US
-rw-r--r--   2 bigred bigboss        695 2022-04-29 10:16 mydataset/customer.csv

2.請將 Linux 的 /etc/hosts 檔案上傳至 HDFS 檔案系統的 mydataset/TW 目錄中

答案:

bigred@dta1:~$ hdfs dfs -put /etc/hosts mydataset/TW

bigred@dta1:~$ hdfs dfs -ls mydataset/TW
Found 1 items
-rw-r--r--   2 bigred bigboss        198 2022-04-29 10:28 mydataset/TW/hosts

HDFS 操作命令 (二)

檔案可以覆蓋

bigred@dta1:~$ hdfs dfs -put ~/mycsv/customer.csv  mydataset/
put: 'mydataset/customer.csv': File exists

bigred@dta1:~$ hdfs dfs -put -f ~/mycsv/customer.csv  mydataset/
## -f ,force 強迫的意思

檔案內容可增加

bigred@dta1:~$ hdfs dfs -cat  mydataset/customer.csv | wc -l
20
bigred@dta1:~$ hdfs dfs -appendToFile ~/mycsv/customer.csv mydataset/customer.csv
## -appendToFile 對已經存在的檔案,增加資料到裡面,從檔案內的最後一行開始增加
bigred@dta1:~$  hdfs dfs -cat  mydataset/customer.csv | wc -l
40

103 年大專校院名錄檔

## wget下載資料
bigred@dta1:~$ wget --no-check-certificate https://stats.moe.gov.tw/files/school/103/u1_new.txt
--2022-04-29 10:38:05--  https://stats.moe.gov.tw/files/school/103/u1_new.txt
Resolving stats.moe.gov.tw (stats.moe.gov.tw)... 140.111.34.86
Connecting to stats.moe.gov.tw (stats.moe.gov.tw)|140.111.34.86|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 26986 (26K) [text/plain]
Saving to: 'u1_new.txt'

u1_new.txt                           100%[====================================================================>]  26.35K  --.-KB/s    in 0.02s

2022-04-29 10:38:05 (1.42 MB/s) - 'u1_new.txt' saved [26986/26986]

## file -bi 檢查檔案格式
bigred@dta1:~$ file -bi u1_new.txt
text/plain; charset=utf-16le

## 因為linux檔案系統是utf-8編碼,所以utf-16看到的是亂碼
bigred@dta1:~$ head -n 3 u1_new.txt
T3x[t^^'\!hb

T1z     0W@W    q       }@W     Ԛ|%R
轉換資料格式
bigred@dta1:~$ iconv -f utf-16le -t utf8 u1_new.txt >103u.txt

顯示檔案內容
bigred@dta1:~$ head -n 10 103u.txt
103學年度大專校院名錄

代碼    學校名稱        縣市名稱        地址    電話    網址    體系別
0001    國立政治大學    [38]臺北市      [116]臺北市文山區指南路二段64號 (02)29393091    http://www.nccu.edu.tw  [1]一般
0002    國立清華大學    [18]新竹市      [300]新竹市東區光復路二段101號  (03)5715131     http://www.nthu.edu.tw  [1]一般
0003    國立臺灣大學    [33]臺北市      [106]臺北市大安區羅斯福路四段1號        (02)33663366    http://www.ntu.edu.tw   [1]一般
0004    國立臺灣師範大學        [33]臺北市      [106]臺北市大安區和平東路一段162號      (02)77341111    http://www.ntnu.edu.tw  [3]師範
0005    國立成功大學    [21]臺南市      [701]臺南市東區大學路1號        (06)2757575     http://www.ncku.edu.tw  [1]一般
0006    國立中興大學    [19]臺中市      [402]臺中市南區國光路250號      (04)22873181    http://www.nchu.edu.tw  [1]一般
0007    國立交通大學    [18]新竹市      [300]新竹市東區大學路1001號     (03)5712121     http://www.nctu.edu.tw  [1]一般

bigred@dta1:~$ hdfs dfs -put 103u.txt mydataset/103u.txt
bigred@dta1:~$ hdfs dfs -ls  mydataset
Found 4 items
-rw-r--r--   2 bigred bigboss      20807 2022-04-29 10:45 mydataset/103u.txt
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:28 mydataset/TW
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:25 mydataset/US
-rw-r--r--   2 bigred bigboss       1390 2022-04-29 10:36 mydataset/customer.csv

練習

1.先建立以下文字檔並上載至 HDFS 檔案系統 $ echo “224.2.2.2 ICRT” > radio.txt $ hdfs dfs -put radio.txt mydataset/TW/

請將 “224.1.1.1 FM989” 這行字串增加到,mydataset/TW/radio.txt 檔案的開頭

答案:

bigred@dta1:~$ nano radio.txt
bigred@dta1:~$ hdfs dfs -put -f radio.txt mydataset/TW

只能在linux系統修改檔案內容,因為==Hadoop被設計出來就是要處理raw data的資料,所以不能在HDFS檔案系統裡面做修改,所以只能在linux檔案系統修改後,用hdfs dfs -put -f 去覆蓋HDFS檔案系統裡面的檔案==


HDFS 協同作業系統

  • HDFS 的誕生之初,就是提供給多人使用的環境
  • 當初是由哪個使用者格式化與部署 HDFS,控制權就在那位使用者上
  • 新增使用者流程
    • 在 Linux 環境下建立使用者
    • 於 HDFS /user 新建對應的使用者家目錄
    • 將權限與群組轉移至對應使用者

實作:

dta1 終端機, 建立兩個帳號rbean和gbean

bigred@dta1:~$ echo -e "rbean\nrbean" | sudo adduser -h /home/rbean -s /bin/bash rbean
Changing password for rbean
New password:
Bad password: too short
Retype password:
passwd: password for rbean changed by root

bigred@dta1:~$ echo -e "gbean\ngbean" | sudo adduser -h /home/gbean -s /bin/bash gbean
Changing password for gbean
New password:
Bad password: too short
Retype password:
passwd: password for gbean changed by root

如何檢查帳號有沒有建立成功

bigred@dta1:~$ tail -n 5 /etc/passwd
qemu:x:36:34:Linux User,,,:/home/qemu:/sbin/nologin
openvpn:x:101:103:openvpn:/dev/null:/sbin/nologin
utmp:x:102:406:utmp:/home/utmp:/bin/false
rbean:x:1002:1002:Linux User,,,:/home/rbean:/bin/bash
gbean:x:1003:1003:Linux User,,,:/home/gbean:/bin/bash
## /bin/bash 代表這個使用者是使用重裝貝殼,
## 如果是使用sh簡易貝殼,沒辦法執行mkdir -p AAA/{bb,cc},不支援左右大括弧

bigred@dta1:~$ ls -l /home
total 16
drwxr-sr-x 10 bigred bigred 4096 Apr 29 10:48 bigred
drwxr-sr-x  2 gbean  gbean  4096 Apr 29 11:16 gbean
drwxr-sr-x  2 qemu   kvm    4096 Sep  5  2020 qemu
drwxr-sr-x  2 rbean  rbean  4096 Apr 29 11:16 rbean

哪個帳號 format HDFS,這帳號就會成為Hadoop檔案系統的管理者 ,而非root! 我們一開始是用bigred帳號format HDFS,所以HDFS檔案系統的管理者就是bigred !

bigred@dta1:~$ hdfs dfs -ls /user
Found 1 items
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:13 /user/bigred

##建立使用者在HDFS檔案系統的家目錄
bigred@dta1:~$ hdfs dfs -mkdir -p /user/{bigred,rbean,gbean}

## 更改rbean他在HDFS檔案系統家目錄的權限
bigred@dta1:~$ hdfs dfs -chown rbean:rbean /user/rbean

## 更改gbean他在HDFS檔案系統家目錄的權限
bigred@dta1:~$ hdfs dfs -chown gbean:gbean /user/gbean

bigred@dta1:~$ hdfs dfs -ls /user
Found 3 items
drwxr-xr-x   - bigred bigboss          0 2022-04-29 10:13 /user/bigred
drwxr-xr-x   - gbean  gbean            0 2022-04-29 11:31 /user/gbean
drwxr-xr-x   - rbean  rbean            0 2022-04-29 11:31 /user/rbean

補充練習: 在練習一個ybean,用另一個命令提示字元登入ybean

先在bigred執行

bigred@dta1:~$ echo -e "ybean\nybean" | sudo adduser -h /home/ybean -s /bin/bash ybean
Changing password for ybean
New password:
Bad password: too short
Retype password:
passwd: password for ybean changed by root

用另一個命令提示字元登入ybean

build derby database ... ok
ybean@dta1:~$ hdfs dfs -mkdir mydata
mkdir: `mydata': No such file or directory

ybean@dta1:~$ hdfs dfs -ls
ls: `.': No such file or directory

ybean@dta1:~$ hdfs dfs -ls /
Found 2 items
drwxrwxrwx   - bigred bigboss          0 2022-04-27 15:26 /tmp
drwxr-xr-x   - bigred bigboss          0 2022-04-29 11:31 /user

ybean@dta1:~$ 

再回到bigred

bigred@dta1:~$ hdfs dfs -mkdir -p /user/ybean
bigred@dta1:~$ hdfs dfs -chown ybean:ybean /user/ybean

再回到ybean

ybean@dta1:~$ hdfs dfs -ls
ybean@dta1:~$ hdfs dfs -mkdir mydataset
ybean@dta1:~$ pig 2>/dev/null
grunt> pwd
hdfs://dtm1:8020/user/ybean
grunt> ls
hdfs://dtm1:8020/user/ybean/mydataset   <dir>
grunt> quit

練習結束


透過bigred使用者,在HDFS檔案系統的根目錄,建立dataset

bigred@dta1:~$ hdfs dfs -mkdir /dataset

bigred@dta1:~$ hdfs dfs -put mycsv/customer.csv /dataset

在另一個終端機,登入rbean

Welcome to DT Platform Version 21.08 (Alpine Linux : 3.15.4)
IP : 192.168.61.3

build derby database ... ok

rbean@dta1:~$  hdfs dfs -ls /dataset
Found 1 items
-rw-r--r--   2 bigred bigboss        695 2022-04-29 13:02 /dataset/customer.csv

rbean@dta1:~$ hdfs dfs -rm /dataset/customer.csv
rm: Permission denied: user=rbean, access=WRITE, inode="/dataset":bigred:bigboss:drwxr-xr-x

rbean@dta1:~$ pig -e 'pwd'  2>/dev/null
hdfs://dtm1:8020/user/rbean

rbean@dta1:~$ hdfs dfs -mkdir mydata

rbean@dta1:~$ hdfs dfs -ls /user/rbean
Found 1 items
drwxr-xr-x   - rbean rbean          0 2022-04-29 13:10 /user/rbean/mydata

rbean@dta1:~$ hdfs dfs -cp /dataset/customer.csv  mydata/

rbean@dta1:~$ hdfs dfs -ls  mydata/
Found 1 items
-rw-r--r--   2 rbean rbean        695 2022-04-29 13:13 mydata/customer.csv

rbean@dta1:~$ hdfs dfs -rm mydata/customer.csv
Deleted mydata/customer.csv

rbean@dta1:~$ hdfs dfs -rm -r mydata/
Deleted mydata
bigred@dta1:~$ lake.schema
/raw/ (bigred:bigboss,755)      #放原始資料
/elt/ (bigred:bigboss,755)      #過濾程式
/dataset/ existed               #過濾後的資料
/apps/ (bigred:bigboss,755)     #application
/metadata/ (bigred:bigboss,755) #資料庫的schdma宣告檔
/tmp/hive created (Jupyter)     #
/tmp (777)                      #跑YARN一定會放在/tmp,要設定成 777 權限,YARN 才能使用

執行完成

設定 HDFS Access Control List

$ hdfs getconf -confKey dfs.namenode.acls.enabled

true

#檢查Access Control有沒有啟動

#設定rbean在HDFS檔案系統裡的/apps目錄裡面擁有最高權限
# -setfacl 可以針對某資料夾修改特定對象的權限
bigred@dta1:~$ hdfs dfs -setfacl -m user:rbean:rwx  /apps/

#檢查
bigred@dta1:~$ hdfs dfs -getfacl /apps
# file: /apps
# owner: bigred
# group: bigboss
user::rwx
user:rbean:rwx
group::r-x
mask::rwx
other::r-x

看見 HDFS 底層運作

HDFS 系統資訊

在資料管理師bigred執行

bigred@dta1:~$  hdfs dfsadmin -report
Configured Capacity: 1578782097408 (1.44 TB)
Present Capacity: 1488026882048 (1.35 TB)
DFS Remaining: 1488025145344 (1.35 TB)
DFS Used: 1736704 (1.66 MB)
DFS Used%: 0.00%
Under replicated blocks: 0
Blocks with corrupt replicas: 0
Missing blocks: 0
Missing blocks (with replication factor 1): 0
Pending deletion blocks: 0

-------------------------------------------------
Live datanodes (3):

Name: 192.168.61.6:50010 (dtw1)
Hostname: dtw1
Decommission Status : Normal
Configured Capacity: 526260699136 (490.12 GB)
DFS Used: 729088 (712 KB)
Non DFS Used: 3538210816 (3.30 GB)
DFS Remaining: 495917797376 (461.86 GB)
DFS Used%: 0.00%
DFS Remaining%: 94.23%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Fri Apr 29 15:16:12 CST 2022
Last Block Report: Fri Apr 29 13:28:13 CST 2022


Name: 192.168.61.7:50010 (dtw2)
Hostname: dtw2
Decommission Status : Normal
Configured Capacity: 526260699136 (490.12 GB)
DFS Used: 573440 (560 KB)
Non DFS Used: 3538227200 (3.30 GB)
DFS Remaining: 495917936640 (461.86 GB)
DFS Used%: 0.00%
DFS Remaining%: 94.23%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Fri Apr 29 15:16:13 CST 2022
Last Block Report: Fri Apr 29 13:33:14 CST 2022


Name: 192.168.61.8:50010 (dtw3)
Hostname: dtw3
Decommission Status : Normal
Configured Capacity: 526260699136 (490.12 GB)
DFS Used: 434176 (424 KB)
Non DFS Used: 3266891776 (3.04 GB)
DFS Remaining: 496189411328 (462.11 GB)
DFS Used%: 0.00%
DFS Remaining%: 94.29%
Configured Cache Capacity: 0 (0 B)
Cache Used: 0 (0 B)
Cache Remaining: 0 (0 B)
Cache Used%: 100.00%
Cache Remaining%: 0.00%
Xceivers: 1
Last contact: Fri Apr 29 15:16:11 CST 2022
Last Block Report: Fri Apr 29 11:22:13 CST 2022

HDFS 分散檔案系統 - 寫入檔案

File.txt是使用wget抓下來的

hdfs dfs -put File.txt /dataset 檔案要丟到HDFS檔案系統裡面,一定要在本機被切割,每128M被切一塊,切好後才能傳到HDFS

以圖片有三個區塊(block)為例,File.txt的檔案大小為 256 < 大小 <= 384

Client透過網路連到dtm1和Name Node這個Java程式說話, 請Name Node,告訴我,我的3個區塊的資料要存到哪裡?

他說,你的第一個block,要存在第一機櫃(Rack)的第一個server的Data Node,同時也要存在第五個機櫃的第五和第六個server的Data Node

代表1個block要存3個機器,3個block就會有可能用到9台機器

以我們上課的環境為例,dtw1,dtw2和dtw3分別要存1個block的資料

Hadoop 實際使用觀念

  • 在建立系統時,要優先確保寫入的資料大小,並以此為基礎乘以三倍準備硬碟
  • 絕對不行減少寫入的 Block 冗余,不要依靠神明系統
  • 目標要有 10TB 要存放,因為每個 Block 會需要存放在三台 Data Node 至少需要 30TB
  • client端(dta1)告知Name Node要存幾個block

檔案要上傳到HDFS前會在Client進行切割 Client向Name Node詢問到存放位置後,會將資料上傳 假如獲得的位置是Blk A到Data Node 1、5、6,則會先將Blk A傳到Data Node 1,Data Node 1接收到"64k"後會將檔案往後傳到Data Node 5,Data Node 5接收到64k後會將檔案往後傳到Data Node 6


HDFS 分散式檔案系統 - 讀取檔案

client跟Name Node說,請告訴我result.txt這個檔案的所有block的locations的清單, Name Node的功能就是決定block存在哪裡,所以Name Node會把以下的清單內容:

block A = 1,5,6  ##意思就是說分別存在3台有Data Node的主機
block B = 8,1,2
block C = 5,8,9

回報給client,client收到資料後,就會自己去讀取資料,而不是Name Node去讀取.

這裡產生一個問題,client要去哪讀資料?

答:把Name Node給的清單抓第一個順位,意思就是說block A的區塊,他會找第一個機器要,block B的區塊,他會找第八台機器的Data Node要來讀,block C的區塊,他會找第五台機器的Data Node讀取

client端會到這3台電腦,同時讀取這3塊資料,把這3個block的資料都讀回來,這時候我們就會有result.txt的所有內容

如果一個block掛了,其他機器的block就會頂上.

  • 如果client端要讀取10T的檔案,clent能成功嗎?

    • client端是工程師在用的電腦,10TB的資料就要有10TB的硬碟,一台個人電腦要有10TB的硬碟,總價約落在3萬到4萬,公司是不會配給這魔好的設備,而且讀取完10TB的資料還要分析,記憶體也要有一定的水準,所以以上的架構檔案不能太大,不然很難成行
  • 當有3個人同時要讀取result.txt,Name Node給的block位置會一樣嗎?

    • 不一樣,當第一個人要讀取result.txt時,Name Node會給的清單第一順位是1,8,5,當第二個人要讀取result.txt時,Name Node會給的清單第一順位是5,1,8,當第三個人要讀取result.txt時,Name Node會給的清單第一順位是6,2,9,當第四個人要讀取result.txt時,Name Node會給的清單第一順位是1,8,5,以上依此類推,這個運作模式就是平衡負載(round robin)

HDFS檔案系統有容錯,有平衡負載,write once(寫一次) read many(多人讀取)


Name Node 目錄內容

nn,為 Name Node (Java程式)所使用的目錄,來儲存它要管理的資料
bigred@dta1:~$ ssh dtm1  tree  nn
nn
├── current
│   ├── VERSION
│   ├── edits_0000000000000000001-0000000000000000009
│   ├── edits_0000000000000000010-0000000000000000011
│   ├── edits_inprogress_0000000000000000012
│   ├── fsimage_0000000000000000000
│   ├── fsimage_0000000000000000000.md5
│   └── seen_txid
└── in_use.lock

1 directory, 10 files

fsimage 稱之為 Meta Data 是目錄和檔案的屬性資料(包含目錄的擁有者、使用者權限、檔案紀錄、檔案的大小等) 針對 HDFS 所下的指令紀錄 » 會記錄在 edits_inprogress_*

HDFS檔案系統運作架構的資訊

bigred@dta1:~$ ssh dtm1  cat  nn/current/VERSION
#Mon May 02 10:12:02 CST 2022
namespaceID=985719912   ## Hdfs的身份證號碼,namespace為一個運作空間
clusterID=cute          ## cluster 聯邦,意思就是說每一個同學都有自己一套Hadoop系統、一套HDFS檔案系統???
cTime=1651044227924     ## 紀錄創立時間,以格林威治時間(1924 年 2 月 5 日)為起點,用秒數表達,紀錄儲存的形式
storageType=NAME_NODE   ## Name Node在處理
blockpoolID=BP-1851199489-192.168.61.4-1651044227924  ##這個是給Data Node識別用的一個ID
layoutVersion=-63       ##二進位在表示版本代號

Data Node 目錄內容

同樣的Data Node可以幫多台Name Node服務

bigred@dta1:~$ ssh dtw1 tree dn
dn
├── current
│   ├── BP-1851199489-192.168.61.4-1651044227924 ## 192.168.61.4 為dtm1的IP位址,這個目錄的意思就是說,他會幫忙在dtm1上的Name Node存取資料
│   │   ├── current
│   │   │   ├── dfsUsed
│   │   │   ├── finalized
│   │   │   │   └── subdir0
│   │   │   │       └── subdir0
│   │   │   │           ├── blk_1073741829
│   │   │   │           ├── blk_1073741829_1009.meta
│   │   │   │           ├── blk_1073741830
│   │   │   │           ├── blk_1073741830_1010.meta
│   │   │   │           ├── blk_1073741831
│   │   │   │           └── blk_1073741831_1011.meta
│   │   │   ├── rbw
│   │   │   └── VERSION
│   │   ├── scanner.cursor
│   │   └── tmp
│   └── VERSION
└── in_use.lock

由blk_1073741829這個檔案名稱可以得知,blk_1~9,總共有10位數,代表Hadoop總共最大可以儲存的檔案大小為9999999999*128MB = 1280PB

HDFS檔案系統由Name Node以及Data Node來做整個檔案系統的資料處理, - Name Node他的重要資訊存在nn目錄 - Data Node的檔案資料存在多台dtw1、dtw2和dtw3裡面的dn目錄區


檢視 NameNode MetaData

Meta Data是HDFS檔案系統的整個目錄以及檔案的重要資訊 » fsimage檔

在看Meta Data之前,首先要先檢查HDFS有沒有啟動

bigred@dta1:~$ hls
pls start HDFS first or fomathdfs
## 如果出現這行,代表HDFS檔案系統沒有啟動

bigred@dta1:~$ starthdfs          ## 啟動HDFS檔案系統
dtm1: Name Node Started
dtm1: Secondary Name Node started
dtw1: Data Node started
dtw2: Data Node started
dtw3: Data Node started

先確認目前擁有的資料

bigred@dta1:~$ ssh dtw1 tree dn
dn
├── current
│   ├── BP-1851199489-192.168.61.4-1651044227924
│   │   ├── current
│   │   │   ├── VERSION
│   │   │   ├── dfsUsed
│   │   │   ├── finalized
│   │   │   │   └── subdir0
│   │   │   │       └── subdir0
│   │   │   │           ├── blk_1073741836
│   │   │   │           ├── blk_1073741836_1012.meta
│   │   │   │           ├── blk_1073741837
│   │   │   │           ├── blk_1073741837_1013.meta
│   │   │   │           ├── blk_1073741856
│   │   │   │           ├── blk_1073741856_1032.meta
│   │   │   │           ├── blk_1073741857
│   │   │   │           ├── blk_1073741857_1033.meta
│   │   │   │           ├── blk_1073741864
│   │   │   │           ├── blk_1073741864_1040.meta
│   │   │   │           ├── blk_1073741866
│   │   │   │           ├── blk_1073741866_1042.meta
│   │   │   │           ├── blk_1073741867
│   │   │   │           ├── blk_1073741867_1044.meta
│   │   │   │           ├── blk_1073741868
│   │   │   │           ├── blk_1073741868_1045.meta
│   │   │   │           ├── blk_1073741870
│   │   │   │           ├── blk_1073741870_1047.meta
│   │   │   │           ├── blk_1073741873
│   │   │   │           ├── blk_1073741873_1050.meta
│   │   │   │           ├── blk_1073741874
│   │   │   │           ├── blk_1073741874_1051.meta
│   │   │   │           ├── blk_1073741875
│   │   │   │           ├── blk_1073741875_1052.meta
│   │   │   │           ├── blk_1073741876
│   │   │   │           └── blk_1073741876_1053.meta
│   │   │   └── rbw
│   │   ├── scanner.cursor
│   │   └── tmp
│   └── VERSION
└── in_use.lock

8 directories, 31 files
bigred@dta1:~$
bigred@dta1:~$
bigred@dta1:~$
bigred@dta1:~$
bigred@dta1:~$ hls
[dtm1]
25123 NameNode
25231 SecondaryNameNode

[dtm2]
4540 ResourceManager
4591 JobHistoryServer

[dtw1]
25068 DataNode
5262 NodeManager

[dtw2]
25187 DataNode
5242 NodeManager

[dtw3]
5222 NodeManager
25023 DataNode

bigred@dta1:~$ stopyarn ; stophdfs
dtw1: Node Manager stoped
dtw2: Node Manager stoped
dtw3: Node Manager stoped
dtm2: Job History Server stoped
dtm2: Resource Manager stoped
dtw1: Data Node stoped
dtw2: Data Node stoped
dtw3: Data Node stoped
dtm1: Secondary Name Node stoped
dtm1: Name Node stoped
bigred@dta1:~$ hls
pls start HDFS first or fomathdfs
bigred@dta1:~$ starthdfs
dtm1: Name Node Started
dtm1: Secondary Name Node started
dtw1: Data Node started
dtw2: Data Node started
dtw3: Data Node started
bigred@dta1:~$ ssh dtm1 tree nn
nn
├── current
│   ├── VERSION
│   ├── edits_0000000000000000001-0000000000000000002
......
│   ├── edits_0000000000000000624-0000000000000000625 
│   ├── edits_inprogress_0000000000000000626
│   ├── fsimage_0000000000000000622
│   ├── fsimage_0000000000000000622.md5
│   ├── fsimage_0000000000000000623
│   ├── fsimage_0000000000000000623.md5 ## 目前最新的資料是625
│   └── seen_txid
└── in_use.lock

1 directory, 81 files

立即更新 fsimage,讓Hdfs檔案系統進入安全模式

安全模式:只能讀取已存在HDFS檔案系統中的檔案,不能新增、修改和刪除資料。

bigred@dta1:~$ hdfs dfsadmin -safemode enter
Safe mode is ON

會立即將記憶體中的資料寫入一個新的 fsimage 檔中

bigred@dta1:~$ hdfs dfsadmin -saveNamespace
Save namespace successful

檢查 最新的fsimage馬上變627

bigred@dta1:~$ ssh dtm1  tree  nn
nn
├── current
│   ├── VERSION
│   ├── edits_0000000000000000001-0000000000000000002
......
│   ├── edits_0000000000000000626-0000000000000000627 
│   ├── edits_inprogress_0000000000000000628
│   ├── fsimage_0000000000000000623
│   ├── fsimage_0000000000000000623.md5
│   ├── fsimage_0000000000000000627
│   ├── fsimage_0000000000000000627.md5  ## 最新的馬上變627
│   └── seen_txid
└── in_use.lock

1 directory, 82 files

離開安全模式

bigred@dta1:~$ hdfs dfsadmin -safemode leave
Safe mode is OFF

取出 fsimage 檔, 並將之轉換成 csv 格式檔

bigred@dta1:~$ hdfs dfsadmin -fetchImage  /tmp/
## -fetchImage , fetch是抓取的意思,也就是說把剛剛產生最新的fsimage檔案,拷貝到/tmp目錄
## 其實也可以用linux檔案系統的cp命令,但檔案名稱太長太麻煩了。

bigred@dta1:~$ dir /tmp/fsimage*
-rw-r--r-- 1 bigred bigred 5.0K May  2 11:29 /tmp/fsimage.csv
-rw-r--r-- 1 bigred bigred 3.7K May  3 00:07 /tmp/fsimage_0000000000000000627

HDFS Offline Image Viewer

bigred@dta1:~$ hdfs oiv -i /tmp/fsimage_0000000000000000627 -o /tmp/fsimage.csv -p Delimited -delimiter ","

## oiv這個指令是把"/tmp/fsimage_0000000000000000562"這個二進位檔案輸出成CSV文字檔,欄位之間用","做分割

bigred@dta1:~$ head -n 10 /tmp/fsimage2.csv
Path,Replication,ModificationTime,AccessTime,PreferredBlockSize,BlocksCount,FileSize,NSQUOTA,DSQUOTA,Permission,UserName,GroupName
/,0,2022-04-29 14:28,1970-01-01 08:00,0,0,0,9223372036854775807,-1,drwxr-xr-x,bigred,bigboss
/tmp,0,2022-05-02 15:48,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwx,bigred,bigboss
/tmp/hadoop-yarn,0,2022-04-27 15:25,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwx,bigred,bigboss
/tmp/hadoop-yarn/staging,0,2022-04-27 15:26,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwx,bigred,bigboss
/tmp/hadoop-yarn/staging/history,0,2022-04-27 15:25,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwx,bigred,bigboss
/tmp/hadoop-yarn/staging/history/done,0,2022-04-27 15:28,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwx,bigred,bigboss
/tmp/hadoop-yarn/staging/history/done_intermediate,0,2022-04-27 15:26,1970-01-01 08:00,0,0,0,-1,-1,drwxrwxrwt,bigred,bigboss
/user,0,2022-04-29 15:01,1970-01-01 08:00,0,0,0,-1,-1,drwxr-xr-x,bigred,bigboss
/user/bigred,0,2022-04-29 10:13,1970-01-01 08:00,0,0,0,-1,-1,drwxr-xr-x,bigred,bigboss

## 以上就是meta data裡面的內容

練習

hdfs dfs -touchz /tmp/zzz 用-touchz命令在/tmp中產生zzz檔 要在fsimage.csv中看到zzz的屬性

答:

在Hdfs檔案系統新增/tmp/zzz
bigred@dta1:~$ hdfs dfs -touchz /tmp/zzz

進入安全模式
bigred@dta1:~$ hdfs dfsadmin -safemode enter
Safe mode is ON

立即將記憶體中剛剛新增的空檔案寫入一個新的 fsimage 檔中
bigred@dta1:~$ hdfs dfsadmin -saveNamespace
Save namespace successful

離開安全模式
bigred@dta1:~$ hdfs dfsadmin -safemode leave
Safe mode is OFF

取出 剛剛新增的fsimage 檔,放到/tmp目錄下
bigred@dta1:~$ hdfs dfsadmin -fetchImage  /tmp/

檢查有沒有新增一個fsimage 檔案
bigred@dta1:~$  dir /tmp/fsimage*
-rw-r--r-- 1 bigred bigred 5.0K May  2 11:29 /tmp/fsimage.csv
-rw-r--r-- 1 bigred bigred 3.4K May  2 11:26 /tmp/fsimage_0000000000000000562
-rw-r--r-- 1 bigred bigred 3.4K May  2 11:41 /tmp/fsimage_0000000000000000566

轉換成 csv 格式檔
bigred@dta1:~$ hdfs oiv -i /tmp/fsimage_0000000000000000566 -o /tmp/fsimage1.csv -p Delimited -delimiter ","

檢查更新內容
bigred@dta1:~$ cat /tmp/fsimage1.csv
...
/tmp/zzz,2,2022-05-02 11:39,2022-05-02 11:39,134217728,0,0,0,0,-rw-r--r--,bigred,bigboss

edits檔案會紀錄Transcation的動作

bigred@dtm1:~$ tree -h nn/current
nn/current
├── [ 180]  VERSION
...
├── [  42]  edits_0000000000000000567-0000000000000000568
├── [1.0M]  edits_inprogress_0000000000000000569 ##要看這個檔案
├── [3.3K]  fsimage_0000000000000000562
├── [  62]  fsimage_0000000000000000562.md5
├── [3.4K]  fsimage_0000000000000000566
├── [  62]  fsimage_0000000000000000566.md5
└── [   4]  seen_txid

0 directories, 66 files
 hdfs oev -i /home/bigred/nn/current/edits_inprogress_0000000000000000569 -o edits.xml -p XML

core-site.xml

bigred@dta1:~$ sudo nano /opt/hadoop-2.10.1/etc/hadoop/core-site.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
 <property>
    <name>fs.defaultFS</name>
    <value>hdfs://dtm1:8020</value>
 </property>
 <property>
    <name>fs.default.name</name>
    <value>hdfs://dtm1:8020</value>
 </property>
 <property>
    <name>io.compression.codecs</name>
    
## 宣告name node在哪,有兩種名稱的宣告,
## fs.defaultFS: 舊的親朋好友專案習慣使用此名稱
## fs.default.name: 新的親朋好友專案習慣使用此名稱
## 以上都是宣告Hdfs他在dtm1的機器,port號是:8020

<value>org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.GzipCodec</val> </property>  
## 上面這條是hdfs裡面有哪些演算法

 <property>
    <name>hadoop.user.group.static.mapping.overrides</name>
    <value>hbase=bigboss;rbean=soup;gbean=soup,rice;ybean=rice</value>
 </property>

## 這邊的宣告與linux檔案系統不同

hdfs-site.xml

bigred@dta1:~$ sudo nano /opt/hadoop-2.10.1/etc/hadoop/hdfs-site.xml

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
  <property>
    <name>dfs.replication</name>
    <value>2</value>                           ## 2代表block會儲存兩份
  </property>
  <property>
    <name>dfs.namenode.name.dir</name>
    <value>file:/home/bigred/nn</value>
  </property>
  <property>
    <name>dfs.datanode.data.dir</name>
    <value>file:/home/bigred/dn</value>
  </property>
  <property>
    <name>dfs.permissions.superusergroup</name>
    <value>bigboss</value>                      ## 具有管理權限的群組
  </property>

  <property>
    <name>dfs.namenode.acls.enabled</name>
    <value>true</value>
  </property>

YARN 分散運算系統運作圖

啟動yarn之後(startyarn) 每個node manager會回報給resource manager他在執行的那台電腦所擁有的運算資源(CPU和記憶體)

resource manager應該要有總量的運算數字出來


檢視 YARN 總量運算資源

在 dta1 執行以下命令

bigred@dta1:~$ curl -s http://dtm2:8088/ws/v1/cluster/metrics | jq | grep -E "totalMB|totalVirtualCores"
    "totalMB": 6144,
    "totalVirtualCores": 6,

curl,使用 HTTP Protocol 獲取資料 -s,Silent mode 安靜模式 metrics (存放運算資源總數) jq,全名jason query,處理 JSON 文件的工具,query是查詢的意思 grep -E,多項目搜尋(模式為左右擴展) [重點] YARN 系統內定每部 Node Manager 的記憶體為 8G, CPU 為 8 Core DTM2:8088執行甚麼JAVA程式 答案是RESOURCE MANAGER/ 另一個JAVA程式是JOB SERVER

使用 curl -s 指令去索取 dtm2 機器中的 metrics 文件(存放運算資源總數),利用 jq 指令處理,把JSON格式化成人在看的資料,交由 grep -E 將 totalMB、totalVirtualCores 這兩個項目呈現到螢幕上

設定單一 Node Manager 運算資源

bigred@dta1:~$ cat vmalpdt/hdp210/conf/hadoop-2.10.1/yarn-site.xml
<?xml version="1.0"?>
<configuration>
......
 <property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>2048</value>    ##設定node manager他的運算資源,記憶體只能用2G
  </property>
  <property>
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>2</value>        ##設定node manager他的運算資源,CPU兩個核心
  </property>
.......

這個設定檔要存在哪幾台機器? 以上的設定檔,是給dtw1,dtw2,dtw3裡面的node manager Java程式讀取的

$ cat vmalpdt/hdp210/conf/hadoop-2.10.1/yarn-site.xml
........
  <property>
    <name>yarn.scheduler.minimum-allocation-mb</name>
    <value>384</value>  ## YARN系統裡每一個Java程式能夠使用的記憶體大小最少384mb
  </property>
  <property>
    <name>yarn.scheduler.maximum-allocation-mb</name>
    <value>896</value>  ## YARN系統裡每一個Java程式能夠使用的記憶體大小最多896mb
  </property>
  <property>
    <name>yarn.scheduler.minimum-allocation-vcores</name>
    <value>1</value>
  </property>
  <property>
    <name>yarn.scheduler.maximum-allocation-vcores</name>
    <value>1</value>
  </property>
..........

Scheduler 的功能是 Resource Manager 做的,所以Scheduler = Resource Manager ,而Resource Manager在dtm2上面執行

因為resource manager他已經得到整個運算資源的總量數字(有多少記憶體可以用,有多少CPU可以用),他會來開始管控,我們的resource manager真正最主要的工作是幫我們執行我們寫的Java程式,YARN他是一個分散式運算系統,它負責要來跑我們要寫的程式,他要來執行我們的程式,所以對要執行的程式所需要用到的記憶體和CPU做使用的上限與下限設定。

YARN這個運算系統,他現在有一個運算總量(有多少記憶體可以用、有多少CPU可以用),當他幫我們跑程式時,我們的程式記憶體最多896,最少384mb,CPU一核心

windows系統只要一啟動,就會執行很多服務(程式),這些服務會共用電腦的CPU,所以CPU越好,程式跑得越快

練習:設定記憶體總量: 9216 mb和 CPU 總量: 6c

首先更改yarn-site.xml設定檔
bigred@dta1:~$ nano vmalpdt/hdp210/conf/hadoop-2.10.1/yarn-site.xml
...
  <property>
    <name>yarn.nodemanager.resource.memory-mb</name>
    <value>3072</value> 
  </property>
  <property>
    <name>yarn.nodemanager.resource.cpu-vcores</name>
    <value>2</value>
  </property>
...

停止yarn運算系統
bigred@dta1:~$ stopyarn
dtw1: Node Manager stoped
dtw2: Node Manager stoped
dtw3: Node Manager stoped
dtm2: Job History Server stoped
dtm2: Resource Manager stoped

把新的yarn-site.xml的設定檔拷貝到每台機器
bigred@dta1:~$ dtconf 210
dta1: apache-hive-3.1.3-bin config ok
dta1: apache-zookeeper-3.6.3-bin config ok
dta1: hadoop-2.10.1 config ok
dta1: hbase-2.4.11 config ok
dta1: spark-3.2.1-bin-hadoop2.7 config ok
dta1 /etc/profile ok

dtm1: apache-hive-3.1.3-bin config ok
dtm1: apache-zookeeper-3.6.3-bin config ok
dtm1: hadoop-2.10.1 config ok
dtm1: hbase-2.4.11 config ok
dtm1: spark-3.2.1-bin-hadoop2.7 config ok
dtm1 /etc/profile ok

dtm2: apache-hive-3.1.3-bin config ok
dtm2: apache-zookeeper-3.6.3-bin config ok
dtm2: hadoop-2.10.1 config ok
dtm2: hbase-2.4.11 config ok
dtm2: spark-3.2.1-bin-hadoop2.7 config ok
dtm2 /etc/profile ok

dtw1: apache-hive-3.1.3-bin config ok
dtw1: apache-zookeeper-3.6.3-bin config ok
dtw1: hadoop-2.10.1 config ok
dtw1: hbase-2.4.11 config ok
dtw1: spark-3.2.1-bin-hadoop2.7 config ok
dtw1 /etc/profile ok

dtw2: apache-hive-3.1.3-bin config ok
dtw2: apache-zookeeper-3.6.3-bin config ok
dtw2: hadoop-2.10.1 config ok
dtw2: hbase-2.4.11 config ok
dtw2: spark-3.2.1-bin-hadoop2.7 config ok
dtw2 /etc/profile ok

dtw3: apache-hive-3.1.3-bin config ok
dtw3: apache-zookeeper-3.6.3-bin config ok
dtw3: hadoop-2.10.1 config ok
dtw3: hbase-2.4.11 config ok
dtw3: spark-3.2.1-bin-hadoop2.7 config ok
dtw3 /etc/profile ok

啟動YARN運算系統
bigred@dta1:~$ startyarn
dtm2: Resource Manager started
dtm2: Job History Server started
dtw1: Node Manager started
dtw2: Node Manager started
dtw3: Node Manager started


檢查運算資源總量
bigred@dta1:~$ curl -s http://dtm2:8088/ws/v1/cluster/metrics | jq | grep -E "totalMB|totalVirtualCores"
    "totalMB": 9216,
    "totalVirtualCores": 6,

MapReduce 資料處理引擎

MapReduce要啟動有一個必要條件,給他一個程式才能跑,程式只要一跑完,MapReduce就會關閉

Mapreduce 叢集運作架構圖

MapReduce處理1GB的檔案(=1024MB) 1024MB/128MB(Block上限)=8個blocks 又每個block存3份,因此3台Work Node都有8個blocks

YARN會平均在Work Node上啟動8個Map程式,做平行處理 Node Manager會告訴Resource Manager其運算資源量(CPU,Memory)

dtw1處理blk1,blk2,blk3 (3個MAP程式) dtw2處理blk4,blk5,blk6 (3個MAP程式) dtw3處理blk7,blk8 (2個MAP程式)

==有幾個block就會有幾個Map程式==

一個Map程式會對一個block的資料做擷取和過濾的動作,程式跑完會output結果到硬碟裡面(小白區塊),這時候MapReduce就會啟動Shuffle這個program(由Hadoop團隊寫的),透過網路傳到其中一台Work Node中的Shuffle接收做Merge分類和排序(大白區塊),完了以後再經過Reduce處理分析,最後會把分析完的結果存到HDFS檔案系統

yarn系統,可以同時執行的數量越大,就可以一輪處理更多的資料

多個 Block 的好處,可以實現多程式處理相同資料的框架 YARN 要盡可能的將每台 Worker Node 能執行的程式量放到最大,但當多人運作碰上運算瓶頸時,還是會有排隊等待的狀況 3.

  • 一個檔案分成多個 Block 的好處:
    • 可以實現平行運算處理,在一個程式作業的時間內完成所有動作,而不是輪替執行
    • 可以實現多使用者、多程式處理的需求
  • YARN 要盡可能的將每台 Worker Node 能執行的程式量放到最大,但當多人運作碰上運算瓶頸時,還是會有排隊等待的狀況

設定 MapReduce Job 的運算資源

$ cat /opt/hadoop-2.10.1/etc/hadoop/mapred-site.xml
.......... 
   <property>
      <name>mapreduce.reduce.memory.mb</name>
      <value>512</value>  ##
   </property>
   <property>
      <name>mapreduce.reduce.java.opts</name>
      <value>-Xmx384m</value>
   </property>
   <property>
      <name>mapreduce.map.memory.mb</name>
      <value>384</value>
   </property>
   <property>
      <name>mapreduce.map.java.opts</name>
      <value>-Xmx256m</value>
   </property>
........

[註]  一般 reduce 設定為 map 的兩倍。Just make sure you set java.opts to 20-25% less than memory.mb

補充Java程式的介紹

bigred@dta1:~$ yarn  jar  /opt/hadoop-2.10.1/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.10.1.jar pi 2 100000

## *.jar是壓縮檔
## pi 是jar檔裡面的程式
## 2是用兩個map去跑
## 100000是10萬個座標

Java process

bigred@dta1:~$ ssh dtm1 jps           # j代表java,p代表process
49648 Jps
55751 SecondaryNameNode
55641 NameNode


bigred@dta1:~$ ssh dtw2 jps -v        # -v,可以看到java程式的參數

54827 DataNode -Dproc_datanode -Xmx1000m -Djava.library.path=/opt/hadoop-2.10.1/lib/native -Dhadoop.log.dir=/tmp -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/opt/hadoop-2.10.1 -Dhadoop.id.str= -Dhadoop.root.logger=ERROR,console -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/tmp -Dhadoop.log.file=hadoop-bigred-datanode-dtw2.log -Dhadoop.home.dir=/opt/hadoop-2.10.1 -Dhadoop.id.str=bigred -Dhadoop.root.logger=ERROR,console -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Dhadoop.security.logger=INFO,RFAS
## -Dproc_datanode -Xmx1000m -,代表可以使用的記憶體有1G

46395 Jps -Dapplication.home=/usr/lib/jvm/java-1.8-openjdk -Xms8m

95930 NodeManager -Dproc_nodemanager -Xmx1000m -Dhadoop.log.dir=/tmp -Dyarn.log.dir=/tmp -Dhadoop.log.file=yarn-bigred-nodemanager-

dtw2.log -Dyarn.log.file=yarn-bigred-nodemanager-dtw2.log -Dyarn.home.dir=/opt/hadoop-2.10.1 -Dhadoop.home.dir=/opt/hadoop-2.10.1 -Dhadoop.root.logger=INFO,RFA -Dyarn.root.logger=INFO,RFA

#!/bin/bash

for n in dtw1 dtw2 dtw3
do
  ssh $n 'nohup maxjps.log &>/dev/null &'  
  ##nohup,當跑到第一台機器時,執行後面的maxjps.log &>/dev/null &,做完後,
  ##會不中斷第一台的機器連線,跑到第二台機器再次執行nohup maxjps.log &>/dev/null &,
  ##之後依此類推
done

*.zip in HDFS

由於壓縮檔的特性,所以將壓縮檔存入 HDFS 後就不能針對 Block 進行解壓縮

結論:HDFS可以對ZIP檔存檔,但不能在裡面解壓縮

從 data.csv 讀取檔案 » 輸出內部結構為每一個 Block 為 100KB 的壓縮檔案

tags: 資料科技平台