[上課講義](https://hackmd.io/@yillkid/r1f7HrFHc/https%3A%2F%2Fhackmd.io%2F%40yillkid%2FHybR5uFr5) ### Hadoop架構: map Readuce:資料處理 YARN:vm的管理 HDFS:資料儲存 安裝環境 - 我們將在 Ubuntu 22.04 Server 上安裝 Hadoop 建議您安裝在 VirtualBox 上方便課堂上架設多個節點 VirtualBox 參數 (最低要求): - Storage: 20 GB - RAM: 2GB SSH key pair 登入: [使用教學](https://www.digitalocean.com/community/tutorials/how-to-configure-ssh-key-based-authentication-on-a-linux-server) :::warning 說明:因為後面會創造多支線都協助作業,因此改用金鑰的方式做登入,否則每次都會向windos或master請求密碼,造成不便。 原理:先申請金鑰(公鑰與私鑰),將公鑰交給伺服器端保管,當我對資料有需求時,會拿我的公鑰給伺服器確認,伺服器確認後會給予認證,伺服器會給予內容包,最後用私鑰打開內容包,取得資料。 ::: ``` ssh-keygen ```    Hadoop 由 Java 建構而成,因此要先安裝 Java 的執行環境 ``` sudo apt update sudo apt-get upgrade sudo apt install default-jdk ``` 確認你的 Java 版本 ``` java -version ``` 安裝SSH ``` sudo apt install ssh ``` 新增 hadoop user: ``` sudo adduser hadoop ``` 新增 hadoop 為 sudor: ``` sudo visudo ``` 找到root ALL=(ALL) ALL :::success 這一行指的是root這個使用者, 可以在所有的終端機下(第1個ALL), 使用所有人的(第2個ALL), 所有指令(第3個ALL)。 ::: 照此邏輯,如法泡製,依序加上 `hadoop ALL=(ALL) ALL` `%hadoop ALL=(ALL) ALL` 查看是否有開啟sudo權限 `id hadoop` 切換 hadoop user: `su - hadoop` 設定 SSH 金鑰: `ssh-keygen -t rsa` :::success `ssh-keygen` 是一個用於創建 SSH 密鑰的命令。在這個命令中,`-t` 選項用於指定密鑰的類型。在你提供的例子中,`-t rsa` 意味着你想要創建一對 RSA 類型的 SSH 密鑰。 RSA 是一種常見的密鑰類型,用於 SSH 連接和身份驗證。 ::: 設定 SSH 登入權限: `cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys` :::info 這條命令用於將你的 SSH 公鑰添加到 `~/.ssh/authorized_keys` 文件中,這樣你就可以使用相應的私鑰進行 SSH 登錄,而無需輸入密碼。 這個命令的具體作用是將你的 SSH 公鑰文件(通常位於 `~/.ssh/id_rsa.pub`)的內容附加到 `~/.ssh/authorized_keys` 文件的末尾。這樣做的目的是將你的公鑰添加到授權的鍵列表中,以便你可以使用相應的私鑰進行 SSH 登錄。 請注意,如果 `~/.ssh/authorized_keys` 文件不存在,這個命令會創建一個新的文件。如果文件已經存在,則會將公鑰內容附加到現有文件的末尾。 ::: 開啟authorized_keys (640權限) ``` chmod 640 ~/.ssh/authorized_keys ```  PS.r:4 w:2 x:1 `ssh hadoop@192.168.255.141 (應該要免密碼)` 下載 Hadoop `wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.6/hadoop-3.3.6.tar.gz` 解壓縮安裝包 `tar -xzvf hadoop-3.3.6.tar.gz` 將執行檔移動到特定資料夾上 `sudo mv hadoop-3.3.6 /usr/local/hadoop` 執行看看你下載的 Hadoop 是否正常 `/usr/local/hadoop/bin/hadoop version` 正常的output ``` Hadoop 3.3.6 Source code repository https://github.com/apache/hadoop -r abe5358143720085498613d399be3bbf01e0f131 Compiled by ubuntu on 2022-03-20T01:18Z Compiled with protoc 2.5.0 From source with checksum 39bb14faec14b3aa25388a6d7c345fe8 This command was run using /usr/local/hadoop/share/hadoop/common/hadoop-common-3.3.6.jar ``` :::danger 出現以下錯誤:'ERROR: JAVA_HOME is not set and could not be found.' 你需要讓 Hadoop 知道你的 Java 執行環境 1.找出你的 Java 路徑: `readlink -f /usr/bin/java | sed "s:bin/java::"` 2.開啟 ~/.bashrc `vi ~/.bashrc` 在最後加上 ``` export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 export HADOOP_HOME=/usr/local/hadoop/ export HADOOP_INSTALL=$HADOOP_HOME export HADOOP_MAPRED_HOME=$HADOOP_HOME export HADOOP_COMMON_HOME=$HADOOP_HOME export HADOOP_HDFS_HOME=$HADOOP_HOME export HADOOP_YARN_HOME=$HADOOP_HOME export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin export HADOOP_OPTS="-Djava.library.path=$HADOOP_HOME/lib/native" ``` 3.載入環境變數 `source ~/.bashrc` 設定你的 Hadoop 設定檔: `vi $HADOOP_HOME/etc/hadoop/hadoop-env.sh` 加上:`JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64` ::: ### Hadoop 運作模式 - 獨立模式 (Standalone) 只需要一台 host 即可 - 偽分佈模式 (Pseudo-Distributed) 只需要一台 host 即可 - 多機安裝模式 (Fully-Distributed) 需要多個 host 來達到分散 (Distributed) 的效果 ### 獨立模式 (Standalone) 啟動:Standalone(預設) `hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar` 查詢pi的使用語法 `hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi`  使用pi: `hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 16 10000` :::success nMaps (任務數 -samples per task) 這是每個 Map 任務將要處理的樣本數。 增加這個值會提高估算的準確性,但同時也會增加計算的時間。 nSamples (樣本總數 - number of tasks): 這是將要啟動的 Map 任務的總數,進而決定了總共要抽樣的次數。 舉例 如果 Map 任務的數量是 16,而每個任務的樣本數是 10000,則總共的抽樣次數是 160000 次。 ::: 查詢grep用法 `hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-<hadoop version>.jar grep` 使用grep ``` hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar grep ~/input ~/output 'dfs[a-z.]+' ``` ### 偽分佈模式 (Pseudo-Distributed) 1.建立 namenode 與 datanode 資料夾: `mkdir -p ~/hadoopdata/hdfs/{namenode,datanode}` :::success Hadoop 依據功能不同,設定檔可分為以下部份: core-site.xml hdfs-site.xml mapred-site.xml yarn-site.xml ::: :::warning 設定檔格式: Property 屬性 name: 屬性名稱 value: 屬性質 description: 屬性描述 用以下格式寫入 ``` <configuration> <property> <name>屬性名稱</name> <value>屬性質</value> <description>形容描述(不會顯示)</description> </property> </configuration> ``` ::: :::info 1.core-site.xml 修改core-site.xml: `vim $HADOOP_HOME/etc/hadoop/core-site.xml` ``` <configuration> <property> <name>fs.defaultFS</name> <value>hdfs://localhost:9000</value> </property> </configuration> ``` 2.hdfs-site.xml 修改hdfs-site.xmll: `vim $HADOOP_HOME/etc/hadoop/hdfs-site.xml ` ``` <configuration> <property> <name>dfs.replication</name> <value>1</value> <description>)</description> </property> </configuration> <configuration> <property> <name>dfs.namenode.name.dir</name> <value>file:///home/hadoop/hadoopdata/hdfs/namenode</value> <description>)</description> </property> </configuration> <configuration> <property> <name>dfs.datanode.data.dir</name> <value>file:///home/hadoop/hadoopdata/hdfs/datanode</value> <description>)</description> </property> </configuration> ``` 3.mapred-site.xml 修改hdfs-site.xmll: `vim $HADOOP_HOME/etc/hadoop/mapred-site.xml ` ``` <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> <description>)</description> </property> </configuration> <configuration> <property> <name>yarn.app.mapreduce.am.env</name> <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value> <description>)</description> </property> </configuration> <configuration> <property> <name>mapreduce.map.env</name> <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value> <description>)</description> </property> </configuration> <configuration> <property> <name>mapreduce.reduce.env</name> <value>HADOOP_MAPRED_HOME=$HADOOP_HOME</value> <description>)</description> </property> </configuration> ``` 4.yarn-site.xml 修改yarn-site.xml: `vim $HADOOP_HOME/etc/hadoop/yarn-site.xml ` ``` <configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> <description>)</description> </property> </configuration> ``` ::: ### 啟動 Hadoop 相關 service 格式化 NameNode: `/usr/local/hadoop/bin/hdfs namenode -format` 啟動 Hadoop cluster ``` cd /usr/local/hadoop/sbin/ ./start-all.sh ``` 確認 Hadoop Cluster 服務正常啟動 JPS (Java process): ``` jps ``` 安裝套件: ``` sudo apt install net-tools ``` 確定 NameNode 正常: ``` sudo netstat -ntlp | grep 9870 ``` 確定 Resource Manage 正常啟動 ``` sudo netstat -ntlp | grep 8088 ``` 確定 HDFS 正常啟動 ``` sudo netstat -ntlp | grep 9000 ```   ### 如何知道節點們的埠號? 1.使用 jps 確定 Hadoop 程序: ``` jps ``` 2.使用 netstat 獲取監聽埠號: ``` netstat -tnlp | grep <PID> ```  ### NameNode web interface (overview)   將資料交給resourcemanerger處理 ``` hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar pi 4 10000 ```  ### Workshop - HDFS(計算字數) 本地待處理的數據 (sample_text.txt): ``` Hadoop is an open-source framework that allows to store and process big data in a distributed environment. Hadoop enables data processing over large clusters of computers. ``` 1.創建2層資料夾project_wordcount/raw_data ``` hdfs dfs -mkdir -p project_wordcount/raw_data ``` 2.將本地資料sample_text.txt送至偽分布project_wordcount/raw_data資料夾之中 ``` hdfs dfs -put ~/hadoopdata/hdfs/sample_text.txt project_wordcount/raw_data ``` 3.利用wordcount方法將sample_text.txt整理至 project_wordcount/processed_data ``` hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar wordcount project_wordcount/raw_data/sample_text.txt project_wordcount/processed_data ``` YARN輸出畫面  project_wordcount/processed_data看這邊有沒有產出的檔案 `hdfs dfs -ls project_wordcount/processed_data`  檢視輸出結果 `hdfs dfs -cat project_wordcount/processed_data/part-r-00000`  ### 分析resource_manager_log結果的輸出文件,顯示 "ERROR" 日誌條目的統計數據。 1.創建project_log/resourcemanager_erroe_log兩層資料夾 ``` hdfs dfs -mkdir -p project_log/resourcemanager_erroe_log ``` 2.將本地端的log資料送到偽分布precessed_data ``` hdfs dfs -put /usr/local/hadoop/logs/hadoop-hadoop-resourcemanager- chang.log project_log/resourcemanager_erroe_log/precessed_data ``` 3.將資料文字"ERROE"過濾出來(資料會倒到result_log資料夾) ``` hadoop jar /usr/local/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.3.6.jar grep project_log/resourcemanager_erroe_log/precessed_data /project_log/resourcemanager_erroe_log/result_log "ERROR" ``` 4.確認result_log資料夾的資料 ``` hdfs dfs -ls /project_log/resourcemanager_erroe_log/result_log ``` 5.檢視part-r-00000輸出資料 ``` hdfs dfs -cat /project_log/resourcemanager_erroe_log/result_log/part-r-00000 ```  ## 多機安裝模式 (Fully-Distributed) 環境建置 1.架設 3 台節點 VirtualVM (slave only): CPU: 1 core RAM: 2GB RAM 硬碟空間: 20GB 請保持 3 台主機都有共同的 username Eg. username: hadoop  #### 重新設定主機名稱(不然名稱會搞混): - Master (於 Master 主機): 將主管機取名為Master ``` hostnamectl set-hostname master ``` - Slave1 (於 Slave1 主機): ``` hostnamectl set-hostname slave1 ```` - Slave2 (於 Slave2 主機): ``` hostnamectl set-hostname slave2 ```` 2.建立金鑰 ``` ssh-keygen -t rsa ``` 3.將公鑰寫入認證 ``` cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys ``` 4.到金鑰帳本將主管機與奴隸機的id_rsa.pub都寫入各自的.ssh/authorized_keys ``` cd /home/hadoop/.ssh ``` 5.確定這 3 台節點,彼此可以使用 SSH 金鑰登入(不需要輸入密碼) ps.請設定這 3 台節點的主機名稱 (hostname),讓彼此可以使用 主機名稱 (hostname) & SSH 金鑰登入 :::success master -> slave-1 slave-1 -> master master -> slave-2 slave-2 -> master slave-1 -> slave-2 slave-2 -> slave-1 ::: #### 綁定主機名稱與 IP 位址: 修改/etc/hosts ``` sudo vim /etc/hosts ``` 將名稱與IP位置做連結(主管機與奴隸機都要貼) ``` 10.167.218.124 master 10.167.218.176 slave1 10.167.218.201 slave2 ``` 6.關閉所有主機防火牆: ``` sudo ufw disable ``` 示範 (Master to slave-1) `ssh slave1` 7.全部的主機都需要事先安裝好 hadoop和java - Master 的主機,請啟動 hadoop - Slave-* 的主機,全部不啟動 hadoop Master和slave確認hadoop執行版本 ``` /usr/local/hadoop/bin/hadoop version ``` 確認java版本 `java -version` 8.Master啟動 Hadoop 相關 service - 停止Hadoop cluster `./stop-all.sh` - 格式化 NameNode: `/usr/local/hadoop/bin/hdfs namenode -format` - 啟動 Hadoop cluster ``` cd /usr/local/hadoop/sbin/ ./start-all.sh ``` #### 依照偽分布操作修改設定檔 - core-site.xml: ``` - name: fs.defaultFS - value: hdfs://master:9000 ``` ``` - name: fs.tmp.dir - value: /usr/local/hadoop/tmp ``` - hdfs-site.xml: ``` - name: dfs.replication - value: 2 ``` ``` - name: dfs.namenode.name.dir - value: /usr/local/hadoop/hdfs/name ``` ``` - name: dfs.namenode.data.dir - value: /usr/local/hadoop/hdfs/data ``` - mapred-site.xml: ``` - property - name: mapreduce.framework.name - value: yarn - property - name: yarn.app.mapreduce.am.env - value:HADOOP_MAPRED_HOME=/usr/local/hadoop - property - name: mapreduce.map.env - value:HADOOP_MAPRED_HOME=/usr/local/hadoop - property - name: mapreduce.reduce.env - value:HADOOP_MAPRED_HOME=/usr/local/hadoop ``` - yarn-site.xml: ``` - name: yarn.resourcemanager.hostname - value: master ``` ``` - name: yarn.nodemanager.aux-services - value: mapreduce_shuffle ``` ``` - property - name: yarn.resourcemanager.resource-tracker.address - value: master:8031 - property - name: yarn.resourcemanager.scheduler.address - value: master:8030 - propery - name: yarn.resourcemanager.address - value: master:8032 - property - name: yarn.resourcemanager.admin.address - value: master:8033 - property - name: yarn.resourcemanager.webapp.address - value: master:8088 ``` 在本機端建立資料夾 ``` mkdir -p /usr/local/hadoop/tmp mkdir -p /usr/local/hadoop/hdfs/name mkdir -p /usr/local/hadoop/hdfs/data ``` 新增以下檔案,以指定 workers `vim /usr/local/hadoop/etc/hadoop/workers` 內容: ``` slave1 slave2 ``` #### 以 SSH 協定佈署到各個位置: ##### 在 Master 機器中,將設定檔複製到 slave1, slave2 將master複製到slave1 ``` scp /usr/local/hadoop/etc/hadoop/* hadoop@slave1:/usr/local/hadoop/etc/hadoop/ ``` 將master複製到slave2 ``` scp /usr/local/hadoop/etc/hadoop/* hadoop@slave2:/usr/local/hadoop/etc/hadoop/ ``` 在 Master 格式化 NodeNode ``` /usr/local/hadoop/bin/hdfs namenode -format ``` 在 Master 機器中啟動 Master & Slave1, 2 的服務: ``` /usr/local/hadoop/sbin/start-all.sh ``` 在master檢查成員 `jps`  在slave1檢查成員  在slave2檢查成員  mkdir -p /usr/local/hadoop/hdfs/data :::warning 環境變數提醒 env | grep HOME   ::: :::danger 缺少 DataNode: `/usr/local/hadoop/sbin/stop-all.sh` `cd ~/hadoopdata/hdfs/` `rm -rf *` `mkdir -p ~/hadoopdata/hdfs/{namenode,datanode}` `/usr/local/hadoop/bin/hdfs namenode -format` (三台都要執行) `rm -rf /tmp/hadoop-*` (master) `/usr/local/hadoop/sbin/start-all.sh` ::: :::danger 缺少NodeManager: 停止運行後 > 格式化 > pkill -9 java >執行程式 ::: ### 測試 HDFS 建立test_file_for_test_hdfs.txt ``` touch test_file_for_test_hdfs.txt ``` 將test_file_for_test_hdfs.txt推至奴隸機 ``` hdfs dfs -put test_file_for_test_hdfs.txt / ``` 在 Master/Slave1/Slave2 中列出檔案: - master ``` hdfs dfs -ls / ```  - slave1 slave2 ``` hdfs dfs -ls / ```    網址輸入: `10.167.218.124:9870` 現在你有2個活的奴隸了!!!  ps.查詢hadoop指行檔 ``` ll /usr/local/hadoop/sbin/ ``` ps2.查看過作情形 ``` watch jps ``` 執行工作畫面  ### Workshop - Fully-Distributed Deploy (Multi-Host)  步驟一:關閉hadoop(同學A_master) `/usr/local/hadoop/sbin/stop-all.sh` 步驟二:抓公鑰給別人(同學B_slave) `cat ~/.ssh/id_rsa.pub` 步驟三:加入別人的公鑰(同學A_master和同學B_slave的公鑰都要互相寫入彼此的驗證裡) `echo '別人的公鑰' >> ~/.ssh/authorized_keys` 步驟四:修改IP對應名稱,用一個好辨識的名稱即可(定義哪個ip是master,哪個是slave) `sudo vim /etc/hosts` 步驟五:將別人的slave加入員工清單,把前一步驟好辨識的名稱加入 `vim /usr/local/hadoop/etc/hadoop/workers` 步驟六:移除暫存、設定,格式化hdfs ``` rm -rf ~/hadoopdata/hdfs/* rm -rf /tmp/* rm -rf /usr/local/hadoop/tmp/* rm -rf /usr/local/hadoop/logs/* rm -rf /usr/local/hadoop/hdfs/name/* rm -rf /usr/local/hadoop/hdfs/data/* ``` `mkdir -p ~/hadoopdata/hdfs/{namenode,datanode}` `/usr/local/hadoop/bin/hdfs namenode -format -y` 步驟七:將設定檔匯入對方電腦(以master傳到slave1為例) `scp /usr/local/hadoop/etc/hadoop/* hadoop@slave1:/usr/local/hadoop/etc/hadoop/` `scp /etc/hostshadoop@slave1:/usr/local/hadoop/etc/hadoop/` 步驟八:開啟hadoop(master) `/usr/local/hadoop/sbin/start-all.sh` :::danger 當奴隸的主人有轉移時,要將暫時的紀錄清空,不然奴隸會不知道誰是主人 `echo " "">known_hosts` `echo " "">known_hosts.old`  :::
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up