本文將介紹如何在docker上從零開始安裝hadoop以及hive環(huán)境。本文不會(huì)介紹如何安裝docker,也不會(huì)過多的介紹docker各個(gè)命令的具體含義,對(duì)docker完全不了解的同學(xué)建議先簡(jiǎn)單的學(xué)習(xí)一下docker再來(lái)看本教程。
一、構(gòu)建自己的centos鏡像
由于官方的centos鏡像什么軟件都沒有,而安裝hadoop需要用到ssh、java等環(huán)境,因此我們可以根據(jù)官方的centos鏡像先構(gòu)建一個(gè)屬于自己的鏡像。整個(gè)過程也很簡(jiǎn)單,我們先新建一個(gè)目錄存放Dockerfile和執(zhí)行腳本run.sh。
vim run.sh
#!/bin/bash
/usr/sbin/sshd -D
vim Dockerfile
#生成的新鏡像以centos鏡像為基礎(chǔ)
FROM centos
MAINTAINER by kongtrio(kongtrio@sina.com)
#升級(jí)系統(tǒng)
RUN yum -y update
#安裝openssh-server、client
RUN yum -y install openssh-server openssh-clients.x86_64 vim less wget
#修改/etc/ssh/sshd_config
#RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config
#將密鑰文件復(fù)制到/etc/ssh/目錄中。這里要用root的權(quán)限生成key
RUN mkdir -p /root/.ssh
#生成秘鑰、公鑰
RUN ssh-keygen -t rsa -b 2048 -P '' -f /root/.ssh/id_rsa
RUN cat /root/.ssh/id_rsa.pub > /root/.ssh/authorized_keys
RUN cp /root/.ssh/id_rsa /etc/ssh/ssh_host_rsa_key
RUN cp /root/.ssh/id_rsa.pub /etc/ssh/ssh_host_rsa_key.pub
# 安裝 jre 1.8
RUN yum -y install java-1.8.0-openjdk.x86_64
ENV JAVA_HOME=/etc/alternatives/jre_1.8.0
#定義時(shí)區(qū)參數(shù)
ENV TZ=Asia/Shanghai
#設(shè)置時(shí)區(qū)
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone
#將ssh服務(wù)啟動(dòng)腳本復(fù)制到/usr/local/sbin目錄中,并改變權(quán)限為755
ADD run.sh /usr/local/sbin/run.sh
RUN chmod 755 /usr/local/sbin/run.sh
#變更root密碼為root
RUN echo "root:root"| chpasswd
#開放窗口的22端口
EXPOSE 22
#運(yùn)行腳本,啟動(dòng)sshd服務(wù)
CMD ["/usr/local/sbin/run.sh"]
之后通過dockerfile構(gòu)建一個(gè)屬于自己的鏡像:
docker build -t my_centos:v1 .
通過鏡像啟動(dòng)容器:
docker run -d -P --name hadoop_centos my_centos:v1 /usr/local/sbin/run.sh
懶得去構(gòu)建鏡像的同學(xué)也可以直接使用我的鏡像啟動(dòng)容器:
docker run -d -P --name hadoop_centos kongtrio/kongtrio_centos:latest /usr/local/sbin/run.sh
啟動(dòng)容器后,我們就可以進(jìn)入容器進(jìn)行hadoop和hive的相關(guān)安裝了。
docker exec -it hadoop_centos /bin/bash
二、hadoop 偽分布式環(huán)境安裝
3種安裝模式
hadoop目前支持三種安裝模式:
- 單機(jī)模式:默認(rèn)情況下,Hadoop即處于該模式,用于開發(fā)和調(diào)式。
- 偽分布式系統(tǒng):一臺(tái)主機(jī)模擬多主機(jī),在一臺(tái)機(jī)器啟動(dòng)NameNode、DataNode、JobTracker、TaskTracker這些守護(hù)進(jìn)程。
- 安全分布式:各個(gè)守護(hù)進(jìn)程運(yùn)行在各個(gè)主機(jī)上,實(shí)現(xiàn)分布式部署。
我們這里介紹的是如何在一個(gè)docker容器中部署偽分布式系統(tǒng)。
偽分布式環(huán)境安裝
安裝前首先要獲取hadoop的安裝包,我們可以直接去官網(wǎng)獲取,也可以直接獲取源碼后編譯獲得。如何編譯hadoop源碼可以看我的這篇博客:mac 下編譯hadoop源碼。
1. 解壓安裝包
假設(shè)我們現(xiàn)在拿到了2.7.0版本的安裝包,且我們?cè)诘谝还?jié)中啟動(dòng)了名稱為hadoop_centos的docker容器。這時(shí)候就可以先把包拷貝到容器的對(duì)應(yīng)目錄后進(jìn)入容器:
# 拷貝安裝包
docker cp hadoop-2.7.0.tar.gz hadoop_centos:/usr/local
# 進(jìn)入容器
docker exec -it hadoop_centos /bin/bash
cd /usr/local/
# 解壓安裝包
tar xvf hadoop-2.7.0.tar.gz
2. 修改相關(guān)配置文件
修改一下core-site.xml、hdfs-site.xml、mapred-site.xml配置文件的值。
vim /usr/local/hadoop-2.7.0/etc/hadoop/core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://127.0.0.1:9000</value>
</property>
vim /usr/local/hadoop-2.7.0/etc/hadoop/hdfs-site.xml
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
cp /usr/local/hadoop-2.7.0/etc/hadoop/mapred-site.xml.template /usr/local/hadoop-2.7.0/etc/hadoop/mapred-site.xml
vim /usr/local/hadoop-2.7.0/etc/hadoop/mapred-site.xml
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
之后還要修改一下hadoop-env.sh的內(nèi)容,主要指定JAVA_HOME的環(huán)境變量,否則啟動(dòng)hadoop時(shí)會(huì)提示找不到JAVA_HOME的值。
vim /usr/local/hadoop-2.7.0/etc/hadoop/hadoop-env.sh
# 將原來(lái)的 export JAVA_HOME=${JAVA_HOME} 改成下面這個(gè)
export JAVA_HOME="/etc/alternatives/jre_1.8.0"
3. 指定HADOOP環(huán)境變量
vim /etc/profile
# 在文本最后加上
export HADOOP_HOME="/usr/local/hadoop-2.7.0"
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile
4. namenode 初始化
hadoop namenode -format
5. 啟動(dòng)hdfs和yarn
啟動(dòng)hdfs相關(guān)進(jìn)程:
start-dfs.sh
執(zhí)行start-dfs.sh腳本后,hadoop會(huì)啟動(dòng)3個(gè)和hdfs相關(guān)的進(jìn)程。通過ps -ef | grep hadoop我們可以看到這幾個(gè)進(jìn)程分別是NameNode、SecondaryNamenode、Datanode。如果少了就要注意hdfs是否沒有正常啟動(dòng)了。
之后啟動(dòng)yarn的相關(guān)進(jìn)程:
start-yarn.sh
執(zhí)行腳本后正常會(huì)有ResourceManager和NodeManager這兩個(gè)進(jìn)程。
6. 驗(yàn)證程序已經(jīng)正確啟動(dòng)
# 新建一個(gè)目錄
hadoop fs -mkdir /test
# 查看是否有對(duì)應(yīng)目錄了
hadoop fs -ls /
# 最后輸出
Found 1 items
drwxr-xr-x - root supergroup 0 2018-12-23 14:09 /test
三、hive環(huán)境安裝
編譯hive
hive的編譯比hadoop簡(jiǎn)單一些,獲取hive源碼后進(jìn)入目錄執(zhí)行以下命令即可:
# -Dmaven.javadoc.skip=true 記得加上
mvn clean package -DskipTests -Pdist -Dmaven.javadoc.skip=true
安裝hive
安裝hive之前,必須保證機(jī)器上已經(jīng)有hadoop環(huán)境了。因此,安裝hive之前請(qǐng)先確保hadoop已經(jīng)安裝完成。
我們可以通過官網(wǎng)獲取指定版本的hive安裝包,也可以自己編譯獲取hive的相關(guān)版本的安裝包。
1. 解壓安裝包
# 拷貝安裝包
docker cp apache-hive-2.1.1-bin.tar.gz hadoop_centos:/usr/local
# 進(jìn)入容器
docker exec -it hadoop_centos /bin/bash
cd /usr/local/
# 解壓安裝包
tar xvf apache-hive-2.1.1-bin.tar.gz
2. 修改配置文件
cp /usr/local/apache-hive-2.1.1-bin/conf/hive-default.xml.template /usr/local/apache-hive-2.1.1-bin/conf/hive-site.xml
vim /usr/local/apache-hive-2.1.1-bin/conf/hive-site.xml
在最前面加上這些配置:
<property>
<name>system:java.io.tmpdir</name>
<value>/tmp/hive/java</value>
</property>
<property>
<name>system:user.name</name>
<value>${user.name}</value>
</property>
如果沒加上面這些錯(cuò)誤,在啟動(dòng)hive的時(shí)候會(huì)報(bào)以下錯(cuò)誤:
Exception in thread "main" java.lang.IllegalArgumentException: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at org.apache.hadoop.fs.Path.initialize(Path.java:205)
at org.apache.hadoop.fs.Path.<init>(Path.java:171)
at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:644)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:563)
at org.apache.hadoop.hive.ql.session.SessionState.beginStart(SessionState.java:531)
at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:705)
at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:641)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.hadoop.util.RunJar.run(RunJar.java:221)
at org.apache.hadoop.util.RunJar.main(RunJar.java:136)
Caused by: java.net.URISyntaxException: Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%7D
at java.net.URI.checkPath(URI.java:1823)
at java.net.URI.<init>(URI.java:745)
at org.apache.hadoop.fs.Path.initialize(Path.java:202)
... 12 more
3. 初始化hive數(shù)據(jù)庫(kù)
我們這里先直接使用hive內(nèi)置的derby作為元數(shù)據(jù)的數(shù)據(jù)庫(kù)。直接用默認(rèn)的配置就行了,執(zhí)行以下命令初始化數(shù)據(jù)庫(kù):
schematool -initSchema -dbType derby
初始化后會(huì)提示:
# ... 省略一些輸出
Initialization script completed
schemaTool completed
4. 配置hive相關(guān)環(huán)境變量
vim /etc/profile
# 在文本最后加上
export HIVE_HOME="/usr/local/apache-hive-2.1.1-bin"
# 設(shè)置PATH變量
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
source /etc/profile
5. 驗(yàn)證
我們先創(chuàng)建一個(gè)數(shù)據(jù)文件放到/usr/local下,
cd /usr/local
vim test.txt
1,jack
2,hel
3,nack
之后通過hive命令進(jìn)入hive交互界面,然后執(zhí)行相關(guān)操作
# 建表
create table test(
id int
,name string
)
row format delimited
fields terminated by ',';
# 導(dǎo)入數(shù)據(jù)
load data local inpath '/usr/local/test.txt' into table test;
# 查詢剛才導(dǎo)入的數(shù)據(jù)
select * from test;
# 查詢結(jié)果:
OK
1 jack
2 hel
3 nack
配置mysql作為元數(shù)據(jù)庫(kù)
上面的教程我們使用derby作為hive的元數(shù)據(jù)庫(kù),但是在我們實(shí)際使用中,更常見的是使用mysql作為元數(shù)據(jù)庫(kù)。下面介紹一下如何使用mysql作為元數(shù)據(jù)庫(kù)。
1. mysql資源準(zhǔn)備
首先我們?cè)趍ac上啟動(dòng)一個(gè)mysql鏡像的docker容器:
# 為了讓mac可以訪問該mysql實(shí)例,我們將它的端口映射到3307上
docker run -p 3307:3306 --name mysql5.5 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5
# 在mac上進(jìn)入該mysql交互界面,創(chuàng)建一個(gè)hive的元數(shù)據(jù)庫(kù)
mysql -uroot -proot -P 3307 -h 127.0.0.1
create database hive;
# 之后通過docker inspect檢查該容器的ip,我獲取到的ip是172.17.0.3
docker inspect mysql5.5 | grep "IPAddress"
2. 配置修改
之后進(jìn)入我們之前的容器中,修改hive的相關(guān)配置
vim /usr/local/apache-hive-2.1.1-bin/conf/hive-site.xml
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://172.17.0.3:3306/hive</value>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
</property>
主要修改數(shù)據(jù)庫(kù)url、驅(qū)動(dòng)、用戶名、密碼,數(shù)據(jù)庫(kù)url記得填mysql實(shí)例的地址,我使用的mysql實(shí)例是在另一個(gè)docker容器上,所以直接填那個(gè)容器的ip。
之后還要通過wget獲取mysql驅(qū)動(dòng)到hive的lib下
cd /usr/local/apache-hive-2.1.1-bin/lib
wget http://central.maven.org/maven2/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar
3. 初始化元數(shù)據(jù)庫(kù)
schematool -initSchema -dbType mysql
成功后提示:
# ... 省略一些輸出
Initialization script completed
schemaTool completed
4. 驗(yàn)證
參考上一節(jié)的驗(yàn)證過程
啟動(dòng) Hiveserver2
剛才我們都是通過hive命令直接進(jìn)入hive交互界面,現(xiàn)在我們介紹一下如何啟動(dòng)hiveserver2,并通過beeline連接hiveserver2來(lái)進(jìn)行相關(guān)操作。
1. 修改hadoop的一些權(quán)限配置
啟動(dòng)hiveserver2之前,需要先往hdfs的core-site.xml加入以下配置:
vim /usr/local/hadoop-2.7.0/etc/hadoop/core-site.xml
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
然后重啟hdfs:
stop-dfs.sh
start-dfs.sh
2. 后臺(tái)啟動(dòng)hiveserver2
nohup hiveserver2 &
3. 驗(yàn)證
通過beeline連接
beeline -u jdbc:hive2://127.0.0.1:10000
查詢一下之前建立的表看下是否能正常訪問
select * from test;