作者:jiangzz
電話:15652034180
微信:jiangzz_wx
微信公衆賬號:jiangzz_wy
大數據(Big Data)
隨着信息化互聯網|物聯網發展要求,萬物互聯趨勢勢在必行。隨之引發架構的演變由單一架構向高併發分佈式架構演變。數據的存儲也開始由原始的單機存儲演變爲分佈式存儲。
- 高併發互聯網設計 LNMP、數據庫主從RDBMS|NoSQL、Spring Cloud、Dubbo – 應用架構
- 海量數據存儲|數據分析 :存儲方案(HDFS)、計算方案(Map Reduce、
Storm
、Spark
、Flink
)
- 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 System
和MapReduce: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