HDFS文件系統(tǒng)
HDFS是一個分布式文件系統(tǒng),采用分而治之的設計思想哼勇,將大文件个初、大批量文件,分布式存放在大量服務器上猴蹂,為各類分布式運算框架(MapReduce,spark楣嘁,tez等)提供數(shù)據(jù)存儲服務磅轻。首先,它是一個文件系統(tǒng)逐虚,用于存儲文件聋溜,通過統(tǒng)一的命名空間目錄樹來定位文件,對用戶來說叭爱,DataNode是透明的撮躁,HDFS相當于是提供了一個統(tǒng)一的目錄結構,用戶上傳的文件的適合买雾,只需要和這個統(tǒng)一的目錄結構打交道把曼,雖然實際上用戶的文件被切成不同的block存放在了不同的DataNode上,這部分元信息被存放在NameNode中漓穿;其次嗤军,它是分布式的,由很多服務器聯(lián)合起來實現(xiàn)其功能晃危,集群中的服務器有各自的角色叙赚。
虛擬機網(wǎng)絡配置
HDFS
基本特性
適合用來做數(shù)據(jù)分析,并不適合用來做網(wǎng)盤應用僚饭,因為震叮,不便修改,延遲大鳍鸵,網(wǎng)絡開銷大苇瓣,成本太高
- HDFS中的文件在物理上是分塊存儲(block),塊的大小可以通過配置參數(shù)(dfs.blocksize)來規(guī)定权纤,默認大小在hadoop2.x版本中是128M钓简,老版本中是64M乌妒;
- HDFS文件系統(tǒng)會給客戶端提供一個統(tǒng)一的抽象目錄樹,客戶端通過路徑來訪問文件外邓,形如:hdfs://namenode:port/dir-a/dir-b/dir-c/file.data撤蚊;
- 目錄結構及文件分塊信息(元數(shù)據(jù))的管理由NameNode節(jié)點承擔。NameNode是HDFS集群主節(jié)點损话,負責維護整個hdfs文件系統(tǒng)的目錄樹侦啸,以及每一個路徑(文件)所對應的block塊信息(block的id,及所在的DataNode服務器)丧枪;
- 文件的各個block的存儲管理由DataNode節(jié)點承擔光涂。DataNode是HDFS集群從節(jié)點,每一個block都可以在多個DataNode上存儲多個副本(副本數(shù)量也可以通過參數(shù)設置dfs.replication)拧烦;
- HDFS是設計成適應一次寫入忘闻,多次讀出的場景,且不支持文件的修改恋博;
常見命令
// 列出文件
hadoop fs -ls /
// 創(chuàng)建目錄
hadoop fs -mkdir 目錄名稱
// 查看文件
hadoop fs -cat 文件名稱
// 刪除文件或文件夾
hadoop fs -rm -r /aaa/bbb/
// 從本地文件系統(tǒng)中拷貝文件到hdfs路徑去
hadoop fs -copyFromLocal ./jdk.tar.gz /aaa/
// 上傳齐佳,等同于copyFromLocal
hadoop fs -put /aaa/jdk.tar.gz /bbb/jdk.tar.gz.2
// 從hdfs拷貝到本地
hadoop fs -copyToLocal /aaa/jdk.tar.gz
// 從hdfs下載文件到本地,等同于copyToLocal
hadoop fs -get /aaa/jdk.tar.gz
// 統(tǒng)計文件系統(tǒng)的可用空間信息
hadoop fs -df -h /
// 統(tǒng)計文件夾的大小信息
hadoop fs -du -s -h /aaa/*
// 統(tǒng)計一個指定目錄下的文件節(jié)點數(shù)量
hadoop fs -count /aaa/
// 設置hdfs中文件的副本數(shù)量债沮,這里設置的副本數(shù)只是記錄在NameNode的元數(shù)據(jù)中炼吴,是否真的會有這么多副本,還得看DataNode的數(shù)量
hadoop fs -setrep 3 /aaa/jdk.tar.gz
常用參數(shù)
hdfs-site.xml
// 每個block塊的大小疫衩,默認128M
dfs.blocksize
// 文件副本個數(shù)
dfs.replication
工作機制
- HDFS集群分為兩大角色:NameNode硅蹦、DataNode;
- NameNode負責管理整個文件系統(tǒng)的元數(shù)據(jù)闷煤;
- DataNode負責管理用戶的文件數(shù)據(jù)塊童芹;
- 文件會按照固定的大小(blocksize)切成若干塊后分布式存儲在若干臺DataNode上;
- 每一個文件塊可以有多個副本曹傀,并存放在不同的DataNode上辐脖;
- DataNode會定期向NameNode匯報自身所保存的文件block信息,而NameNode則會負責保持文件的副本數(shù)量皆愉;
- HDFS的內(nèi)部工作機制對客戶端保持透明嗜价,客戶端請求訪問HDFS都是通過向NameNode申請來進行;
NameNode機制
NameNode職責:負責客戶端請求的響應幕庐;元數(shù)據(jù)的管理(查詢久锥,修改);
NameNode對數(shù)據(jù)的管理采用了三種存儲形式:
- 內(nèi)存元數(shù)據(jù)(NameSystem)异剥;
- 磁盤元數(shù)據(jù)鏡像文件瑟由;
- 數(shù)據(jù)操作日志文件(可通過日志運算出元數(shù)據(jù));
元數(shù)據(jù)管理機制
- 內(nèi)存中有一份完整的元數(shù)據(jù):內(nèi)存meta data冤寿;
- 磁盤有一個“準完整”的元數(shù)據(jù)鏡像:fsimage歹苦,文件存在于NameNode的工作目錄中青伤;
- 用于銜接內(nèi)存metadata和持久化元數(shù)據(jù)鏡像fsimage之間的操作日志:edits文件,當客戶端對HDFS中的文件進行新增或者修改操作殴瘦,操作記錄首先被記入edits日志文件中狠角,當客戶端操作成功后,相應的元數(shù)據(jù)會更新到內(nèi)存meta.data中蚪腋;
元數(shù)據(jù)checkpoint
每隔一段時間丰歌,會由SecondaryNameNode將NameNode上積累的所有edits和一個最新的fsimage下載到本地,并加載到內(nèi)存進行merge屉凯,這個過程稱為checkpoint立帖。
NameNode和SecondaryNameNode的工作目錄存儲結構完全相同,所以悠砚,當NameNode故障退出需要重新恢復時晓勇,可以從SecondaryNameNode的工作目錄中將fsimage拷貝到NameNode的工作目錄值依,以恢復NameNode的元數(shù)據(jù)役首。
checkpoint參數(shù)
dfs.namenode.checkpoint.check.period=60 #檢查觸發(fā)條件是否滿足的頻率,60秒
dfs.namenode.checkpoint.dir=file://${hadoop.tmp.dir}/dfs/namesecondary
#以上兩個參數(shù)做checkpoint操作時辩棒,secondary namenode的本地工作目錄
dfs.namenode.checkpoint.edits.dir=${dfs.namenode.checkpoint.dir}
dfs.namenode.checkpoint.max-retries=3 #最大重試次數(shù)
dfs.namenode.checkpoint.period=3600 #兩次checkpoint之間的時間間隔3600秒
dfs.namenode.checkpoint.txns=1000000 #兩次checkpoint之間最大的操作記錄
DataNode機制
Datanode工作職責:存儲管理用戶的文件塊數(shù)據(jù)节榜;定期向NameNode匯報自身所持有的block信息(通過心跳信息上報),這點很重要别智,因為當集群中發(fā)生某些block副本失效時宗苍,集群如何恢復block初始副本數(shù)量的問題。
<property>
<name>dfs.blockreport.intervalMsec</name>
<value>3600000</value>
<description>Determines block reporting interval in milliseconds.</description>
</property>
DataNode掉線判斷時限參數(shù)
DataNode進程死亡或者網(wǎng)絡故障造成DataNode無法與NameNode通信薄榛,NameNode不會立即把該節(jié)點判定為死亡讳窟,要經(jīng)過一段時間,這段時間暫稱作超時時長敞恋。HDFS默認的超時時長為10分鐘+30秒丽啡。如果定義超時時間為timeout,則超時時長的計算公式為:
timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval
而默認的heartbeat.recheck.interval 大小為5分鐘硬猫,dfs.heartbeat.interval默認為3秒补箍。
需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的單位為毫秒,dfs.heartbeat.interval的單位為秒啸蜜。所以坑雅,舉個例子,如果heartbeat.recheck.interval設置為5000(毫秒)衬横,dfs.heartbeat.interval設置為3(秒裹粤,默認),則總的超時時間為40秒蜂林。
<property>
<name>heartbeat.recheck.interval</name>
<value>2000</value>
</property>
<property>
<name>dfs.heartbeat.interval</name>
<value>1</value>
</property>
文件上傳機制
用戶上傳的文件遥诉,被切成諾干個block塊存放在不同的DataNode中拇泣,并且每個文件都會在集群中存儲多個文件副本,副本的數(shù)量可以由用戶指定矮锈。至于文件被切成多少個block快霉翔,每個塊在哪臺DataNode上,這部分元信息存儲在NameNode中愕难。
客戶端要向HDFS寫數(shù)據(jù)早龟,首先要跟NameNode通信以確認可以寫文件并獲得接收文件block的DataNode,然后猫缭,客戶端按順序?qū)⑽募饌€block傳遞給相應DataNode葱弟,并由接收到block的DataNode負責向其他DataNode復制block的副本。
- 根NameNode通信請求上傳文件猜丹,NameNode檢查目標文件是否已存在芝加,父目錄是否存在;
- NameNode返回是否可以上傳射窒;
- client請求第一個block該傳輸?shù)侥男ヾatanode服務器上藏杖;
- NameNode返回3個DataNode服務器ABC;
- client請求3臺dn中的一臺A上傳數(shù)據(jù)(本質(zhì)上是一個RPC調(diào)用脉顿,建立pipeline)蝌麸,A收到請求會繼續(xù)調(diào)用B,然后B調(diào)用C艾疟,將真?zhèn)€pipeline建立完成来吩,逐級返回客戶端;
- client開始往A上傳第一個block(先從磁盤讀取數(shù)據(jù)放到一個本地內(nèi)存緩存)蔽莱,以packet為單位弟疆,A收到一個packet就會傳給B,B傳給C盗冷;A每傳一個packet會放入一個應答隊列等待應答怠苔;
- 當一個block傳輸完成之后,client再次請求NameNode上傳第二個block的服務器仪糖;
文件下載機制
客戶端將要讀取的文件路徑發(fā)送給NameNode柑司,NameNode獲取文件的元信息(主要是block的存放位置信息)返回給客戶端,客戶端根據(jù)返回的信息找到相應DataNode逐個獲取文件的block并在客戶端本地進行數(shù)據(jù)追加合并從而獲得整個文件锅劝。
- 跟NameNode通信查詢元數(shù)據(jù)帜羊,找到文件塊所在的DataNode服務器;
- 挑選一臺DataNode(就近原則鸠天,然后隨機)服務器讼育,請求建立socket流;
- DataNode開始發(fā)送數(shù)據(jù)(從磁盤里面讀取數(shù)據(jù)放入流,以packet為單位來做校驗)奶段;
- 客戶端以packet為單位接收饥瓷,現(xiàn)在本地緩存,然后寫入目標文件痹籍;
HDFS客戶端編程場景
- 數(shù)據(jù)采集
YARN
運算資源調(diào)度呢铆。
MapReduce程序應該是在很多機器上并行啟動,而且先執(zhí)行MapTask蹲缠,當眾多的MapTask都處理完自己的數(shù)據(jù)后棺克,還需要啟動眾多的ReduceTask,這個過程如果用用戶自己手動調(diào)度不太現(xiàn)實线定,需要一個自動化的調(diào)度平臺娜谊,hadoop中就為運行MapReduce之類的分布式運算程序開發(fā)了一個自動化調(diào)度平臺:YARN。
YARN集群中有兩個角色:1臺 ResourceManager 和 N臺 NodeManager斤讥。ResourceManager一般安裝在一臺專門的機器上纱皆,NodeManager應該與HDFS中的DataNode重疊在一起。
yarn-site.xml
<property>
<name>yarn.resourcemanager.hostname</name>
<value>hdp-04</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
Linux環(huán)境準備
接下來主要介紹Hadoop集群環(huán)境的搭建過程芭商,實際應用中應該不會這樣做派草,而是通過一些管理工具進行安裝,比如可視化安裝:Ambari铛楣。
前置條件
CentOS7
Oracle VM VirtualBox
安裝過程
這就相當于通過虛擬機搭建一個局域網(wǎng)近迁,安裝配置過程已經(jīng)截圖并整理成PPT。主要需要注意的地方就是網(wǎng)絡的配置簸州,我這里通過配置兩個網(wǎng)卡來實現(xiàn):一個用于訪問外部網(wǎng)絡(NAT)钳踊;一個用于和window主機交互(Host-Only)。
我的系統(tǒng)是centos7
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3
配置文件修改成以下內(nèi)容
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
NAME=enp0s3
UUID=4704faea-0e23-4ad9-a06c-3e37e577636c
DEVICE=enp0s3
ONBOOT=yes
NM_CONTROLLED=yes
IPADDR=192.168.88.21
虛擬機安裝過程
基礎配置
添加用戶
分別在三臺服務器上執(zhí)行創(chuàng)建 haddop用戶勿侯,同時設置密碼為hadoop
useradd hadoop
passwd hadoop
創(chuàng)建用戶之后切換為hadoop用戶登錄,我們所有的操作都基于hadoop用戶
配置host
分別在三臺服務器配置host
vi /etc/hosts
添加以下內(nèi)容
192.168.88.21 master
192.168.88.22 slave1
192.168.88.23 slave2
配置免密登錄
分別在三臺機器上安裝 openssh-server
yum install openssh-server
分別在三臺機器上執(zhí)行以下命令
mkdir .ssh
chmod 700 .ssh
ssh-keygen -t rsa
cp id_rsa.pub authorized_keys
chmod 600 authorized_keys
在 22 服務器執(zhí)行
scp /home/hadoop/.ssh/id_rsa.pub hadoop@master:/home/hadoop/.ssh/id_rsa.pub.slave1
在 23 服務器執(zhí)行
scp /home/hadoop/.ssh/id_rsa.pub hadoop@master:/home/hadoop/.ssh/id_rsa.pub.slave2
在 21 服務器執(zhí)行
cat id_rsa.pub.slave1 >> authorized_keys
cat id_rsa.pub.slave2 >> authorized_keys
scp /home/hadoop/.ssh/authorized_keys hadoop@slave1:/home/hadoop/.ssh/authorized_keys
scp /home/hadoop/.ssh/authorized_keys hadoop@slave2:/home/hadoop/.ssh/authorized_keys
至此配置完成缴罗,接下來是測試:
在 21 服務器執(zhí)行
ssh salve1
ssh salve2
有個問題助琐,之前配置好了之后還是不停提示要輸入密鑰,然后安裝了 openssh-server 之后面氓,再測試就可以了兵钮,不知道是不是這個的影響。
配置JDK
jdk-8u171-linux-x64.tar.gz
在/home/hadoop 目錄下創(chuàng)建java文件夾
mkdir java
在java 目錄內(nèi)解壓安裝包
tar -zxvf jdk-8u171-linux-x64.tar.gz
然后分別拷貝到兩臺slave
scr -r jdk1.8 hadoop@slave1:/home/hadoop
scr -r jdk1.8 hadoop@slave2:/home/hadoop
分別在三臺機器上配置JAVA_HOME
export JAVA_HOME=/home/hadoop/jdk1.8
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar
:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
測試:
執(zhí)行 java -version 看控制臺輸出
其它配置
修改windos下的hosts文件舌界,因為到時候再瀏覽器上訪問的時候會用到域名
C:\WINDOWS\System32\drivers\etc\hosts
192.168.88.21 master
192.168.88.22 slave1
192.168.88.23 slave2
修改linux系統(tǒng)的hostname掘譬,注意不是修改/etc/hoss文件,centos7永久修改hostname使用以下命令
hostnamectl set-hostname 名稱
安裝Hadoop
下載安裝
1呻拌、官網(wǎng)下載葱轩,這個地址下載有點慢
2、以下的地址下載更快一些
http://mirror.bit.edu.cn/apache/
http://mirror.bit.edu.cn/apache/
https://mirrors.tuna.tsinghua.edu.cn/apache/
我最終下載的版本是:hadoop-2.7.6.tar.gz
安裝過程很簡單,只需要直接解壓就可以了靴拱。
三臺機器機器最終的配置基本一樣垃喊,所以我們只需要在一臺機器上配置好,然后拷貝到其它機器就好袜炕, 這里是在master機器上配置本谜。
在master上執(zhí)行以下命令
cd /home/Hadoop
mkdir -p cludata/hadoop
cd cludata/hadoop
mkdir -p hdfs/data hdfs/name temp
tar -zxvf hadoop-2.7.6.tar.gz
HADOOP_HOME
就是配置hadoop環(huán)境變量,這個需要在三臺機器上分別執(zhí)行
vi ~/.bash_profile
export HADOOP_HOME=/home/hadoop/hadoop-2.7.6
export PATH=$PATH:$JAVA_HOME/bin::$HADOOP_HOME/bin:$HADOOP_HOME/sbin
配置文件
主要需要配置以下幾個配置文件:core-site.xml偎窘、hdfs-site.xml乌助、mapred-site.xml和yarn-site.xml、slaves陌知。然后可能還需要再hadoop-env.sh中添加JAVA環(huán)境變量他托。
以下配置文件可作為參考,還有很多其它配置項纵诞。
- core-site.xml
該配置文件主要用于定義系統(tǒng)級別的參數(shù)上祈,如HDFS、URL浙芙、hadoop的臨時目錄
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://master:9000</value>
<description>文件系統(tǒng)主機和端口</description>
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
<description>每個block的大小</description>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/home/hadoop/cludata/hadoop/temp</value>
<description>臨時目錄</description>
</property>
</configuration>
- dfs-site.xml
<configuration>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>master:9001</value>
<description>通過web界面來查看HDFS狀態(tài)</description>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/home/hadoop/cludata/hadoop/hdfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/home/hadoop/cludata/hadoop/hdfs/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
<description>每個Block有2個備份</description>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
<description>是否通過http協(xié)議訪問hdfs文件</description>
</property>
</configuration>
- mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
</property>
<property>
<name>mapreduce.jobhistory.webapp.address</name>
<value>master:19888</value>
</property>
</configuration>
- yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
<property>
<name>yarn.nodemanager.aux-services.mapreduce.shuffle.class</name>
<value>org.apache.hadoop.mapred.ShuffleHandler</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>master:8032</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>master:8030</value>
</property>
<property>
<name>yarn.resourcemanager.resource-tracker.address</name>
<value>master:8031</value>
</property>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>master:8033</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>master:8088</value>
</property>
<property>
<name>yarn.nodemanager.resource.memory-mb</name>
<value>8192</value>
</property>
</configuration>
- slaves
這個配置文件主要是配置 datanode
把localhost去掉登刺,添加以下內(nèi)容
slave1
slave2
配置完成之后,將整個hadoop文件夾拷貝到其它兩臺機器
cd /home/hadoop
scp -r hadoop-2.7.6 hadoop@slave1:/home/hadoop/
scp -r hadoop-2.7.6 hadoop@slave2:/home/hadoop/
格式化
在啟動hadoop之前嗡呼,需要先格式化HDFS文件系統(tǒng)纸俭,只需要在master上執(zhí)行即可
hadoop namenode -format
啟動
有關于hadoop的一些腳本命令,存放在根目錄下的sbin 文件夾下:即/home/hadoop /hadoop-2.7.6/sbin
所以南窗,先進入sbin目錄
cd /home/hadoop /hadoop-2.7.6/sbin
- 啟動NameNode
hadoop-daemon.sh start namenode
執(zhí)行該命令后可以通過 ps -ef|grep hadoop 命令查看hadoop進程揍很,也可以使用jsp命令查看JVM進行。運行jsp命令之后万伤,可以可能到 Namenode進程窒悔。
- 啟動DataNode
hadoop-daemon.sh start datanode
在master上執(zhí)行該命令后,在兩臺slave上分別執(zhí)行 jps 命令查看 datanode是否啟動敌买,如果發(fā)現(xiàn) Datanode 進程說明啟動成功简珠。
提示:其實以上兩個啟動過程可以通過一個腳本來啟動,hadoop里面也提供了這個腳本虹钮,也是在sbin目錄中聋庵,只要執(zhí)行這個腳本就可以了
./start-dfs.sh
//對應的停止命令
./stop-dfs.sh
- 啟動ResourceManager
yarn-daemon.sh start resourcemanager
執(zhí)行該命令之后,使用jsp命令可以查看到ResourceManager說明啟動成功芙粱。
- 啟動NodeManager
yarn-daemon.sh start nodemanager
同理祭玉,通過jpps命令可以看到 NodeManage進程。
注意:以上兩個過程也可以通過一個腳本來啟動
./start-yarn.sh
//對應的停止命令
./stop-yarn.sh
- 瀏覽器訪問
可以看到以下界面
可以看到以下界面
常見命令
hadoop下有一些常見命令
列出文件:hadoop fs -ls /
創(chuàng)建目錄:hadoop fs -mkdir 目錄
上傳文件:hadoop fs -put filename 目錄
查看文件:hadoop fs -cat 文件
測試案例
啟動之后春畔,可以用hadoop來處理一個demo脱货,這個demo程序是hadoop在安裝包里面已經(jīng)提供了岛都。
hadoop jar /home/hadoop/hadoop-2.7.6/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.6.jar pi 5 10
Pi 5 10 表示開 5個Map , 10 個 Reduce
執(zhí)行這命令之后蹭劈,控制臺會有一系列輸出疗绣,同時在瀏覽器上也可以看到效果
MapReducer
其實上面就是一個Map Reducer 程序,這是官方提供的一個Demo铺韧,不過我們好像并不是很清楚這個程序的運行機制是什么樣的多矮,所以在此之前,有必要了解一下MapReducer哈打。MapReducer可以在任何地方運行程序塔逃,訪問HDFS上的文件并進行統(tǒng)計運算,并且可以把統(tǒng)計的結果寫回HDFS的結果文件中料仗。包括接下來介紹了HIVE湾盗,其實內(nèi)部也是基于MapReducer實現(xiàn),只不過HIVE內(nèi)部進行了大量封裝立轧,所以我們才可以寫SQL語句格粪,其實每條SQL語句,都可以看成是一個MapReducer程序氛改。MapReducer中有兩個概念:Map 和 Reducer帐萎。
Map階段: 將每一行文本數(shù)據(jù)變成<單詞,1>這樣的kv數(shù)據(jù)
Reduce階段:將相同單詞的一組kv數(shù)據(jù)進行聚合:累加所有的v
下面是一個簡單WordCount 示例
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hand.sxy</groupId>
<artifactId>MapReducer</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.6</version>
</dependency>
</dependencies>
</project>
WordCount.java
package com.hand.sxy;
import com.hand.sxy.utils.FileUtil;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;
public class WordCount {
public static void main(String[] args) throws Exception {
FileUtil.deleteDir("/output");
Configuration conf = new Configuration();
String[] otherArgs = new String[]{"hdfs://master:9000/test/dream.txt", "/output"};
if (otherArgs.length != 2) {
System.err.println("Usage:Merge and duplicate removal <in> <out>");
System.exit(2);
}
Job job = Job.getInstance(conf, "WordCount");
job.setJarByClass(WordCount.class);
job.setMapperClass(WordCount.TokenizerMapper.class);
job.setReducerClass(WordCount.IntSumReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(otherArgs[0]));
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
public static final IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
this.word.set(itr.nextToken());
context.write(this.word, one);
}
}
}
public static class IntSumReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
IntWritable val;
for (Iterator i = values.iterator(); i.hasNext(); sum += val.get()) {
val = (IntWritable) i.next();
}
this.result.set(sum);
context.write(key, this.result);
}
}
}
這里面就涉及到了一些API,這個可以自己去網(wǎng)上查胜卤,這里不做過多介紹疆导。
接下來需要做的就是執(zhí)行這個程序,首先葛躏,將這個程序打包成jar澈段,然后上傳服務器
mvn clen install
在hdfs系統(tǒng)上準備好數(shù)據(jù),編輯 dream.txt 文件內(nèi)容如下
Hello bob
I am good
How are you
I am fine
Good good study
上傳dream.txt到hdfs系統(tǒng)
hadoop fs -mkdit /test
hadoop fs -put dream.txt /test/dream.txt
執(zhí)行MapReducer-1.0.jar程序
hadoop jar MapReducer-1.0.jar com.hand.sxy.WordCount
在控制臺和瀏覽器上觀察
瀏覽器打開:http://master:8088/cluster/apps
瀏覽器打開:http://master:50070/explorer.html#/output
程序結果即在hsfs中的 /output/part-r-00000文件中
hadoop fs -cat /output/part-r-00000
輸出的就是每個單詞出現(xiàn)的次數(shù)舰攒,這就是一個最簡單的MapReducer程序败富。
HA集群
hadoop的HA集群,即hadoop的高可用集群配置摩窃,為了解決hadoop中的NameNode單點故障問題兽叮。這個配置的時候比較繁瑣,有空再補上
安裝HIVE
HIVE是在MapReducer上的一層封裝偶芍,通過寫sql方式來實現(xiàn)MapReducer程序。什么意思德玫?就是說大部分情況下匪蟀,有了HIVE之后,不需要再開發(fā)MapReducer程序了宰僧,直接寫HQL即可材彪,大大節(jié)約了時間成本。HIVE非常強大,在創(chuàng)建hie表的時候段化,字段類型用的是java里面的數(shù)據(jù)類型嘁捷,連Map類型都可以用,很強大显熏。
下載安裝
http://mirror.bit.edu.cn/apache/hive/
http://mirrors.hust.edu.cn/apache/hive/
http://mirrors.shu.edu.cn/apache/hive/
http://mirrors.tuna.tsinghua.edu.cn/apache/hive/
安裝位置隨便安裝到那臺機器都都可以雄嚣,先解壓
tax -zxvf apache-hive-1.2.2-bin.tar.gz
6.2. 配置文件
添加一個hive-site.xml配置文件
<configuration>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://centos81:3306/hive?
createDatabaseIfNotExist=true</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
</configuration>
這里其實就是配置hive元數(shù)據(jù)的存放位置,即hive中的數(shù)據(jù)庫名喘蟆、表名缓升、字段等西信息。其實不配置也沒關系蕴轨, hive默認內(nèi)置了一個其它 的數(shù)據(jù)庫港谊。
這里選擇的是mysql數(shù)據(jù)庫,所以還需要提供一個mysql驅(qū)動包橙弱,這里是:mysql-connector-java-5.1.46.jar
啟動
cd hive-1.2.2
bin/hive
如果你已經(jīng)安裝好了mysql歧寺,執(zhí)行這個命令之后,就會在mysql下創(chuàng)建一個hive數(shù)據(jù)庫棘脐。如圖:
之后斜筐,就可以用一些hive的語法了。
常見命令
和我們的sql非常類似
列出數(shù)據(jù)庫:show databases;
創(chuàng)建數(shù)據(jù)庫:create database 數(shù)據(jù)庫名;
使用數(shù)據(jù)庫:use 數(shù)據(jù)庫 名;
創(chuàng)建數(shù)據(jù)表:create table 表名 (xxx);
創(chuàng)建外部表:create external table 表名 (xxx);
創(chuàng)建分區(qū)表:create external table 表名 (xxx) partitioned by (day string);
配置分隔符:在建表語句后面加 row format delimited fields terminated by ',' ;
測試
在hive中新建數(shù)據(jù)庫和表荆残,并在hadoop中上傳文件奴艾,看看在hivez怎么通過sql查出來。
create database tsdb;
use tsdb;
create table t_test1(id int,name string,age int) row format delimited fields terminated by ',';
執(zhí)行以上命令之后内斯,觀察在hadoop中hdfs的目錄
可以看到蕴潦,生成了一個和數(shù)據(jù)庫名相同的文件夾子健无,點進去發(fā)現(xiàn)惋戏,也生成了一個和表名對應的目錄。
vi t_test1.txt
文件內(nèi)容如下:
1,xiaoyong,20
2,gaoxiao,40
3,liuxin,19
上傳這個文件到hdfs
hadoop fs -put t_test1.txt /user/hive/warehouse/tsdb.db/t_test1
在hive控制臺查詢
select * from t_test1;
[圖片上傳失敗...(image-83e835-1535979338058)]
結果已經(jīng)查出來了痴腌。
這本是一個MapReducer程序做的事情真朗,現(xiàn)在一個SQL就搞定了此疹。Hive中還有很多概念,這里就不做過多結算了遮婶。
安裝MySQL
這里安裝MySQL的目的就一個:保存HIVE中的元數(shù)據(jù)蝗碎。在安裝MySQL之前,先裝一個虛擬機旗扑,修改IP蹦骑,修改四臺機器的 /etc/host,這就當作是一臺專用數(shù)據(jù)庫服務器臀防。
更新yum源
下載mysql的yum源:
wget -P /home/lisonglin [http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm](http://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm)
安裝mysql的yum源:
rpm -ivh mysql57-community-release-el7-11.noarch.rpm
安裝
執(zhí)行以下命令眠菇,然后一直按y就可以了
yum install mysql-community-server
啟動測試
啟動服務
systemctl start mysqld
通過mysql客戶但登錄mysql边败,默認是不需要密碼
mysql -uroot
設置密碼
set password = passeord(‘root’);
修改配置文件,這里只修改編碼集捎废,配置文件默認在 /etc/my.cnf
show variables lie ‘character%’;
vi /etc/my.cnf
[mysql]
default-character-set = utf8
[mysqld]
character_set_server = utf8
常用命令
常見的 啟動笑窜、停止、重啟等命令
啟動:systemctl start mysqld
停止:# systemctl stop mysqld
重啟:systemctl restart mysqld
設置開機啟動:systemctl enable mysqld
查看 MySQL Server 狀態(tài):systemctl status mysqld
安裝Zookeeper
Zookeeper是一個基礎組件登疗,主要功能包括:
可以為客戶端管理少量數(shù)據(jù)排截,其中在zookeeeper中數(shù)據(jù)為鍵值格式。其中key類似于文件目錄結構谜叹,但不是目錄
/aa “valuea”
/aa/cc “valueb”
可以為客戶端監(jiān)聽指定數(shù)據(jù)節(jié)點得裝填匾寝,并在數(shù)據(jù)節(jié)點發(fā)生變化時通知客戶端。
應用場景:zookeeeper的應用場景可以非常廣泛荷腊,比如微服務架構中的服務注冊中心艳悔,用于服務上下線動態(tài)感知。zookeeper在hadoop體系中是為了高可用女仰,是為了解決DataNode的單點故障問題猜年;在Hbase中保存了Hbase各個ReginServer和master的信息。
下載安裝
生產(chǎn)環(huán)境一般是部署zookeeper集群疾忍,部署到奇數(shù)臺服務器乔外,一般3臺或者5臺。zookeeper有一個投票選舉機制一罩,所以有個leader 和 flower概念杨幼。
下載地址:http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.4.12/
解壓:tax -zxvf zookeeper-3.4.12.tar.gz
8.2. 配置文件
cd zookeeper-3.4.12/conf
cp zoo_sample.cfg zoo.cfg
vi zoo.cfg
我的配置文件內(nèi)容如下:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/home/hadoop/cludata/zkdata
# the port at which the clients will connect
clientPort=2181
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.21=master:2888:3888
server.22=slave1:2888:3888
server.23=slave2:2888:3888
創(chuàng)建zk數(shù)據(jù)目錄
cd ~
mkdir -p cludata/zkdata
啟動
在三臺服務器下分別執(zhí)行以下命令
cd ~/zookeeper-3.4.12/
bin/zkServer.sh start
在啟動之后可以查看狀態(tài)
bin/zkServer.sh status
啟動腳本
為了方便啟動,提供一個啟動腳本
常見命令
進入客戶端
cd zookeeper-3.4.12
bin/zkCli.sh
//或者連接到其它服務器
bin/zkCli.sh -server slave1:2181
zookeeper 下提供了一些常見客戶端命令
創(chuàng)建節(jié)點:create /aa “value”
查看節(jié)點:ls /
查看數(shù)據(jù):get /aa
修改數(shù)據(jù):set /add “vakue2”
刪除節(jié)點:rmr /aa
監(jiān)聽數(shù)據(jù):get /aa watch
安裝HBASE
HBase是一個基于HDFS的NoSQL數(shù)據(jù)庫聂渊,可以提供數(shù)據(jù)的實時隨機讀寫差购,其中包括的概念有:HMaster、HRegionServer汉嗽、庫名欲逃、表名、行鍵饼暑、列族等稳析,其中HBase集群中的各個節(jié)點信息是維護在zookeeper中的。
下載安裝
下載地址:http://apache.claz.org/hbase/1.2.6.1/
tar -zxvf
HBase中包括兩個角色:HMaster弓叛、HRegionServer彰居。HMaster負責管理HRegionServer,數(shù)據(jù)讀寫交給HRegionServer撰筷。其中陈惰,HRegionServer應該和HDFS中的DataNode安裝在一起。
配置文件
主要修改三個配置文件:hbase-env.sh闭专、hbase-site.xml奴潘、regionservers
cd hbase-1.2.6.1/conf
修改hbase-env.sh
export JAVA_HOME=/home/hadoop/jdk1.8
//hbase自己有一套zookeeper管理機制,這里不使用自帶的影钉,而是使用我們配置的
export HBASE_MANAGES_ZK=false
修改hbase-site.xml
<configuration>
<!-- 指定hbase在HDFS上存儲的路徑 -->
<property>
<name>hbase.rootdir</name>
<value>hdfs://master:9000/hbase</value>
</property>
<!-- 指定hbase是分布式的 -->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 指定zk的地址画髓,多個用“,”分割 -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>master:2181,slave1:2181,slave2:2181</value>
</property>
</configuration>
修改regionservers,這里就是配置HRegionServer服務器的
slave1
slave2
然后將安裝包拷貝到slave1 和 slave2
scr -r hbase-1.2.6.1 hadoop@slave1:/home/hadoop
scr -r hbase-1.2.6.1 hadoop@slave2:/home/hadoop
啟動
啟動hbase的時候有個要求平委,需要各個服務器之間時間差不超過30s奈虾,所以在啟動之前需要先設置同步一下服務器時間,可以選擇時間服務器廉赔,這里就直接用命令了
date -s "2018-07-08 16:39:03"
//寫入bios肉微,防止重啟系統(tǒng)時間又變了
hwclock -w
啟動hdfs,不啟動yarn也沒關系蜡塌,在master服務器啟動
cd hadoop-2.7.6
sbin/start-dfs.sh
啟動zookeeper碉纳,進入三臺服務器啟動
cd zookeeper-3.4.12
bin/zkServer.sh start
啟動hbase
bin/start-hbase.sh
啟動之后,三臺服務器上的進程分別如下馏艾,可以看到hbase已經(jīng)啟動起來了
啟動成功之后劳曹,也可以在瀏覽器上觀察效果
http://master:16010
前面已經(jīng)說過,hbase相關的節(jié)點信息和zookeeper已經(jīng)關聯(lián)了琅摩,所以可以在zookeeper上查看hbase相關信息
cd zookeeper-3.4.12
bin/zkCli.sh
Hbase的文件存儲是基于HDFS的铁孵,所以也可以在hdfs上看到hbase相關的目錄
打開瀏覽器:http://master:50070/explorer.htm
命令行
Hbase提供了一些交互命令,但是這種情況我們用的不多一般是在程序中通過API來對hbase交互房资。
進入hbase命令行客戶端
cd hbase-1.2.6.1
bin/hbase shell
常用命令如下:
常見用法
創(chuàng)建表
create 表名, 列族名, 列族名 ……
create 't_user_info','base_info','extra_info'
插入數(shù)據(jù)
put 't_user_info','001','base_info:username','zhangsan'
put 't_user_info','001','base_info:age','18'
查詢數(shù)據(jù)
scan 't_user_info'
get 't_user_info','001'
刪除kv數(shù)據(jù)
delete 't_user_info','001','base_info:sex'
deleteall 't_user_info','001'
刪除表
先禁用蜕劝,然后刪除
disable 't_user_info'
drop 't_user_info'
API
創(chuàng)建一個連接
Connection conn = ConnectionFactory.createConnection(conf);
拿到一個DDL容器
Admin admin = conn.getAdmin();
用表管理器的API去操作表
admin.createTable(HTableDescriptor descriptor);
創(chuàng)建一個連接
Connection conn = ConnectionFactory.createConnection(conf);
安裝Flume
Flume用于數(shù)據(jù)采集。在實際開發(fā)中轰异,有各種各樣的數(shù)據(jù)來源岖沛,比如:kafka、mysql溉浙、hbase等等烫止,而我們的業(yè)務系統(tǒng),往往需要根據(jù)不用的數(shù)據(jù)來源開發(fā)不同的程序戳稽。Flume就相當一層殼馆蠕,并且里面提供了一些常用的實現(xiàn)類,有個核心概念就Agent惊奇,可以啟動Agent程序進行數(shù)據(jù)采集互躬,大大減少了我們的開發(fā)時間。
不過看網(wǎng)上說颂郎,F(xiàn)lume在嚴格場景是不推薦使用的吼渡,會有問題。所以簡單了解一下吧乓序。
下載安裝
下載地址
http://mirror.bit.edu.cn/apache/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz http://mirrors.hust.edu.cn/apache/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz http://mirrors.shu.edu.cn/apache/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz http://mirrors.tuna.tsinghua.edu.cn/apache/flume/1.8.0/apache-flume-1.8.0-bin.tar.gz
解壓并拷貝到其它兩臺機器
tar -zxvf apache-flume-1.8.0-bin.tar.gz
scp -r flume-1.8.0 hadoop@slave1:/home/hadoop
scp -r flume-1.8.0 hadoop@slave2:/home/hadoop
配置文件
使用Flume主要就是配置了寺酪,需要編寫的配置內(nèi)容比較多坎背。 這里就不過多介紹了,有興趣的網(wǎng)上了解一下寄雀。
問題總結
DataNode無法啟動
多次執(zhí)行hadoop namenode -format命令得滤,slave 上的執(zhí)行這個命令之前,我已經(jīng)清空了三臺服務器下的一些目錄盒犹,并且停掉了所有進程
cd /home/hadoop/hadoop
rm -rf temp/*
rm -rf hdfs/name/* hdfs/data/*
cd hadoop-2.7.6
rm -rf logs/*
sbin/stop-all.sh
然后在master上執(zhí)行以下命令
sbin/ hadoop-daemon.sh start namenode
sbin/ hadoop-daemon.sh start datanode
執(zhí)行該命令后懂更,發(fā)現(xiàn)在 master節(jié)點上找到了 NameNode 和 DataNode 進行,但是在其它兩臺服務器上未找到 DataNode 進程急膀。
最后的解決方案:
分別在slave1 和 slave2 上執(zhí)行 以下命令
sbin/ hadoop-daemon.sh start datanode
這時候可以在 slave1 和 slave2 上找到 DataNode進程沮协。
同時,在瀏覽器上可以發(fā)現(xiàn)3個DataNode
http://192.168.88.21:50070/dfshealth.html#tab-datanode
可能應該在三臺服務器上把 hdfs目錄下的所有文件和文件夾都清空卓嫂,或者把整個hdfs目錄刪除慷暂。
同理,對于slave1 和slave2 上的沒有NodeManager進程情況晨雳,就手動在slave1和slave2上啟動
yarn-daemon.sh start nodemanager
http://192.168.88.21:8088/cluster/nodes
腳本啟動權限問題
執(zhí)行 sbin/start-dfs.fs 命令呜呐,通過ssh的方式啟動slave1和slave2節(jié)點,提示沒有/tmp目錄的權限悍募,但是很好奇都是hadoop用戶蘑辑,啟動本地的NameNode卻沒有權限問題。單絲坠宴,雖然提示權限問題洋魂,兩個DataNode卻都已經(jīng)啟動了。
為了去除這個警告喜鼓,嘗試是將 /tmp 目錄的權限賦給hadoop用戶副砍,分別在三臺機器上執(zhí)行以下命令
chown -R hadoop /tmp
再次重啟hadoop
sbin/stat-dfs.sh
sbin/stat-yarn.sh
發(fā)現(xiàn)警告已經(jīng)沒有了,同時兩臺DataNode已經(jīng)啟動成功庄岖。
這時候豁翎,三臺機器下分別啟動的進程有
**master**:NameNode、SecondaryNameNode隅忿、ResourceManager
**slave1**:DataNode心剥、NodeManager、
**slave2**:DataNode背桐、NodeManager优烧、
可以這樣理解:NameNode用于管理DataNode,而ResourceManager用于管理NodeManager链峭。
其實這個問題還有另外一種解決方案畦娄,就是修改 etc/hadoop/hadoop.env配置文件,里面有那么個選項可以修改。