本文是『Hadoop』MapReduce 處理 日志log(單機(jī)版)的旭文, maybe還有后續(xù)
在搭建環(huán)境的時(shí)候發(fā)現(xiàn)很難搜到合適的教程,所以這篇應(yīng)該會(huì)有一定受眾
偽分布式就是假分布式,假在哪里,假就假在他只有一臺(tái)機(jī)器而不是多臺(tái)機(jī)器來完成一個(gè)任務(wù),
但是他模擬了分布式的這個(gè)過程,所以偽分布式下Hadoop也就是你在一個(gè)機(jī)器上配置了hadoop的所有節(jié)點(diǎn)
但偽分布式完成了所有分布式所必須的事件
偽分布式Hadoop和單機(jī)版最大的區(qū)別就在于需要配置HDFS
HDFS
HDFS = Hadoop Distributed File System
當(dāng)數(shù)據(jù)量超過單個(gè)物理機(jī)器上存儲(chǔ)的容量,管理跨越機(jī)器的網(wǎng)絡(luò)存儲(chǔ)特定操作系統(tǒng)被稱為分布式文件系統(tǒng),HDFS就是這樣一種系統(tǒng)
HDFS集群主要由 NameNode 管理文件系統(tǒng) Metadata 和從機(jī) DataNodes 存儲(chǔ)的實(shí)際數(shù)據(jù)
NameNode = Hadoop Master, DataNodes = Hadoop Slave
- NameNode: NameNode即系統(tǒng)的主站
- 其維護(hù)所有系統(tǒng)中存在的文件和目錄的文件系統(tǒng)樹和元數(shù)據(jù)
- DataNode : DataNodes作為從機(jī),每臺(tái)機(jī)器位于一個(gè)集群中,并提供實(shí)際的存儲(chǔ),它負(fù)責(zé)為客戶讀寫請(qǐng)求服務(wù)
HDFS中的讀/寫操作運(yùn)行在一個(gè)個(gè)塊中,塊作為獨(dú)立的單元存儲(chǔ)
之前我們提到這些塊都是邏輯上劃分的,只是用一個(gè)索引記錄塊的始末,并未真正的劃分塊
在Hadoop 1.x中block默認(rèn)size=64M,而Hadoop 2.x中默認(rèn)size改為128M
如果想重新定義block.size
$ vim etc/hadoop/hdfs-site.xml
# add
<property>
<name>dfs.block.size</name>
<value>20971520</value> # 其中該值為字節(jié)B數(shù),且需要滿足>1M=1048576=1024×1024, 且能被512整除
</property>
HDFS是可容錯(cuò)的,可伸縮的,易于擴(kuò)展,高可用的
HDFS讀操作
HDFS這個(gè)系統(tǒng)除了主機(jī)和從機(jī)之外,還包括client端,file system

當(dāng)客戶端想讀取一個(gè)文件的時(shí)候,客戶端需要和NameNode節(jié)點(diǎn)進(jìn)行交互,因?yàn)樗俏ㄒ淮鎯?chǔ)數(shù)據(jù)節(jié)點(diǎn)元數(shù)據(jù)的節(jié)點(diǎn)
NameNode規(guī)定奴隸節(jié)點(diǎn)的存儲(chǔ)數(shù)據(jù)的地址跟位置
客戶端通過NameNode找到它需要數(shù)據(jù)的節(jié)點(diǎn),然后直接在找到DataNode中進(jìn)行讀操作
考慮到安全和授權(quán)的目的,NameNode給客戶端提供token,這個(gè)token需要出示給DateNote進(jìn)行認(rèn)證,認(rèn)證通過后,才可以讀取文件
由于HDFS進(jìn)行讀操作的時(shí)候需要需要訪問NameNode節(jié)點(diǎn),所以客戶端需要先通過接口發(fā)送一個(gè)請(qǐng)求,然后NameNode節(jié)點(diǎn)在返回一個(gè)文件位置
在這個(gè)過程中,NameNode負(fù)責(zé)檢查,該客戶端是否有足夠的權(quán)限去訪問這組數(shù)據(jù)?
如果擁有權(quán)限,NameNode會(huì)將文件儲(chǔ)存路徑分享給該客戶端,與此同時(shí),namenode也會(huì)將用于權(quán)限檢查的token分享給客戶端
當(dāng)該客戶端去數(shù)據(jù)節(jié)點(diǎn)讀文件的時(shí)候,在檢查token之后,數(shù)據(jù)節(jié)點(diǎn)允許客戶端讀特定的block. 一個(gè)客戶端打開一個(gè)輸入流開始從DataNode讀取數(shù)據(jù),然后,客戶端直接從數(shù)據(jù)節(jié)點(diǎn)讀取數(shù)據(jù)
如果在讀取數(shù)據(jù)期間datanodes突然廢了,這個(gè)客戶端會(huì)繼續(xù)訪問Namenode, 這是NameNode會(huì)給出這個(gè)數(shù)據(jù)節(jié)點(diǎn)副本的所在位置
HDFS寫操作

我們知道讀取文件需要客戶端訪問Namenode. 相似的寫文件也需要客戶端與NameNode進(jìn)行交互,NameNode需要提供可供寫入數(shù)據(jù)的奴隸節(jié)點(diǎn)的地址
當(dāng)客戶端完成在block中寫數(shù)據(jù)的操作時(shí),這個(gè)奴隸節(jié)點(diǎn)開始復(fù)制自身給其他奴隸節(jié)點(diǎn),直到完成擁有n個(gè)副本(這里的n為副本因子數(shù))
當(dāng)復(fù)制完成后,它會(huì)給客戶端發(fā)一個(gè)通知,同樣的這個(gè)授權(quán)步驟也和讀取數(shù)據(jù)時(shí)一樣
當(dāng)一個(gè)客戶端需要寫入數(shù)據(jù)的時(shí)候,它需要跟NameNode進(jìn)行交互,客戶端發(fā)送一個(gè)請(qǐng)求給NameNode, NameNode同時(shí)返回一個(gè)可寫的地址給客戶端
然后客戶端與特定的DataNode進(jìn)行交互,將數(shù)據(jù)直接寫入進(jìn)去。當(dāng)數(shù)據(jù)被寫入和被復(fù)制的過程完成后,Datanode發(fā)送給客戶端一個(gè)通知,告知數(shù)據(jù)寫入已經(jīng)完成
當(dāng)客戶端完成寫入第一個(gè)block時(shí),第一個(gè)數(shù)據(jù)節(jié)點(diǎn)會(huì)復(fù)制一樣的block給另一個(gè)DataNode, 然后在這個(gè)數(shù)據(jù)節(jié)點(diǎn)完成接收block之后,它開始復(fù)制這些blocks給第三個(gè)數(shù)據(jù)節(jié)點(diǎn)
第三個(gè)數(shù)據(jù)節(jié)點(diǎn)發(fā)送通知給第二個(gè)數(shù)據(jù)節(jié)點(diǎn),第二個(gè)數(shù)據(jù)節(jié)點(diǎn)在發(fā)送通知給第一個(gè)數(shù)據(jù)節(jié)點(diǎn),第一個(gè)數(shù)據(jù)節(jié)點(diǎn)負(fù)責(zé)最后通知客戶端
不論副本因子是多少,客戶端只發(fā)送一個(gè)數(shù)據(jù)副本給DataNode, DataNode完成后續(xù)所有任務(wù)的復(fù)制工作
所以,在Hadoop中寫入文件并不十分消耗系統(tǒng)資源,因?yàn)樗梢栽诙鄠€(gè)數(shù)據(jù)點(diǎn)將blocks平行寫入
HDFS 配置
# 修改為主機(jī)名
$ vim etc/hadoop/slaves
# 添加主機(jī)名
$ vim /etc/hosts
# create folder
$ mkdir -p /usr/local/hadoop/tmp
# 修改temp地址
$ vim etc/hadoop/core-site.xml
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/local/hadoop/tmp</value>
<description>Abase for other temporary directories.</description>
</property>
<property>
<name>fs.defaultFS</name>
<value>hdfs://localhost:9000</value> ## localhost填主機(jī)名->主機(jī)名也是一個(gè)坑
</property>
# create folder
$ mkdir -p /usr/local/hadoop/dfs/name
$ mkdir -p /usr/local/hadoop/dfs/data
# 修改分布式儲(chǔ)存配置
$ vim etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>10</value> ## node數(shù)
</property>
<property>
<name>dfs.block.size</name>
<value>20971520</value> ## block.size
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:///usr/local/hadoop/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:///usr/local/hadoop/dfs/data</value>
</property>
<property>
<name>dfs.permissions</name>
<value>false</value>
</property>
</configuration>
# yarn 配置,注意所有l(wèi)ocalhost為主機(jī)名,需保持一致
$ vim etc/hadoop/yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.admin.address</name>
<value>localhost:8033</value>
</property>
<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.resource-tracker.address</name>
<value>localhost:8025</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>localhost:8030</value>
</property>
<property>
<name>yarn.resourcemanager.address</name>
<value>localhost:8050</value>
</property>
<property>
<name>yarn.resourcemanager.scheduler.address</name>
<value>localhost:8030</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.address</name>
<value>localhost:8088</value>
</property>
<property>
<name>yarn.resourcemanager.webapp.https.address</name>
<value>localhost:8090</value>
</property>
</configuration>
完成上述配置之后,需要對(duì)FS進(jìn)行相應(yīng)的格式化操作
hdfs namenode -format
hdfs getconf -namenodes
然后就可以啟動(dòng)hdfs了
$ bash sbin/start-all.sh
啟動(dòng)之后可以通過Jbs命令查看進(jìn)程
也可以通過http://ip:50070進(jìn)入HDFS的前端進(jìn)行文件管理
報(bào)錯(cuò)FAQ
- Hadoop 3.1.1版本在bash sbin/start-dfs.sh會(huì)報(bào)bash v3.2+ is required. Sorry.
這個(gè)沒法解決,搜了好多都沒有答案,把包換成2.9.1就好了
PS: 記得把所有環(huán)境變量,軟鏈接都改一遍
Starting namenodes on [localhost]
ERROR: Attempting to operate on hdfs namenode as root
ERROR: but there is no HDFS_NAMENODE_USER defined. Aborting operation.
配置環(huán)境變量
$ vim ~/.zshrc
export HDFS_NAMENODE_USER="root"
export HDFS_DATANODE_USER="root"
export HDFS_SECONDARYNAMENODE_USER="root"
export YARN_RESOURCEMANAGER_USER="root"
export YARN_NODEMANAGER_USER="root"
$ source ~/.zshrc
$ vim etc/hadoop/hadoop-env.sh
export JAVA_HOME=/etc/local/java/xxx ## 絕對(duì)路徑
$ vim ~/.zshrc
PATH=$PATH:/usr/local/hadoop/sbin
$ source ~/.zshrc
$ export HADOOP_CONF_DIR = $HADOOP_HOME/etc/hadoop
$ echo $HADOOP_CONF_DIR
$ hdfs namenode -format
$ hdfs getconf -namenodes
$ etc/hadoop/start-all.sh
hdfs系統(tǒng)和外部文件系統(tǒng)不同步,需要手動(dòng)把文件傳進(jìn)去, hdfs有一套類似于外部文件系統(tǒng)的fs命令
$ hadoop fs -mkdir -p /user/log/input
$ hadoop fs -put <datafile> /user/log/input
文件也可以在http://ip:50070中查看

$ hadoop fs -ls /
$ hadoop fs -put < local file > < hdfs file >
$ hadoop fs -moveFromLocal < local src > ... < hdfs dst >
$ hadoop fs -copyFromLocal < local src > ... < hdfs dst >
$ hadoop fs -get < hdfs file > < local file or dir>
性能對(duì)比
單機(jī)版
Reduce input groups=1
Reduce shuffle bytes=14
Reduce input records=1
Reduce output records=1
Spilled Records=2
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=33
Total committed heap usage (bytes)=291282944
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=2977
File Output Format Counters
Bytes Written=18
spend:21559ms
偽分布-1節(jié)點(diǎn),block.size=10M
Map input records=180
Map output records=180
Map output bytes=1080
Map output materialized bytes=14
Input split bytes=106
Combine input records=180
Combine output records=1
Reduce input groups=1
Reduce shuffle bytes=14
Reduce input records=1
Reduce output records=1
Spilled Records=2
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=31
Total committed heap usage (bytes)=287883264
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=2941
File Output Format Counters
Bytes Written=6
spend:23277ms
偽分布-10節(jié)點(diǎn),block.size=20M
ted successfully
18/10/07 22:51:57 INFO mapreduce.Job: Counters: 35
File System Counters
FILE: Number of bytes read=683924
FILE: Number of bytes written=8139284
FILE: Number of read operations=0
FILE: Number of large read operations=0
FILE: Number of write operations=0
HDFS: Number of bytes read=281872252
HDFS: Number of bytes written=181666
HDFS: Number of read operations=181
HDFS: Number of large read operations=0
HDFS: Number of write operations=88
Map-Reduce Framework
Map input records=180
Map output records=180
Map output bytes=1080
Map output materialized bytes=14
Input split bytes=106
Combine input records=180
Combine output records=1
Reduce input groups=1
Reduce shuffle bytes=14
Reduce input records=1
Reduce output records=1
Spilled Records=2
Shuffled Maps =1
Failed Shuffles=0
Merged Map outputs=1
GC time elapsed (ms)=39
Total committed heap usage (bytes)=287825920
Shuffle Errors
BAD_ID=0
CONNECTION=0
IO_ERROR=0
WRONG_LENGTH=0
WRONG_MAP=0
WRONG_REDUCE=0
File Input Format Counters
Bytes Read=2941
File Output Format Counters
Bytes Written=6
spend:24229ms
總的來說因?yàn)樵谝慌_(tái)機(jī)子上, 偽分布性能并沒有提升
但跑起來 我那臺(tái)破服務(wù)器 內(nèi)存就跌零了 恐怖??


不充錢怎么變得強(qiáng)大