終於開始學習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
我的配置到這里就完成了,如果有錯誤,歡迎指正😄

