Apache Hadoop

作者:jiangzz 電話:15652034180 微信:jiangzz_wx 微信公衆賬號:jiangzz_wy

大數據(Big Data)

隨着信息化互聯網|物聯網發展要求,萬物互聯趨勢勢在必行。隨之引發架構的演變由單一架構向高併發分佈式架構演變。數據的存儲也開始由原始的單機存儲演變爲分佈式存儲。

  • 高併發互聯網設計 LNMP、數據庫主從RDBMS|NoSQL、Spring Cloud、Dubbo – 應用架構
  • 海量數據存儲|數據分析 :存儲方案(HDFS)、計算方案(Map Reduce、StormSparkFlink
  • BI/AI: 高級數據分析Machine Learing (Mahout、Spark Mllib、FlinkMllib)

面臨問題?

分佈式:服務間出現跨機器、跨進程通信同一稱爲分佈式

  • 存儲:

    • 單機存儲-瓶頸:容量限制、擴展性差、數據災備問題

    • 分佈式存儲:使用存儲的集羣實現對海量數據的並行化的讀寫,提升系統寫的吞吐能力。目前針對傳統業務領域的分佈式文件存儲方案有:FastDFS/GlusterFS/GridFS、大文本日誌存儲解決方案:HDFS

  • 分析:

    • 單機分析-計算:慢,受限於單機存儲的內存、CPU、網絡限制。
    • 分佈式計算:將計算任務交給專門的計算集羣負責任務的計算。打破單機計算的瓶頸,實現並行計算,模擬多核CPU的計算能力。可以實現在一定的時間內達到對數據的有效分析。

Hadoop誕生

2003-2004年,Google公佈了部分GFS和MapReduce思想的細節,受此啓發的Doug Cutting等人用2年的業餘時間實現了DFS和MapReduce機制,使Nutch性能飆升。然後Yahoo招安Doug Gutting及其項目。
2005年:Hadoop作爲Lucene的子項目Nutch的一部分正式引入Apache基金會。
2006年2月:yahoo加入Nutch工程嘗試將Nutch存儲和計算分離出來,成爲一套完整獨立的軟件並起名爲Hadoop 。

人稱Hadoop之父的Doug Cutting,Apache軟件基金會主席,是Lucene、Nutch 、Hadoop等項目的發起人。最開始Hadoop只是Apache Lucene的子項目Nutch的一部分。Lucene 是全球第一個開源的全文檢索引擎工具包, Nutch基於Lucene,並具有網頁抓取和解析的功能,可以實現一個搜索引擎的開發,但是如果投入使用的話就必須在極短時間內做出反應,並且能夠實現短時間內對億級數量的網頁進行分析處理,這就需要考慮分佈式任務處理、故障恢復、負載均衡這些問題。後來Doug Cutting 借鑑谷歌的Google File SystemMapReduce:Simplified Data Processing On Large Clusters兩篇論文,移植了其中的技術,並將其命名爲:Hadoop。

HDFS:Hadoop 分佈式文件存儲系統,解決海量數據的存儲問題(非常重要)

Map Reduce:Hadoop項目分佈式計算框架(老),已經成爲大數據計算的標杆。是早期分佈式計算解決方案。期間該方案在2010年又被Yahoo團隊做了一次升級,主要解決的是MapReduce在大規模計算集羣的擴展性問題,但是並沒有本質改變MapReduce計算本質。因爲MapReduce計算的是通過對數據做磁盤迭代計算。導致計算速度不算太快。2013年下半年出現了Spark是一款基於內存的分佈式計算框架,用於替代Hadoop的MapReduce,被人們稱爲第二代大數據計算引擎。

Hadoop HDFS

Hadoop編譯

安裝編譯依賴

[root@CentOS ~]# yum install -y autoconf automake libtool cmake gcc* ncurses-devel openssl-devel

安裝protobuf-2.5.0.tar.gz

hadoop使用protocol buffer進行通信,需要下載和安裝protobuf-2.5.0.tar.gz。

[root@CentOS ~]# tar -zxf protobuf-2.5.0.tar.gz
[root@CentOS ~]# cd protobuf-2.5.0
[root@CentOS protobuf-2.5.0]# ./configure
[root@CentOS protobuf-2.5.0]# make && make install

配置Maven編譯環境

[root@CentOS ~]# tar -zxf apache-maven-3.3.9-bin.tar.gz -C /usr
[root@CentOS ~]# vi .bashrc

M2_HOME=/usr/apache-maven-3.6.0
MAVEN_OPTS="-Xms256m -Xmx768m -XX:PermSize=128m -XX:MaxPermSize=256M"
JAVA_HOME=/usr/java/latest
CLASSPATH=.
PATH=$PATH:$JAVA_HOME/bin:$M2_HOME/bin
export JAVA_HOME
export CLASSPATH
export PATH
export M2_HOME
export MAVEN_OPTS

[root@CentOS ~]# source .bashrc

編譯hadoop源碼

[root@CentOS ~]# wget http://us.mirrors.quenda.co/apache/hadoop/common/hadoop-2.9.2/hadoop-2.9.2-src.tar.gz
[root@CentOS ~]# tar -zxf hadoop-2.9.2-src.tar.gz
[root@CentOS ~]# cd hadoop-2.9.2-src
[root@CentOS hadoop-2.9.2-src]# mvn package -Pdist,native -DskipTests -Dtar

在編譯的時候需要保證電腦聯網,因爲在編譯的時候還需要下載tomcat。編譯的目標文件:hadoop-2.9.2-src/hadoop-dist/target 目錄下,成功後會看到如下界面:

[INFO] ---------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] Apache Hadoop Main ................................. SUCCESS [ 10.140 s]
[INFO] Apache Hadoop Project POM .......................... SUCCESS [ 5.495 s]
...略....
[INFO] Apache Hadoop Tools Dist ......SUCCESS [ 14.265 s]
[INFO] Apache Hadoop Tools ...............SUCCESS [ 0.070 s]
[INFO] Apache Hadoop Distribution .......... SUCCESS [01:00 min]

HDFS基本概念

是一個基於分佈式存儲通用的文件系統,該系統特點容易部署、對系統硬件要求低,搭建成本可控。可以使得數據存儲大小和集羣過程呈現一種線性關係 (目前最大已知規模2000臺左右規模,實際在生產環境下集羣規模一般在10~100臺左右)。HDFS文件系統的架構圖:
在這裏插入圖片描述

NameNode:使用內存存儲集羣中的元數據(文件命名空間-文件目錄結構、數據塊到DataNode映射)

DataNode:負責響應客戶端對數據塊的讀寫請求,向NameNode彙報自身狀態信息。

Block:是HDFS切分文件的尺度,默認是128MB,一個文件最多隻有 一個不足128MB塊

副本因子:HDFS爲了防止DataNode宕機導致塊的丟失,允許一個塊又多個備份,默認備份是3

爲什麼HDFS不擅長存儲小文件?

案例 NN DN
1文件128MB 1條數據塊映射元數據 128MB磁盤存儲*(副本因子)
1000文件總計128MB 1000*1條數據塊映射元數據 128MB磁盤存儲*(副本因子)

因爲Namenode使用單機的內存存儲,因此由於小文件會佔用更多的內存空間,導致了Namenode內存浪費。

Secondary(輔助) NameNode & NameNode關係?
在這裏插入圖片描述
fsimage:存儲在Namenode服務所在物理主機磁盤上的一個二進制文本文件。記錄了元數據信息

edits:存儲在Namenode服務所在物理主機磁盤上的一個二進制文本文件,記錄了對元數據修改操作。

當第一次啓動Namenode服務的時候,系統會加載fsimage和edits文件進行合併得到最新元數據信息,並且更新fsimage和edits,一旦服務啓動成功後,在服務允許期間不再更新fsimage,只是將操作記錄在edits中。導致namenode在長期運行之後重啓導致namenode啓動時間過長,還可能導致edits文件過大。因此Hadoop HDFS引入Secondary Namenode 輔助Namenode在運行期間完成對元數據的備份和整理。

HDFS環境搭建(單機|僞分佈式)

  • 安裝虛擬器並且安裝CentOS-6.5 64位 (參考[CentOS 64安裝.wmv](./CentOS 64安裝.wmv))

  • 安裝jdk-8u171-linux-x64.rpm配置JAVA_HOME環境變量(~/.bashrc)

[root@CentOS ~]# rpm -ivh jdk-8u171-linux-x64.rpm 
[root@CentOS ~]# ls -l /usr/java/
total 4
lrwxrwxrwx. 1 root root   16 Mar 26 00:56 default -> /usr/java/latest
drwxr-xr-x. 9 root root 4096 Mar 26 00:56 jdk1.8.0_171-amd64
lrwxrwxrwx. 1 root root   28 Mar 26 00:56 latest -> /usr/java/jdk1.8.0_171-amd64
[root@CentOS ~]# vi .bashrc 
JAVA_HOME=/usr/java/latest
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH=.
export JAVA_HOME
export PATH
export CLASSPATH
[root@CentOS ~]# source ~/.bashrc # 加載環境變量
  • 配置主機名和IP映射關係
[root@CentOS ~]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:0C:29:37:20:59  
          inet addr:`192.168.40.128`  Bcast:192.168.40.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe37:2059/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:246948 errors:0 dropped:0 overruns:0 frame:0
          TX packets:22719 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:370063776 (352.9 MiB)  TX bytes:2150553 (2.0 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)
[root@CentOS ~]# vi /etc/hosts # 一定是自己的IP
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.40.128 CentOS          
  • 配置Linux免密碼登陸(Linux系統間登陸方式)

    基於口令登陸需要輸入用戶名和密碼

    基於祕鑰登陸方式

[root@CentOS ~]# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
4b:29:93:1c:7f:06:93:67:fc:c5:ed:27:9b:83:26:c0 root@CentOS
The key's randomart image is:
+--[ RSA 2048]----+
|                 |
|         o   . . |
|      . + +   o .|
|     . = * . . . |
|      = E o . . o|
|       + =   . +.|
|        . . o +  |
|           o   . |
|                 |
+-----------------+
[root@CentOS ~]# ssh-copy-id CentOS
The authenticity of host 'centos (192.168.40.128)' can't be established.
RSA key fingerprint is 3f:86:41:46:f2:05:33:31:5d:b6:11:45:9c:64:12:8e.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'centos,192.168.40.128' (RSA) to the list of known hosts.
root@centos's password: 
Now try logging into the machine, with "ssh 'CentOS'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.
[root@CentOS ~]# ssh root@CentOS
Last login: Tue Mar 26 01:03:52 2019 from 192.168.40.1
[root@CentOS ~]# exit
logout
Connection to CentOS closed.
  • 關閉防火牆
# 臨時關閉服務
[root@CentOS ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter [  OK  ]
iptables: Flushing firewall rules: [  OK  ]
iptables: Unloading modules: [  OK  ]
[root@CentOS ~]# service iptables status
iptables: Firewall is not running.
# 關閉開機自動啓動
[root@CentOS ~]# chkconfig iptables off
[root@CentOS ~]# chkconfig --list | grep iptables
iptables        0:off   1:off   2:off   3:off   4:off   5:off   6:off
  • 安裝配置Hadoop

解壓bingo配置環境變量

[root@CentOS ~]# tar -zxf hadoop-2.6.0_x64.tar.gz -C /usr/
[root@CentOS ~]# ls /usr/hadoop-2.6.0/
bin  etc  include  lib  libexec  LICENSE.txt  NOTICE.txt  README.txt  sbin  share
[root@CentOS ~]# vi ~/.bashrc 
HADOOP_HOME=/usr/hadoop-2.6.0
JAVA_HOME=/usr/java/latest
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
CLASSPATH=.
export JAVA_HOME
export PATH
export CLASSPATH
export HADOOP_HOME
[root@CentOS ~]# source  ~/.bashrc 
[root@CentOS ~]# hadoop version
Hadoop 2.6.0
Subversion Unknown -r Unknown
Compiled by root on 2016-08-01T20:48Z
Compiled with protoc 2.5.0
From source with checksum 18e43357c8f927c0695f1e9522859d6a
This command was run using /usr/hadoop-2.6.0/share/hadoop/common/hadoop-common-2.6.0.jar

配置hadoop配置文件etc/hadoop/{core-site.xml|hdfs-site.xml|slaves}

core-site.xml(配置的是NameNode訪問入口,以及服務存儲的根目錄)

[root@CentOS ~]# vi /usr/hadoop-2.6.0/etc/hadoop/core-site.xml 
<!--nn訪問入口-->
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://CentOS:9000</value>
</property>
<!--hdfs工作基礎目錄-->
<property>
    <name>hadoop.tmp.dir</name>
    <value>/usr/hadoop-2.6.0/hadoop-${user.name}</value>
</property>
[root@CentOS ~]# vi /usr/hadoop-2.6.0/etc/hadoop/hdfs-site.xml 
<!--block副本因子-->
<property>
    <name>dfs.replication</name>
    <value>1</value>
</property>
<!--配置Sencondary namenode所在物理主機-->
<property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>CentOS:50090</value>
</property>
[root@CentOS ~]# vi /usr/hadoop-2.6.0/etc/hadoop/slaves 
CentOS
  • HDFS啓動

    如果是第一次初始化啓動HDFS服務,需要創建一個空的fsimage文件,以便Namenode在啓動的時候加載

[root@CentOS ~]# hdfs namenode -format # 創建初始化所需的fsimage文件
...
19/03/26 01:31:09 INFO namenode.NNConf: Maximum size of an xattr: 16384
19/03/26 01:31:09 INFO namenode.FSImage: Allocated new BlockPoolId: BP-1143348175-192.168.40.128-1553535069443
19/03/26 01:31:09 INFO common.Storage: Storage directory `/usr/hadoop-2.6.0/hadoop-root/dfs/name has been successfully formatted.`
19/03/26 01:31:09 INFO namenode.NNStorageRetentionManager: Going to retain 1 images with txid >= 0
...
[root@CentOS ~]# ls /usr/hadoop-2.6.0/hadoop-root/dfs/name/current/
fsimage_0000000000000000000  fsimage_0000000000000000000.md5  seen_txid  VERSION

​ 啓動HDFS的服務

[root@CentOS ~]# start-dfs.sh 
Starting namenodes on [CentOS]
CentOS: starting namenode, logging to /usr/hadoop-2.6.0/logs/hadoop-root-namenode-CentOS.out
CentOS: starting datanode, logging to /usr/hadoop-2.6.0/logs/hadoop-root-datanode-CentOS.out
Starting secondary namenodes [CentOS]
CentOS: starting secondarynamenode, logging to /usr/hadoop-2.6.0/logs/hadoop-root-secondarynamenode-CentOS.out
[root@CentOS ~]# jps
2097 SecondaryNameNode
2280 Jps
1993 DataNode
1918 NameNode

或者訪問:http://[IP]:50070/

HDFS Shell(腳本)

[root@CentOS ~]# hdfs dfs -help
Usage: hadoop fs [generic options]
        [-appendToFile <localsrc> ... <dst>]
        [-cat [-ignoreCrc] <src> ...]
        [-checksum <src> ...]
        [-chmod [-R] <MODE[,MODE]... | OCTALMODE> PATH...]
        [-copyFromLocal [-f] [-p] [-l] <localsrc> ... <dst>]
        [-copyToLocal [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-cp [-f] [-p | -p[topax]] <src> ... <dst>]
        [-get [-p] [-ignoreCrc] [-crc] <src> ... <localdst>]
        [-help [cmd ...]]
        [-ls [-d] [-h] [-R] [<path> ...]]
        [-mkdir [-p] <path> ...]
        [-moveFromLocal <localsrc> ... <dst>]
        [-moveToLocal <src> <localdst>]
        [-mv <src> ... <dst>]
        [-put [-f] [-p] [-l] <localsrc> ... <dst>]
        [-rm [-f] [-r|-R] [-skipTrash] <src> ...]
        [-tail [-f] <file>]
        [-text [-ignoreCrc] <src> ...]
        [-touchz <path> ...]

[root@CentOS ~]# hadoop fs -ls /
[root@CentOS ~]# hadoop fs -touchz /aa.log
[root@CentOS ~]# hdfs dfs -ls /
Found 1 items
-rw-r--r--   1 root supergroup          0 2019-03-26 01:47 /aa.log
[root@CentOS ~]# hdfs dfs -appendToFile /root/install.log /aa.log
[root@CentOS ~]# hdfs dfs -mkdir -p /aa/bb
[root@CentOS ~]# hdfs dfs -cp /aa.log  /aa/bb
[root@CentOS ~]# hdfs dfs -mv /aa.log  /install.log
[root@CentOS ~]# md5sum install.log
98b85629951ad584feaf87e28c073088  install.log
[root@CentOS ~]# rm -rf install.log
[root@CentOS ~]# hadoop fs -copyToLocal /install.log /root
[root@CentOS ~]#  md5sum install.log
98b85629951ad584feaf87e28c073088  install.log
[root@CentOS ~]# hdfs dfs -rm -r -f /aa
19/03/26 01:53:04 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 0 minutes, Emptier interval = 0 minutes.
Deleted /aa

HDFS 垃圾回收站

用戶可以通過配置core-site.xml,開啓NameNode的垃圾回收。NameNode會根據fs.trash.interval配置配置垃圾回收的頻率,默認單位是分鐘。

<property>
    <name>fs.trash.interval</name>
    <value>1</value>
</property>

表示1分鐘內,如果用戶不處理刪除文件,系統會自動刪除回收戰的內容。該種機制就是爲了防止用戶的誤操作。

[root@CentOS ~]# hdfs dfs -rm -r -f /install.log
19/03/26 17:58:31 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://CentOS:9000/install.log' to trash at: hdfs://CentOS:9000/user/root/.Trash/Current
[root@CentOS ~]# hdfs dfs -ls -R /user
drwx------   - root supergroup          0 2019-03-26 17:58 /user/root
drwx------   - root supergroup          0 2019-03-26 17:59 /user/root/.Trash
drwx------   - root supergroup          0 2019-03-26 17:58 /user/root/.Trash/190326175900
-rw-r--r--   1 root supergroup       8815 2019-03-26 01:47 /user/root/.Trash/190326175900/install.log
[root@CentOS ~]# hdfs dfs -put /root/hadoop-2.6.0_x64.tar.gz /
[root@CentOS ~]# hdfs dfs -rm -r -f -skipTrash /hadoop-2.6.0_x64.tar.gz
Deleted /hadoop-2.6.0_x64.tar.gz
[root@CentOS ~]# hdfs dfs -ls -R /user
drwx------   - root supergroup          0 2019-03-26 17:58 /user/root
drwx------   - root supergroup          0 2019-03-26 18:00 /user/root/.Trash

NameNode的安全模式

是對HDFS的一種保護機制,1)正常情況下當系統在加載fsimage的初期會自動進入安全模式,在該模式下系統不接受外界的任何請求,當加載完數據檢查系統完畢,系統會自動離開安全模式。2)如果當DataNode/NameNode使用空間不足時,系統會自動進入安全模式。3).當系統維護時,管理員也可手動的將NameNode切換成安全模式,維護結束再離開。

[root@CentOS ~]# hdfs dfsadmin -safemode get
Safe mode is OFF
[root@CentOS ~]# hdfs dfsadmin -safemode enter
Safe mode is ON
[root@CentOS ~]# hdfs dfs -put /root/install.log /
put: Cannot create file/install.log._COPYING_. Name node is in safe mode.
[root@CentOS ~]# hdfs dfsadmin -safemode leave
Safe mode is OFF
[root@CentOS ~]# hdfs dfs -put /root/install.log /

機架 Rack Aware

使用Rack標示去表示在大規模HDFS集羣中DataNode節點所在物理主機所屬機架的映射關係。這樣hadoop在管理存儲和計算的時候,會優先考慮機架內部恢復和機架內部計算原則,提升系統的計算效率(網絡帶寬有一定提升)。
在這裏插入圖片描述

[root@CentOS ~]# hdfs dfsadmin -printTopology
Rack: /default-rack  # 機架標示
   192.168.40.128:50010 (CentOS)  ## DataNode物理主機

Java API HDFS (Windows)

  • 配置windos開發環境

    • 解壓hadoop的安裝包

    • 將winutil.exe和hadoop.dll文件拷貝到hadoop安裝目錄下的bin目錄

    • 在Windows上配置CentOS的主機名和IP的映射關係
      在這裏插入圖片描述

      192.168.40.128 CentOS
      
    • 配置HADOOP_HOME環境變量

    • 重啓IDEA開發工具,否則IDAE無法識別HADOOP_HOME,因爲windows執行代碼程序需要通過HADOOP_HOME定位winutil.exe和hadoop.dll文件。

  • 關閉HDFS權限
    在這裏插入圖片描述
    方案1:配置hdfs-site.xml關閉HDFS權限管理(臨時關閉),配置完後重啓hdfs服務

<property>
	<name>dfs.permissions.enabled</name>
    <value>false</value>
</property>

方案2:欺騙hadoop告訴hadoop當前就是root用戶,可以通過添加虛擬機啓動參數方式

java -DHADOOP_USER_NAME=root xxxxx

Maven依賴hdfs

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-hdfs</artifactId>
    <version>2.6.0</version>
</dependency>

在這裏插入圖片描述
上傳文件

Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);
Path src = new Path("file:///F:\\Java大數據資料\\筆記.md");
Path dst = new Path("/");
fs.copyFromLocalFile(src,dst);
---
Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);

InputStream in=new FileInputStream("F:\\Java大數據資料\\筆記.md");
Path dst = new Path("/筆記1.md");
OutputStream os=fs.create(dst);

IOUtils.copyBytes(in,os,1024,true);    

下載文件

Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);
Path dst = new Path("file:///C:\\Users\\Administrator\\Desktop\\筆記.md");
Path src = new Path("/筆記.md");
fs.copyToLocalFile(src,dst);//如果測試失敗,請嘗試它的重載方法
---
Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);

Path dst = new Path("/筆記.md");
InputStream in= fs.open(dst);
OutputStream os=new FileOutputStream("C:\\Users\\Administrator\\Desktop\\筆記.md");

IOUtils.copyBytes(in,os,1024,true);    

刪除文件

Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);

Path delete = new Path("/筆記1.md");
---
Configuration conf = new Configuration();
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
FileSystem fs=FileSystem.get(conf);
Trash trash=new Trash(fs,conf);
Path delete = new Path("/筆記.md");
trash.moveToTrash(delete);    

Map Reduce

概述

Map Reduce是一個 Hadoop 的並行計算框架,借鑑了函數式編程(Scala 編程應用在Spark)思想和矢量編程(任務做階段化拆分,每個階段都可以設定並行度)。Hadoop 中是充分利用了存儲節點(Data Node)運行所在主機的計算資源(CPU、內存、網絡、少許磁盤-存儲計算中間結果)完成對任務的並行計算。Map Reduce框架會在所有的DataNode所在的物理主機啓動一個計算資源管理者-Node Manager用於管理本地的計算資源,默認系統會將計算資源均分8個等份,每個等份抽象成一個Container。還會再找一些其他的主機啓動一個資源管理中心-Resource Manager,用於管理集羣的計算資源。

當用戶提交一個計算任務給MapReduce框架,框架會將任務拆分成Map階段和Reduce階段(矢量編程思想將任務拆分成兩個階段),框架會根據Map/Reduce階段的任務並行度.在任務提交初期會啓動一個任務管理者(每個任務都有自己的任務管理者)-MRAppMaster(該進程會浪費掉1個計算資源)用於管理Map階段和Reduce階段任務執行。在任務執行時期,每個階段會根據階段任務的並行度分配計算資源(每個計算資源啓動一個Yarn Child),由MRAppMaster完成對階段任務的檢測管理。
在這裏插入圖片描述
ResourceManager:負責任務資源的統一調度,管理NodeManager資源,啓動MRAppMaster

NodeManager:用於管理本機上的計算資源,默認會將本機的計算資源拆分爲8個等份,每個等份抽象成Container

MRAppMaster:任何一個執行的任務都會有一個MRAppMaster負責YarnChild任務的執行和監測。

YarnChild:是具體執行的MapTask或者是ReduceTask的統稱。

任務執行期間系統會啓動MRAppmaster和YarnChild負責任務的執行,一旦任務執行結束MRAppMaster和YarnChild會自動退出。

環境搭建

yarn-site.xml

<!--配置MapReduce計算框架的核心實現Shuffle-洗牌-->
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>
<!--配置資源管理器所在的目標主機-->
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>CentOS</value>
</property>

mapred-site.xml-該文件不存在,需要手動創建

<!--MapRedcue框架資源管理器的實現-->
<property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
</property>

啓動yarn計算框架

[root@CentOS ~]# start-yarn.sh 
starting yarn daemons
starting resourcemanager, logging to /usr/hadoop-2.6.0/logs/yarn-root-resourcemanager-CentOS.out
CentOS: starting nodemanager, logging to /usr/hadoop-2.6.0/logs/yarn-root-nodemanager-CentOS.out

查看進程

[root@CentOS ~]# jps
5091 ResourceManager
5172 NodeManager
1332 NameNode
1413 DataNode
1525 SecondaryNameNode
5477 Jps

ResourceManager內嵌一個web服務嗎,用於查看整個集羣的資源調度信息http://ip:8088

入門案例

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-mapreduce-client-jobclient</artifactId>
    <version>2.6.0</version>
</dependency>

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-mapreduce-client-core</artifactId>
    <version>2.6.0</version>
</dependency>

日誌文件格式如下(1TB):

日誌級別 URL 用戶ID 日期
INFO /product 001 2019-03-26 10:00:00
INFO /cart 003 2019-03-26 10:00:00
INFO /product 001 2019-03-26 10:00:00
INFO /cart 002 2019-03-26 10:00:00
INFO /order 004 2019-03-26 10:00:00

1.按照URL統計每個板塊訪問的次數,並且使用柱狀圖顯示?

商品板塊 2

購物車 2

訂單 1

create table t_click(
   level varchar(32),
   url varchar(128),
   uid varchar(32),
   click_time timestamp 
)
select url,sum(1) from t_click group by url
      reduce(key,values)        map(key,value)
      reduce(url,[1,1,1,...])    map(url,1)

Map

public class ClickMappper  extends Mapper<LongWritable, Text,Text, IntWritable> {
    //INFO /product 001 2019-03-26 10:00:00
    @Override
    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
        String[] tokens = value.toString().split(" ");
        context.write(new Text(tokens[1]),new IntWritable(1));
    }
}

Reduce

public class ClickReducer extends Reducer<Text, IntWritable,Text,IntWritable> {
    @Override
    protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
        int total=0;
        for (IntWritable value : values) {
            total=value.get();
        }
        context.write(key,new IntWritable(total));
    }
}

Job任務

public class CustomJobSubmitter extends Configured implements Tool {
    public int run(String[] strings) throws Exception {
        //1.封裝Job對象
        Job job=Job.getInstance(getConf());
        //2.設置任務的讀取、寫出數據格式
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        //3.設置數據讀入和寫出路徑
        Path src = new Path("/demo/click");
        TextInputFormat.addInputPath(job,src);
        Path dst = new Path("/demo/result");//必須不存在,否則任務提交失敗
        TextOutputFormat.setOutputPath(job,dst);
        //4.設置數據處理邏輯代碼片段
        job.setMapperClass(ClickMappper.class);
        job.setReducerClass(ClickReducer.class);
        //5.設置Mapper和Reducer輸出key-value類型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        //6.任務提交
        //job.submit();
        job.waitForCompletion(true);
        return 0;
    }
    public static void main(String[] args) throws Exception {
        ToolRunner.run(new CustomJobSubmitter(),args );
    }
}

發佈任務

  • 遠程jar發佈
job.setJarByClass(CustomJobSubmitter.class);

hadoop jar xxxxx.jar com.baizhi.CustomJobSubmitter

  • 本地測試(本地模擬Map Reduce邏輯-測試
    在這裏插入圖片描述
    解決方案

覆蓋NativeIO類,修改access實現,將該方法的實現短路。

public static boolean access(String path, NativeIO.Windows.AccessRight desiredAccess) throws IOException {
    return true;
    //return access0(path, desiredAccess.accessRight());
}
  • 跨平臺提交

項目添加配置文件
在這裏插入圖片描述
提交代碼需要添加如下

//設置配置信息
conf.addResource("core-site.xml");
conf.addResource("hdfs-site.xml");
conf.addResource("yarn-site.xml");
conf.addResource("mapred-site.xml");
conf.set("mapreduce.job.jar","file:///jar包路徑");

In/OutputFormat

Split&Record Reader

在這裏插入圖片描述

In/OutputFormat實戰

對接文件系統-(讀取):

  • TextInputFormat: (必須掌握)

切片計算 :以文件爲單位,對一個文件按照SplitSize計算切片大小(0~140.8 MB)

Key-Value : 行字節偏移量LongWritable | 當前文本行 ,確定Mapper<LongWritable,Text,X,X>

  • NLineInputFormat

切片計算 :以文件爲單位,對一個文件按照行切割,默認是1行一個切片
Key-Value : 行字節偏移量LongWritable | 當前文本行 ,確定Mapper<LongWritable,Text,X,X>
mapreduce.input.lineinputformat.linespermap = 10000

  • KeyValueTextInputFormat

切片計算 :以文件爲單位,對一個文件按照SplitSize計算切片大小(0~140.8 MB)

Key-Value : Text \t Text ,確定Mapper<Text,Text,X,X>
mapreduce.input.keyvaluelinerecordreader.key.value.separator=|

  • CombineTextInputFormat(小文件計算優化)

切片計算 :對N個文件按照SplitSize計算切片大小(0~140.8 MB),多個文件對應一個切片
Key-Value :行字節偏移量LongWritable | 當前文本行 ,確定Mapper<LongWritable,Text,X,X>

MultipleInputs 實現 Join

1、在Map端分別對不同格式的數據定製Mapper和InputFormat
2、所有的Mapper輸出KEY-VALUE必須保證一致
3、所有Map輸出的KEY必須是 join 字段
4、針對不同的Mapper輸出,通過對做標記,這樣纔可以在Reduce端區分數據

DBOutputFormat(重點)

//1.配置數據鏈接參數
DBConfiguration.configureDB(conf,
             "driver",
             "url",
             "username",
             "password"
             );
//2.設置任務的寫出數據格式
job.setOutputFormatClass(DBOutputFormat.class);
//3.設置數據寫出路徑
DBOutputFormat.setOutput(job,"t_user_order","id","name","age","items","price");
//4.Reduce端輸出的Key類型必須實現DBWritable接口
job.setOutputKeyClass(Class<? extends DBWritable>);

Writable和DBWritable用法

Writable:當自定義Map端輸出Value類型,必須實現Writable接口,因爲框架將會對Map的輸出做本地磁盤的序列化。如果用戶需要自定義Map端輸出key類型,和值類型相比較多個排序的需求因此如果用戶需要自定map端的輸出key類型,必須實現WritableComparable接口。

DBWriteable:當用戶使用DBOutputFormat時候,強制要求Reducer端的輸出key類型必須實現DBWriteable接口,此時需要用戶實現write方法給?賦值。通過使用DBOutputFormat可以獲知,Reducer端輸出的Key-Value類型所限與用戶使用的OutputFormat。因此Reduce端的輸出key-value類型和Writable接口沒有任何關係。

Jar包依賴問題

  • 運行時依賴(Yarn Child依賴)

方案1

要求用戶將依賴的jar包拷貝給所有的計算節點(NodeManager運行所在主機)

[root@CentOS ~]# hadoop jar  xxx.jar 入口類  -libjars 依賴jar包1,依賴jar包2,....

方案2

[root@CentOS ~]# hdfs dfs -mkdir /libs
[root@CentOS ~]# hdfs dfs -put mysql-connector-java-5.1.46.jar /libs
conf.setStrings("tmpjars","/libs/xxx1.jar,/libs/xxx2.jar,...");
  • 提交時依賴(client node)

需要用戶配置HADOOP_CLASSPATH環境變量(/root/.bashrc),通常這種依賴發生在切片計算階段。

HADOOP_CLASSPATH=/root/mysql-connector-java-5.1.46.jar
export HADOOP_CLASSPATH
[root@CentOS ~]# source .bashrc 
[root@CentOS ~]# hadoop classpath #查看hadoop的類路徑
/usr/hadoop-2.6.0/etc/hadoop:/usr/hadoop-2.6.0/share/hadoop/common/lib/*:/usr/hadoop-2.6.0/share/hadoop/common/*:/usr/hadoop-2.6.0/share/hadoop/hdfs:/usr/hadoop-2.6.0/share/hadoop/hdfs/lib/*:/usr/hadoop-2.6.0/share/hadoop/hdfs/*:/usr/hadoop-2.6.0/share/hadoop/yarn/lib/*:/usr/hadoop-2.6.0/share/hadoop/yarn/*:/usr/hadoop-2.6.0/share/hadoop/mapreduce/lib/*:/usr/hadoop-2.6.0/share/hadoop/mapreduce/*:`/root/mysql-connector-java-5.1.46.jar`:/usr/hadoop-2.6.0/contrib/capacity-scheduler/*.jar

案例參考 DBInputFormat案例。

任務提交源碼追蹤

在這裏插入圖片描述

job.waitForCompletion(true);
    submit
    	final JobSubmitter submitter =  getJobSubmitter(fs, yarn);
		submitter.submitJobInternal(Job.this, cluster);
				 checkSpecs(job);//檢查輸出目錄是否爲null
 				 JobID jobId = submitClient.getNewJobID();//獲取jobid
				 copyAndConfigureFiles(job, submitJobDir);//拷貝代碼片段以及依賴jars
 				 int maps = writeSplits(job, submitJobDir);//計算切片
  				 writeConf(conf, submitJobFile);//生成job.xml
				 submitClient.submitJob(jobId, submitJobDir,...);
					 ApplicationSubmissionContext appContext =
      createApplicationSubmissionContext(conf, jobSubmitDir, ts);//構建MR AP所需信息
			         resMgrDelegate.submitApplication(appContext);//任務提交

OutputFormat(Redis)

RedisOutpoutFormat

public class RedisOutpoutFormat extends OutputFormat<String,String> {
    public RecordWriter<String, String> getRecordWriter(TaskAttemptContext context) throws IOException, InterruptedException {
        Configuration conf = context.getConfiguration();
        RedisConfiguration redisConf = new RedisConfiguration(conf);
        return new RedisHashRecordWriter(redisConf.getHost(),redisConf.getPort(),redisConf.getDescriptKey());
    }

    public void checkOutputSpecs(JobContext context) throws IOException, InterruptedException { }

    public OutputCommitter getOutputCommitter(TaskAttemptContext context) throws IOException, InterruptedException {
        return new FileOutputCommitter(FileOutputFormat.getOutputPath(context),
                context);
    }
}

RedisHashRecordWriter

public class RedisHashRecordWriter extends RecordWriter<String,String> {
    private Jedis jedis;
    private String descriptKey;
    private Pipeline pipeline;

    public RedisHashRecordWriter(String host,int port,String descriptKey) {
        this.jedis = new Jedis(host,port);
        pipeline=jedis.pipelined();
        this.descriptKey=descriptKey;
    }

    public void write(String key, String value) throws IOException, InterruptedException {
        //啓用Redis的批處理
        pipeline.hset(descriptKey,key,value);
    }

    public void close(TaskAttemptContext context) throws IOException, InterruptedException {
        pipeline.sync();//批量提交
        jedis.close();//關閉鏈接
    }
}

RedisConfiguration

public class RedisConfiguration {
    private Configuration conf;

    public RedisConfiguration(Configuration conf) {
        this.conf = conf;
    }

    public static final String REDIS_HOST="redis.host";
    public static final String REDIS_PORT="redis.port";
    public static final String REDIS_DESCRIPT_KEY="redis.descriptKey";

    public static void configRedis(Configuration conf,String host,int port,String descriptKey){
        conf.set(REDIS_HOST,host);
        conf.setInt(REDIS_PORT,port);
        conf.set(REDIS_DESCRIPT_KEY,descriptKey);
    }

    public String getHost(){
        return conf.get(REDIS_HOST);
    }
    public int getPort(){
        return conf.getInt(REDIS_PORT,6379);
    }
    public String getDescriptKey(){
        return conf.get(REDIS_DESCRIPT_KEY);
    }


}

代碼中使用如下

public class CustomJobSubmitter extends Configured implements Tool {
    public int run(String[] strings) throws Exception {
        //1.封裝Job對象\
        Configuration conf = getConf();
        RedisConfiguration.configRedis(conf,
                                       "CentOS",
                                       6379,
                                       "url_click");
        Job job=Job.getInstance(conf);
        //2.設置任務的讀取、寫出數據格式
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(RedisOutpoutFormat.class);
        //3.設置數據讀入和寫出路徑
        Path src = new Path("file:///D:/demo/click");
        TextInputFormat.addInputPath(job,src);
        //4.設置數據處理邏輯代碼片段
        job.setMapperClass(ClickMappper.class);
        job.setReducerClass(ClickReducer.class);
        //5.設置Mapper和Reducer輸出key-value類型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(String.class);
        job.setOutputValueClass(String.class);
        //6.任務提交
        //job.submit();
        job.waitForCompletion(true);
        return 0;
    }
    public static void main(String[] args) throws Exception {
        ToolRunner.run(new CustomJobSubmitter(),args );
    }
}

Shuffle&任務調優

NumReduceTask = 0

在這裏插入圖片描述

public class CustomJobSubmitter extends Configured implements Tool {
    public int run(String[] strings) throws Exception {
        //1.封裝Job對象
        Job job=Job.getInstance(getConf());

        //2.設置任務的讀取、寫出數據格式
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);
        //3.設置數據讀入和寫出路徑
        Path src = new Path("file:///D:/demo/click");
        TextInputFormat.addInputPath(job,src);

        Path dst = new Path("file:///D:/demo/result");//必須不存在,否則任務提交失敗
        TextOutputFormat.setOutputPath(job,dst);
        //4.設置數據處理邏輯代碼片段
        job.setMapperClass(ClickMappper.class);
        //5.設置Mapper和Reducer輸出key-value類型
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);

        job.setNumReduceTasks(0);//設置NumReducecTask 0
        //6.任務提交
        //job.submit();
        job.waitForCompletion(true);
        return 0;
    }
    public static void main(String[] args) throws Exception {
        ToolRunner.run(new CustomJobSubmitter(),args );
    }
}

NumReduceTask = 3

在這裏插入圖片描述

  • 如何幹預MapReduce分區策略?
job.setPartitionerClass(...)
  • MapReduce輸出特點是什麼?

分區內部有序,默認按照Map端輸出key的升序

  • 什麼是Mapreduce數據傾斜?

是因爲選取的Key不合理,到時分區數據分佈不均勻。在任務計算第二階段Reduce計算帶來壓力。

  • Reduce並行度是靠什麼決定的?和Map端計算區別是什麼?

Map端並行度是通過計算任務切片決定的,Reduce端是通過job.setNumReduceTask(n)

MapReduce調優策略

  • 避免小文件計算,適當線下合併
  • 調整環裝緩衝區的參數,減少Map任務的IO操作
  • 開啓Map段壓縮
conf.setBoolean("mapreduce.map.output.compress",true);
conf.setClass("mapreduce.map.output.compress.codec", GzipCodec.class, CompressionCodec.class);
  • 如果條件允許,可以考慮在Map端預執行Reduce邏輯-Map端的Combiner

是一種針對Mapshuffle的優化,主要是通過在Map端本地支持局部Reduce操作,該操作可以極大減輕網絡IO佔用,減少key的排序量,但是並不是所有的操作都支持Combiner:

  • Combiner默認不會開啓,需要程序員編碼設置
  • 要求Combiner不可以改變Map端最終的輸出key-value類型(Combiner輸入和輸出類型一致)
  • 必須滿足計算支持迭代,例如:求和、最大值、最小值 ,但是 平均值就不適用
job.setCombinerClass(ClickCombiner.class);
----
public class ClickCombiner extends Reducer<Text, IntWritable,Text,IntWritable> {
        @Override
        protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
            System.out.println("--ClickCombiner---");
            int total=0;
            for (IntWritable value : values) {
                total += value.get() ;
            }
            context.write(key,new IntWritable(total));
        }
}
  • 適當調整NodeManager管理Container的個數和內存大小
yarn.nodemanager.resource.cpu-vcores = 8
yarn.nodemanager.resource.memory-mb = 8192 

Map Reduce 使用場景

  • 網絡日誌清洗數據 ETL (Extract Transfer Load),一般這種操作不需要Reduce即可完成
  • 基於大數據數據統計和報表 求最大、求最小、求平均 使用柱狀圖、餅狀圖展示。
  • 畫像生成-爲後續AI學習提供計算所需數據模型 特徵向量 線性迴歸|邏輯迴歸

杯子-畫像

容量 材質 顏色 是否保溫 口徑 品牌
陶瓷 10CM xx

身高 體重 顏值 年齡 性別 收入 消費
178 130 10 25 true 100W 50W
  • 個性化推薦 通過MapReduce 生成算法所需數據樣本

    • 基於用戶的協同推薦算法
    • 基於物品協同過濾算法(比較多)

    數據格式(MapReduce ETL或者統計得來)

    userid/itemid/score

1,101,5.0
1,102,3.0
1,103,2.5
2,101,2.0
2,102,2.5
2,103,5.0
2,104,2.0
3,101,2.5
3,104,4.0
3,105,4.5
3,107,5.0
4,101,5.0
4,103,3.0
4,104,4.5
4,106,4.0
5,101,4.0
5,102,3.0
5,103,2.0
5,104,4.0
5,105,3.5
5,106,4.0
  • 安裝Mahout(下載Mahout算法庫)
[root@CentOS ~]# tar -zxf apache-mahout-distribution-0.13.0.tar.gz -C /usr/

  • 將準備好的數據存儲到/recomand
  • 調用Mahout的推薦算法(MapReduce任務實現的算法,該算法分爲4個階段,共計9個MapReduce任務)
[root@CentOS ~]# hadoop jar /usr/apache-mahout-distribution-0.13.0/mahout-mr-0.13.0-job.jar org.apache.mahout.cf.taste.hadoop.item.RecommenderJob --input /recomand --output /recomand-out -s SIMILARITY_LOGLIKELIHOOD
1	[104:2.8088317,106:2.5915816,105:2.5748677]
2	[105:3.5743618,106:3.3991857]
3	[103:4.336442,106:4.0915813,102:4.0915813]
4	[102:3.6903737,105:3.6903737]
5	[107:3.663558]

Hadoop HA構建

概述

  • NameNode HA構建 存儲

  • ResourceManager HA構建 計算
    在這裏插入圖片描述

準備工作

  • 安裝三臺CentOS-6.5 64 bit操作系統(完成JDK、SSH免密碼認證、IP主機名映射、關閉防火牆等工作)

主機和服務啓動映射表

主機 服務
CentOSA NameNode、zkfc、DataNode、JournalNode、Zookeeper、NodeManager
CentOSB NameNode、zkfc、DataNode、JournalNode、Zookeeper、NodeManager、ResourceManager
CentOSC DataNode、JournalNode、Zookeeper、NodeManager、ResourceManager

主機信息

主機名 IP信息
CentOSA 192.168.40.129
CentOSB 192.168.40.130
CentOSC 192.168.40.131

JDK安裝和配置

[root@CentOSX ~]# rpm -ivh jdk-8u171-linux-x64.rpm
[root@CentOSX ~]# vi .bashrc
JAVA_HOME=/usr/java/latest
PATH=$PATH:$JAVA_HOME/bin
CLASSPATH=.
export JAVA_HOME
export CLASSPATH
export PATH
[root@CentOSX ~]# source .bashrc

IP主機名映射

[root@CentOSX ~]# vi /etc/hosts

192.168.40.129 CentOSA
192.168.40.130 CentOSB
192.168.40.131 CentOSC

關閉防火牆

[root@CentOSX ~]# service iptables stop
iptables: Setting chains to policy ACCEPT: filter          [  OK  ]
iptables: Flushing firewall rules:                         [  OK  ]
iptables: Unloading modules:                               [  OK  ]
[root@CentOSX ~]# chkconfig iptables off

SSH免密碼認證

[root@CentOSX ~]# ssh-keygen -t rsa
[root@CentOSX ~]# ssh-copy-id CentOSA
[root@CentOSX ~]# ssh-copy-id CentOSB
[root@CentOSX ~]# ssh-copy-id CentOSC

Zookeeper

[root@CentOSX ~]# tar -zxf zookeeper-3.4.6.tar.gz -C /usr/
[root@CentOSX ~]# mkdir /root/zkdata

[root@CentOSA ~]# echo 1 >> /root/zkdata/myid
[root@CentOSB ~]# echo 2 >> /root/zkdata/myid
[root@CentOSC ~]# echo 3 >> /root/zkdata/myid

[root@CentOSX ~]# touch /usr/zookeeper-3.4.6/conf/zoo.cfg
[root@CentOSX ~]# vi /usr/zookeeper-3.4.6/conf/zoo.cfg
tickTime=2000
dataDir=/root/zkdata
clientPort=2181
initLimit=5
syncLimit=2
server.1=CentOSA:2887:3887
server.2=CentOSB:2887:3887
server.3=CentOSC:2887:3887

[root@CentOSX ~]# /usr/zookeeper-3.4.6/bin/zkServer.sh start zoo.cfg
[root@CentOSX ~]# /usr/zookeeper-3.4.6/bin/zkServer.sh status zoo.cfg
JMX enabled by default
Using config: /usr/zookeeper-3.4.6/bin/../conf/zoo.cfg
Mode: `follower|leader`
[root@CentOSX ~]# jps
5879 `QuorumPeerMain`
7423 Jps

搭建Hadoop 集羣(HDFS)

解壓並配置HADOOP_HOME

[root@CentOSX ~]# tar -zxf hadoop-2.6.0_x64.tar.gz -C /usr/
[root@CentOSX ~]# vi .bashrc
HADOOP_HOME=/usr/hadoop-2.6.0
JAVA_HOME=/usr/java/latest
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
CLASSPATH=.
export JAVA_HOME
export CLASSPATH
export PATH
export HADOOP_HOME
[root@CentOSX ~]# source .bashrc

配置core-site.xml

<!--配置Namenode服務ID-->
<property>		
      <name>fs.defaultFS</name>		
      <value>hdfs://mycluster</value>	
</property>
<property>		
     <name>hadoop.tmp.dir</name>		
     <value>/usr/hadoop-2.6.0/hadoop-${user.name}</value>    
</property>
<property>		
     <name>fs.trash.interval</name>		
     <value>30</value>    
</property>
<!--配置機架腳本-->
<property>		
     <name>net.topology.script.file.name</name>		
     <value>/usr/hadoop-2.6.0/etc/hadoop/rack.sh</value>    
</property>
<!--配置ZK服務信息-->
<property>   
	<name>ha.zookeeper.quorum</name>
	<value>CentOSA:2181,CentOSB:2181,CentOSC:2181</value> 
</property>
<!--配置SSH祕鑰位置-->
<property>
     <name>dfs.ha.fencing.methods</name>
     <value>sshfence</value>
</property>
<property>
     <name>dfs.ha.fencing.ssh.private-key-files</name>
     <value>/root/.ssh/id_rsa</value>
</property>

配置機架腳本

[root@CentOSX ~]# touch /usr/hadoop-2.6.0/etc/hadoop/rack.sh
[root@CentOSX ~]# chmod u+x /usr/hadoop-2.6.0/etc/hadoop/rack.sh
[root@CentOSX ~]# vi /usr/hadoop-2.6.0/etc/hadoop/rack.sh
while [ $# -gt 0 ] ; do
	  nodeArg=$1
	  exec</usr/hadoop-2.6.0/etc/hadoop/topology.data
	  result="" 
	  while read line ; do
		ar=( $line ) 
		if [ "${ar[0]}" = "$nodeArg" ] ; then
		  result="${ar[1]}"
		fi
	  done 
	  shift 
	  if [ -z "$result" ] ; then
		echo -n "/default-rack"
	  else
		echo -n "$result "
	  fi
done
[root@CentOSX ~]# touch /usr/hadoop-2.6.0/etc/hadoop/topology.data
[root@CentOSX ~]# vi /usr/hadoop-2.6.0/etc/hadoop/topology.data
192.168.40.129 /rack01
192.168.40.130 /rack01
192.168.40.131 /rack03

配置hdfs-site.xml

<property>
	<name>dfs.replication</name>
	<value>3</value>
</property> 
<!--開啓自動故障轉移-->
<property>
	<name>dfs.ha.automatic-failover.enabled</name>
	<value>true</value>
</property>
<!--解釋core-site.xml內容-->
<property>
	<name>dfs.nameservices</name>
	<value>mycluster</value>
</property>
<property>
	<name>dfs.ha.namenodes.mycluster</name>
	<value>nn1,nn2</value>
</property>
<property>
	<name>dfs.namenode.rpc-address.mycluster.nn1</name>
	<value>CentOSA:9000</value>
</property>
<property>
	 <name>dfs.namenode.rpc-address.mycluster.nn2</name>
	 <value>CentOSB:9000</value>
</property>
<!--配置日誌服務器的信息-->
<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://CentOSA:8485;CentOSB:8485;CentOSC:8485/mycluster</value>
</property>
<!--實現故障轉切換的實現類-->
<property>
	<name>dfs.client.failover.proxy.provider.mycluster</name>
	<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>

配置slaves

CentOSA
CentOSB
CentOSC

啓動HDFS(集羣初始化啓動)

[root@CentOSX ~]# hadoop-daemon.sh start journalnode (等待10s鍾)
[root@CentOSA ~]# hdfs namenode -format
[root@CentOSA ~]# hadoop-daemon.sh start namenode
[root@CentOSB ~]# hdfs namenode -bootstrapStandby
[root@CentOSB ~]# hadoop-daemon.sh start namenode
#註冊Namenode信息到zookeeper中,只需要在CentOSA或者B上任意一臺執行一下指令
[root@CentOSA|B ~]# hdfs zkfc -formatZK
[root@CentOSA ~]# hadoop-daemon.sh start zkfc
[root@CentOSB ~]# hadoop-daemon.sh start zkfc
[root@CentOSX ~]# hadoop-daemon.sh start datanode

查看機架信息

[root@CentOSB ~]# hdfs dfsadmin -printTopology
Rack: /rack01
   192.168.40.129:50010 (CentOSA)
   192.168.40.130:50010 (CentOSB)

Rack: /rack03
   192.168.40.131:50010 (CentOSC)

Resource Manager搭建

yarn-site.xml

<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>
<property>
    <name>yarn.resourcemanager.ha.enabled</name>
    <value>true</value>
</property>
<property>
    <name>yarn.resourcemanager.cluster-id</name>
    <value>cluster</value>
</property>
<property>
    <name>yarn.resourcemanager.ha.rm-ids</name>
    <value>rm1,rm2</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm1</name>
    <value>CentOSB</value>
</property>
<property>
    <name>yarn.resourcemanager.hostname.rm2</name>
    <value>CentOSC</value>
</property>
<property>
    <name>yarn.resourcemanager.zk-address</name>
    <value>CentOSA:2181,CentOSB:2181,CentOSC:2181</value>
</property>

mapred-site.xml

<property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
</property>

啓動|關閉Yarn服務

[root@CentOSB ~]# yarn-daemon.sh start|stop resourcemanager
[root@CentOSC ~]# yarn-daemon.sh start|stop resourcemanager
[root@CentOSX ~]# yarn-daemon.sh start|stop nodemanger

更多精彩內容關注

微信公衆賬號

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