終於開始學習hadoop
了,雖然是學校開課了才開始跟着學校的課程學,至少也是開始了。
首先要做的就是搭建好一個hadoop
的環境,需要三台主機,配置一個master
兩個slave
的架構。
老師讓我們用vbox
來做,但是個人覺得虛擬機太慢了,而且還要開三個,太虧。剛好最近開始接觸docker
,准備就在docker
的環境下搭建hadoop
環境。
安裝docker
可以考慮使用國內的加速鏡像 daocloud.io 注冊后可以看到如何使用
由於我已經通過官網的方法安裝了,這里就只記錄下我的操作:
curl -fsSL https://get.docker.com/ | sh
這個過程會很漫長,誰讓我作死去官網下呢 (-_-)
腳本執行完后就能發現docker
已經安裝好了,而且還添加了一個用戶組docker
,可以把自己常用的用戶加入到這個組,方便使用。
可以使用docker version
查看一下版本
$ docker version
Client:
Version: 1.11.1
API version: 1.23
Go version: go1.5.4
Git commit: 5604cbe
Built: Tue Apr 26 23:43:49 2016
OS/Arch: linux/amd64
Server:
Version: 1.11.1
API version: 1.23
Go version: go1.5.4
Git commit: 5604cbe
Built: Tue Apr 26 23:43:49 2016
OS/Arch: linux/amd64
拉取鏡像
docker
和git
的命令有些相像,可以使用pull
命令拉取遠程倉庫,不過git
拉取的往往是代碼,而docker
拉取的是鏡像
從daocloud
拉取鏡像
docker pull daocloud.io/library/centos:centos7
daocloud.io/library/centos
表示鏡像的名字centos7
表示鏡像的版本,默認是latest
,表示最新版
啟動鏡像
我們可以使用docker images
命令查看本地鏡像列表,選擇啟動哪一個鏡像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
daocloud.io/library/centos centos7 96eecaf1019a 6 days ago 196.7 MB
daocloud.io/library/centos latest 96eecaf1019a 6 days ago 196.7 MB
44mfwmrx.mirror.aliyuncs.com/library/redis latest ad6e7427198c 2 weeks ago 184.9 MB
daocloud.io/library/ubuntu latest c5f1cf30c96b 2 weeks ago 120.8 MB
hello-world latest 94df4f0ce8a4 3 weeks ago 967 B
daocloud.io/library/ubuntu trusty-20160424 8fa7f61732d6 4 weeks ago 188 MB
daocloud.io/daocloud/daocloud-toolset latest 1ab33797d8a1 4 weeks ago 150.2 MB
$ docker run -h master --dns=61.139.2.69 -it daocloud.io/library/centos:centos7
這個命令啟動一個容器,參數解釋如下
參數名 | 參數值 | 參數含義 |
---|---|---|
-h | master | 指定hostname |
--dns | 61.139.2.69 | 指定DNS ,默認的是8.8.8.8 ,國內環境... |
-it | 以交互模式啟動 |
具體的含義可以使用docker run --help
查看,這里就不贅述了。
安裝需要的軟件
安裝wget
等
$ sudo yum install -y wget vim openssh-server openssh-clients net-tools
拉取到本地的鏡像是盡可能小的,所以很多命令都沒有安裝:
openssh-server
: 安裝sshd
服務openssh-clients
: 安裝ssh
命令net-tools
: 安裝netstat
,ifconfig
等命令
但是安裝完后並不會啟動sshd
服務,容器是被docker
管理的,無法使用一些系統命令,要啟動sshd
需要執行如下命令
后台啟動sshd
服務,之后就可以使用ssh
命令登錄容器了。
因為ssh
是hadoop
必需的服務,所以我們要在容器啟動是就開啟,所以把這條命令寫到一個腳本里
$ vim /root/run.sh
$ chmod 750 /root/run.sh
$ cat /root/run.sh
!/bin/bash
/usr/sbin/sshd -D
這里不讓其后台運行是為了保證容器不退出,只要容器在后台運行,我們就可以在宿主機上連接容器。
網絡配置
本來是要開始下載jdk
的,但是發現不能上網,測試了一下發現是dns
的問題。
不怕折騰的我怎么能夠忍受每啟動一個容器都要帶上--dns
參數呢,一定可以改的。
結果是折騰了半天(真的是半天啊),找到了下面的解決方案。
修改默認dns
...
DOCKER_NETWORK_OPTIONS="--dns=61.139.2.69"
...
- 修改
/lib/systemd/system/docker.service
...
[Service]
EnviornmentFile=-/etc/default/docker
ExecStart=/usr/bin/docker daemon -H fd:// $OPTIONS \
$DOCKER_NETWORK_OPTIONS
...
這里的設置是按照官網的說明來配置的,百度到的東西都不能使參數生效,不知道為什么
然后重啟docker
systemctl daemon-reload
systemctl restart docker.service
#使用這個命令可以查看 docker 的啟動命令是否生效
$ ps -ef | grep docker
root *** 1 0 5月25 ? 00:02:23 /usr/bin/docker daemon -H fd:// --dns=61.139.2.69 --registry-mirror=***
安裝JDK8
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u91-b14/jdk-8u91-linux-x64.tar.gz
sudo mkdir /usr/java
sudo tar zxf jdk-8u91-linux-x64.tar.gz -C /usr/java
sudo echo "export JAVA_HOME=/usr/java/jdk1.8.0_91" >> /etc/bashrc
sudo "export PATH=$PATH:$JAVA_HOME/bin" >> /etc/bashrc
sudo echo "export CLASSPATH=$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar" >> /etc/bashrc
source /etc/bashrc
安裝Hadoop
下載與環境變量
wget http://mirrors.cnnic.cn/apache/hadoop/common/hadoop-2.7.2/hadoop-2.7.2.tar.gz
sudo mkdir /usr/local/hadoop
sudo tar zxf hadoop-2.7.2.tar.gz -C /usr/local/hadoop
sudo echo "export HADOOP_HOME=/usr/local/hadoop/hadoop-2.7.2" >> /etc/bashrc
sudo echo "export HADOOP_CONFIG_HOME=$HADOOP_HOME/etc/hadoop" >> /etc/bashrc
sudo echo "export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin" >> /etc/bashrc
source /etc/bashrc
配置
對於
hadoop
,我還是個初學者,下面的配置是在網上借鑒的別人的文章
-
首先在
HADOOP_HOME
目錄下創建如下目錄tmp
:臨時目錄namenode
:NameNode 存放目錄datanode
:DataNode 存放目錄
-
切換到
HADOOP_CONFIG_HOME
目錄
cp mapred-site.xml.template mapred-site.xml
hadoop.tmp.dir
/usr/local/hadoop/hadoop-2.7.2/tmp
A base for other temporary dirctories.
fs.default.name
hdfs://master:9000
true
The name of the default file system.
A URI whose scheme and authority determine the FileSystem implemntation.
The uri's scheme determines the config property (fs.SCHEME.impl) naming the FileSystem implemnetation class.
The uri's authority is used to determine the host, port, etc. for a filesystem.
這里指定了緩存目錄$HADOOP_HOME/tmp
和默認文件系統
dfs.replication
2
true
Default block replication.
The actual number of replications can be specified when the file is created.
The default is used if replication is not specified in create time.
dfs.namenode.name.dir
/usr/local/hadoop/hadoop-2.7.2/namenode
true
dfs.datenode.data.dir
/usr/local/hadoop/hadoop-2.7.2/datanode
true
這里指定了備份的數目、namenode
和datanode
的目錄
maperd.job.tracker
master:9001
The host and port that the MapReduce job tracker runs at.
IF "local", then jobs are run in-process as a single map and reduce task
這里指定了MapReduce
作業調度程序的工作主機和端口。
配置免密碼登錄
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
cd ~/.ssh
#獲取宿主機的公鑰,方便宿主機登錄
scp melo@172.17.0.1:~/.ssh/id_rsa.pub authorized_keys
cat id_rsa.pub >> authorized_keys
chmod 600 authorized_keys
還有一個細節,因為后面運行時,如果每次都從鏡像啟動,那都是全新的環境,使用ssh
登錄時是需要確認的。
為了避免不必要的麻煩,特意查了資料,找到解決辦法。
想要達到連接新主機時不用確認的效果,就需要修改客戶端的ssh
配置的StrictHostKeyChecking
。該參數默認為ask
,修改為no
Host *
StrictHostKeyChecking no
Docker配置
保存Container
docker commit -m "hadoop installed" centos:hadoop
#啟動 Hadoop
一開始沒有理清hadoop
的網絡模型,以為需要每個節點都需要知道其他所有節點的地址,一直在配置固定IP
。
但認真想一下,hadoop
並沒有這樣的需求,它只需要master
知道其他節點在哪里就行了,slave
之間根本不需要通信。
事實證明上面這段理解是錯誤的,
slave
需要知道master
在哪里,才能向master
發送心跳和數據塊,否則master
上的namenode
將找不到datanode
因為對docker
的網絡配置不熟悉,所以我采用了一個簡單的辦法,修改/root/run.sh
#!/bin/bash
echo "172.17.0.4 master" >> /etc/network
/usr/sbin/sshd -D
因為節點只有3個,我也只開這三個容器,master
又是最后啟動的,所有master
的地址就是172.17.0.4
所以上面創建的鏡像已經可以使用了。
啟動容器
$ docker run -d --name slave1 centos:hadoop /root/run.sh
$ docker run -d --name slave2 centos:hadoop /root/run.sh
$ docker run -d --name master -h master -P --link slave1:slave1 --link slave2:slave2 centos:hadoop /root/run.sh
我將以上三個命令寫到了一個啟動腳本里,直接就可以啟動了,然后在用ssh
登錄到master
上啟動hadoop
因為使用的是docker
的默認網絡,所有可以算出master
的IP
地址,當然,也可以通過docker netword inspect bridge
命令去獲取
啟動 Hadoop
切換到$HADOOP_HOME
目錄,首先格式化namenode
:
./bin/hadoop namenode -format
看到如下信息,說明格式化成功了。
然后就可以啟動Hadoop
了
$ ./sbin/start-all.sh
This script is Deprecated. Instead use start-dfs.sh and start-yarn.sh
Starting namenodes on [master]
master: Warning: Permanently added 'master,172.17.0.4' (RSA) to the list of known hosts.
master: starting namenode, logging to /usr/local/hadoop/hadoop-2.7.2/logs/hadoop-root-namenode-master.out
localhost: starting datanode, logging to /usr/local/hadoop/hadoop-2.7.2/logs/hadoop-root-datanode-master.out
Starting secondary namenodes [0.0.0.0]
0.0.0.0: Warning: Permanently added '0.0.0.0' (RSA) to the list of known hosts.
0.0.0.0: starting secondarynamenode, logging to /usr/local/hadoop/hadoop-2.7.2/logs/hadoop-root-secondarynamenode-master.out
starting yarn daemons
starting resourcemanager, logging to /usr/local/hadoop/hadoop-2.7.2/logs/yarn-root-resourcemanager-master.out
localhost: starting nodemanager, logging to /usr/local/hadoop/hadoop-2.7.2/logs/yarn-root-nodemanager-master.out
#使用 jps 查看進程
$ jps
480 SecondaryNameNode
640 ResourceManager
737 NodeManager
290 DataNode
195 NameNode
1192 Jps
我的配置到這里就完成了,如果有錯誤,歡迎指正😄