Hadoop安裝指南
支持平臺
- GNU/Linux是產品開發和運行的平臺。 Hadoop已在有2000個節點的GNU/Linux主機組成的集群系統上得到驗證。
- Win32平臺是作為開發平臺支持的。由于分布式操作尚未在Win32平臺上充分測試,所以還不作為一個生產平臺被支持。
所需軟件
Linux和Windows所需軟件包括:
- JavaTM1.5.x,必須安裝,建議選擇Sun公司發行的Java版本。
- ssh 必須安裝并且保證 sshd一直運行,以便用Hadoop 腳本管理遠端Hadoop守護進程。
一般來說,現在的Linux都帶有open ssh,可以通過下面的命令看看是不是啟用了sshd: ps -ef | grepsshd,如果沒有啟用可以在/etc/init.d里面找到啟用
Windows下的附加軟件需求
- Cygwin - 提供上述軟件之外的shell支持。
安裝軟件
如果你的集群尚未安裝所需軟件,你得首先安裝它們。
以Ubuntu Linux為例:
$ sudo apt-get install ssh
$ sudo apt-get install rsync
以Cent OS Linux為例,本示例采用的是Cent OS Linux。
yum install rsync
在Windows平臺上,如果安裝cygwin時未安裝全部所需軟件,則需啟動cyqwin安裝管理器安裝如下軟件包:
- openssh - Net 類
下載
為了獲取Hadoop的發行版,從Apache的某個鏡像服務器上下載最近的 穩定發行版。這里下載的是0.20.203.0版本
新建系統Hadoop用戶
Hadoop要求所有機器上hadoop的部署目錄結構要相同,并且都有一個相同的用戶名的帳戶,所以需要每臺機器見一個同名的用戶。
在這4臺機器上建hadoop用戶,密碼:hadoop,默認路徑/home/hadoop/。
運行Hadoop集群的準備工作
解壓所下載的Hadoop發行版。編輯conf/hadoop-env.sh文件,至少需要將JAVA_HOME設置為Java安裝根路徑。
嘗試如下命令:
$ bin/hadoop
將會顯示hadoop腳本的使用文檔。
現在你可以用以下三種支持的模式中的一種啟動Hadoop集群:
- 單機模式
- 偽分布式模式
- 完全分布式模式
單機模式的操作方法
默認情況下,Hadoop被配置成以非分布式模式運行的一個獨立Java進程。這對調試非常有幫助。
下面的實例將已解壓的conf目錄拷貝作為輸入,查找并顯示匹配給定正則表達式的條目。輸出寫入到指定的output目錄。
在hadoop根目錄下:
$ mkdir input
$ cp conf/*.xml input
$ bin/hadoop jar hadoop-examples-*.jar grep input output 'dfs[a-z.]+'
$ cat output/*
說明:這里的grep不是通常意義的grep,語句的意思是,使用hadoop運行hadoop-examples-*.jar,grep作為jar的參數,input作為輸入,output作為輸出。通常意義的grep如下:
grep(global search regular expression(RE) and print out the line,全面搜索正則表達式并把行打印出來)是一種強大的文本搜索工具,它能使用正則表達式搜索文本,并把匹配的行打印出來。Unix的grep家族包括grep、egrep和fgrep。
偽分布式模式的操作方法
Hadoop可以在單節點上以所謂的偽分布式模式運行,此時每一個Hadoop守護進程都作為一個獨立的Java進程運行。
配置
使用如下的conf/core-site.xml:
|
<configuration> |
|
<property> |
|
<name>fs.default.name</name> |
|
<value>hdfs://localhost:9000/</value> |
|
</property> |
|
</configuration> |
使用如下的conf/hdfs-site.xml:
|
<configuration> |
|
<property> |
|
<name>dfs.replication</name> |
|
<value>1</value> |
|
</property> |
|
</configuration> |
使用如下的conf/mapred-site.xml:
|
<configuration> |
|
<property> |
|
<name>mapred.job.tracker</name> |
|
<value>localhost:9001/</value> |
|
</property> |
|
</configuration> |
免密碼ssh設置
注意:使用非root用戶登錄,此處的用戶名為hadoop。
現在確認能否不輸入口令就用ssh登錄localhost:
$ ssh localhost
如果不輸入口令就無法用ssh登陸localhost,執行下面的命令:
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
#密鑰拷貝為認證keys,將id_dsa.pub文件內容追加到authorized_keys
$ cat ~/.ssh/id_dsa.pub >>~/.ssh/authorized_keys 此腳本
注意:root用戶直接執行上面腳本就可以實現不輸人口令自動ssh登錄,但是非root用戶還需要做如下工作:
1)修改/etc/ssh/sshd_config: 然后用root賬戶執行/sbin/servicesshd restart重啟
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
2)執行chmod 600 ~/.ssh/authorized_keys
特別提示:如果報Agent admitted failure to sign using the key錯誤
則執行ssh-add會出現下述訊息.
Identity added: /home/user/.ssh/id_rsa(/home/user/.ssh/id_rsa)
再次連線就正常囉~
執行
格式化一個新的分布式文件系統:
$ bin/hadoop namenode -format
啟動Hadoop守護進程:
$ bin/start-all.sh
注意:如果啟動的時候報如下錯:
Unrecognizedoption: -jvm
則解決辦法如下:
可以修改的地方有兩個
第一個(次要的):/usr/local/hadoop/conf/hadoop-env.sh
修改參數: export HADOOP_HEAPSIZE=256 #默認值為1000M,為Java虛擬機占用的內存的大小
第二個(主要的):
查看/usr/local/hadoop/bin/hadoop源碼:
####################################################################
if [[ $EUID -eq0 ]]; then
HADOOP_OPTS="$HADOOP_OPTS -jvm server $HADOOP_DATANODE_OPTS"
else
HADOOP_OPTS="$HADOOP_OPTS -server $HADOOP_DATANODE_OPTS"
fi
####################################################################
如果以root身份啟動,則hadoop啟動java虛擬機時,會帶上-jvm參數。
不同的java版本,啟動參數可能會不一致,由此導致以上問題。
因此,
新建一個hadoop用戶,
重新初始化操作:#./hadoopnamenode -format
再次啟動hadoop:#./start-all.sh
正常。
Hadoop守護進程的日志寫入到${HADOOP_LOG_DIR}目錄 (默認是${HADOOP_HOME}/logs).
瀏覽NameNode和JobTracker的網絡接口,它們的地址默認為:
- NameNode - http://localhost:50070/
- JobTracker - http://localhost:50030/
將輸入文件拷貝到分布式文件系統:
$ bin/hadoop fs -put conf input
運行發行版提供的示例程序:
$ bin/hadoop jar hadoop-examples-*.jar grep inputoutput 'dfs[a-z.]+'
查看輸出文件:
將輸出文件從分布式文件系統拷貝到本地文件系統查看:
$ bin/hadoop fs -get output output
$ cat output/*
或者
在分布式文件系統上查看輸出文件:
$ bin/hadoop fs -cat output/*
完成全部操作后,停止守護進程:
$ bin/stop-all.sh
完全分布式模式的操作方法
下面搭建四臺機器的Hadoop集群,四臺機器ip分別為:192.168.221.128(NameNode), 192.168.221.129(JobTracker), 192.168.221.130(DataNode1), 192.168.221.131(DataNode2)
SSH互聯
Ssh本機無密碼訪問前面已經介紹過了,下面只介紹與遠程機器ssh無密碼訪問。
1. 把本地的公鑰復制到另外的機器(比如192.168.221.129)上:
scp ~/.ssh/id_dsa.pub hadoop@192.168.221.129:~/.ssh/128_dsa.pub
這個會要求輸入129的密碼,照提示輸入即可。
在配置從NameNode(192.168.221.128免密碼ssh訪問)JobTracker(192.168.221.129)時,一定要在NameNode上執行這個命令。雖然我不知道為什么,但是多次嘗試下來,就只有這樣才能成功。或許還有其它辦法,以后有機會了再研究研究。
2. 在另外一臺機器上JobTracker(192.168.221.129),把剛剛拷貝過來的公鑰導入authorized_keys
cat ~/.ssh/128_dsa.pub >> authorized_keys
3. 從128上連接129:
ssh 192.168.221.129
同樣第一次連接的話會詢問是否添加機器以及要求輸入密碼,第二次就不用了。
至此就算配置好了ssh從其中一臺到另外一臺的免密碼訪問了,把這個操作在各個機器上兩兩執行,就可以讓任意一臺機器免密碼訪問另外任意一臺機器了。
如果配置過程中有失誤,想要重新來,可以刪除.ssh下的所有東西,從頭來過。
Hadoop集群
關于Hadoop的配置,按照我的理解,應該有六個文件需要修改,它們都在Hadoop的conf文件夾下,分別是:
masters/slavers:配置masters和slavers的機器IP
hadoop-env.sh:Hadoop運行時的環境變量,比如JAVA_HOME,LOG之類的
core-site.xml:Hadoop的核心配置文件,對應并覆蓋core-default.xml中的配置項
hdfs-site.xml:HDFS的配置文件,對應并覆蓋hdfs-default.xml中的配置項
mapred-site.xml:Map/Reduce的配置文件,對應并覆蓋mapred-default.xml中的配置項
上面提到的三個*-default.xml是Hadoop的默認配置項,理論上都是只讀的,如果要修改,就通過對應的用戶配置文件來覆蓋其設置。
1、先配置masters/slavers,NameNode和JobTracker是master,DataNode01和DataNode02是salvers
Masters:
1. vi /hadoop/conf/masters
masters文件內容如下:
1. 192.168.221.128
2. 192.168.221.129
Slavers:
1. vi /hadoop/conf/slavers
slavers文件內容如下:
1. 192.168.221.130
2. 192.168.221.131
2、先配置hadoop-env.sh,這里最重要的是配置JAVA_HOME,在我的機器上是這樣的:
1. export JAVA_HOME=/usr/lib/jvm/java-6-sun
其余的可以考慮配置日志文件路徑:
1. export HADOOP_LOG_DIR=${HADOOP_HOME}/logs
3、配置core-site.xml,通過文檔可以知道這里一般是配置NameNode的地址,即機器名或IP:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://192.168.221.128:9000</value>
</property>
</configuration>
4、配置hdfs-site.xml,這里一般配置文件存放路徑以及文件權限:
<configuration>
<property>
<!-- DFS中存儲文件命名空間信息的目錄 -->
<name>dfs.name.dir</name>
<value>/home/hadoop/Research/hadoop-0.20.203.0/dfs/name</value>
</property>
<property>
<!-- DFS中存儲文件數據的目錄 -->
<name>dfs.data.dir</name>
<value>/home/hadoop/Research/hadoop-0.20.203.0/dfs/data</value>
</property>
<property>
<!-- 是否對DFS中的文件進行權限控制(測試中一般用false)-->
<name>dfs.permissions</name>
<value>false</value>
</property>
</configuration>
5、配置mapred-site.xml,這里配置的東西有很多,都是跟Map-Reduce相關的,不過暫時先配置如下幾項:
<configuration>
<property>
<!-- JobTracker節點-->
<name>mapred.job.tracker</name>
<value>192.168.221.129:9001</value>
</property>
<property>
<!-- map/reduce的系統目錄(使用的HDFS的路徑)-->
<name>mapred.system.dir</name>
<value>/home/hadoop/Research/hadoop-0.20.203.0/mapred/system</value>
</property>
<property>
<!-- map/reduce的臨時目錄(可使用“,”隔開,設置多重路徑來分攤磁盤IO)-->
<name>mapred.local.dir</name>
<value>/home/hadoop/Research/hadoop-0.20.203.0/mapred/local</value>
</property>
</configuration>
這些配置都可以在一臺機器上搞定,由于Hadoop所有機器是使用同樣的配置,所以可以通過scp命令將conf下的內容拷貝復制到各個機器上:
以下當前路徑默認為hadoop-0.20.203.0的上一級目錄:
scp –rphadoop-0.20.203.0/confhadoop@192.168.221.129:/home/hadoop/Research/hadoop-0.20.203.0
scp –rphadoop-0.20.203.0/confhadoop@192.168.221.130:/home/hadoop/Research/hadoop-0.20.203.0
scp –rphadoop-0.20.203.0/confhadoop@192.168.221.131:/home/hadoop/Research/hadoop-0.20.203.0
只復制conf是由于我拷貝虛擬機時就已經把JAVA,Hadoop都安裝好后才拷貝的,這樣可以保證所有文件在同一目錄。
啟動
然后,激動人心的時刻到了,所有配置都搞定了,我們可以啟動了!
不過還有一件事情必須要先做,格式化名稱空間。
在NameNode上,執行如下命令:
1. cd /hadoop/bin
2. ./hadoop namenode -format
執行后結果如下:
然后就可以執行最后一個命令了:
1. ./start-all.sh
如果一切順利的話,應該就成功了:
瀏覽NameNode和JobTracker的網絡接口,它們的地址默認為:
- NameNode - http://localhost:50070/
- JobTracker - http://localhost:50030/
將輸入文件拷貝到分布式文件系統:
$ bin/hadoop fs -put conf input
運行發行版提供的示例程序:
$ bin/hadoop jar hadoop-examples-*.jar grep inputoutput 'dfs[a-z.]+'
運行上述程序如果遇到java.net.NoRouteToHostException: No route to host錯誤,則
解決方法:網上有人說是/etc/hosts下面的ip和機器名沒寫對,有人說是防火墻沒關。我遇到這個問題是由于防火墻沒關,/etc/init.d/iptables stop關閉防火墻。
運行成功后查看輸出文件:
將輸出文件從分布式文件系統拷貝到本地文件系統查看:
$ bin/hadoop fs -get output output
$ cat output/*
或者
在分布式文件系統上查看輸出文件:
$ bin/hadoop fs -cat output/*
完成全部操作后,停止守護進程:
$ bin/stop-all.sh
如果要關閉的話,可以執行
1. ./stop-all.sh
附錄:常見錯誤解決:
http://hi.baidu.com/wyw5257/blog/item/39e51fd3c93d451c3af3cf28.html
1. 如果在bin/hadoopdfs -put /home/test-in input該過程中出現"can only bereplicated to node 0, instead of 1",以下兩種辦法,均可嘗試。
1)解決辦法一:
打開http://localhost:50070/dfshealth.jsp查看,確定了livenode數目為你的機器實際數目時,再進行put(注:如果有個別datanode沒有啟動起來,這是正常的,重新格式化文件系統,然后start-up)。
2)解決辦法二:
當執行 #bin/hadoop dfs -put input input時,報錯 ...,could only bereplicated to 0 nodes, instead of 1,網上查了查,最后確定應該是iptables問題。
如果你的 conf/core-site.xml的配置是:
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://machine1:9000/</value>
</property>
</configuration>
那么你應該將machine1的9000端口打開:
#iptables -I INPUT -p tcp --dport 9000 -j ACCEPT
然后可以查看
http://machine1:50070/dfshealth.jsp(你應該將500070端口也打開)
再執行,又報別的錯:hdfs.DFSClient: Exception in createBlockOutputStreamjava.net.ConnectException: Connection refused
應該是datanode上的端口不能訪問,到datanode上修改iptables:
#iptables -IINPUT -s machine1 -p tcp -j ACCEPT
OK了!
2.如果put時出現java.io.IOException:Not a file: hdfs://localhost:9000/user/icymary/input/test-in
解決辦法是bin/hadoop dfs -rmr input
bin/hadoop dfs -put /home/test-in input
原因是,當執行了多次put之后,就會在分布式文件系統中生成子目錄,刪除重新put即可。
3.如果在 bin/hadoop jarhadoop-0.16.0-examples.jar wordcount input output該過程中出現"canonly be replicated to node 0, instead of 1",解決辦法是,給磁盤釋放更多的空間,當時我的空間只有200M了,運行一直報錯,折騰了1天。
4.如果 bin/hadoop jarhadoop-0.16.0-examples.jar wordcount input output過程中
INFO mapred.JobClient: map 0% reduce 0%
且一直卡住,在log日志中也沒有出現異樣,那么解決辦法是,把/etc/hosts里面多余的機器名刪掉,即可。