本文将介绍如何在docker上从零开始安装hadoop以及hive环境。本文不会介绍如何安装docker,也不会过多的介绍docker各个命令的具体含义,对docker完全不了解的同学建议先简单的学习一下docker再来看本教程。
一、构建自己的centos镜像
由于官方的centos镜像什么软件都没有,而安装hadoop需要用到ssh、java等环境,因此我们可以根据官方的centos镜像先构建一个属于自己的镜像。整个过程也很简单,我们先新建一个目录存放Dockerfile和执行脚本run.sh。
vim run.sh
#!/bin/bash
/usr/sbin/sshd -D
vim Dockerfile
#生成的新镜像以centos镜像为基础
FROM centos
MAINTAINER by kongtrio(kongtrio@sina.com)
#升级系统
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
#将密钥文件复制到/etc/ssh/目录中。这里要用root的权限生成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
#定义时区参数
ENV TZ=Asia/Shanghai
#设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo '$TZ' > /etc/timezone
#将ssh服务启动脚本复制到/usr/local/sbin目录中,并改变权限为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
#运行脚本,启动sshd服务
CMD ["/usr/local/sbin/run.sh"]
之后通过dockerfile构建一个属于自己的镜像:
docker build -t my_centos:v1 .
通过镜像启动容器:
docker run -d -P --name hadoop_centos my_centos:v1 /usr/local/sbin/run.sh
懒得去构建镜像的同学也可以直接使用我的镜像启动容器:
docker run -d -P --name hadoop_centos kongtrio/kongtrio_centos:latest /usr/local/sbin/run.sh
启动容器后,我们就可以进入容器进行hadoop和hive的相关安装了。
docker exec -it hadoop_centos /bin/bash
二、hadoop 伪分布式环境安装
3种安装模式
hadoop目前支持三种安装模式:
- 单机模式:默认情况下,Hadoop即处于该模式,用于开发和调式。
- 伪分布式系统:一台主机模拟多主机,在一台机器启动NameNode、DataNode、JobTracker、TaskTracker这些守护进程。
- 安全分布式:各个守护进程运行在各个主机上,实现分布式部署。
我们这里介绍的是如何在一个docker容器中部署伪分布式系统。
伪分布式环境安装
安装前首先要获取hadoop的安装包,我们可以直接去官网获取,也可以直接获取源码后编译获得。如何编译hadoop源码可以看我的这篇博客:mac 下编译hadoop源码。
1. 解压安装包
假设我们现在拿到了2.7.0版本的安装包,且我们在第一节中启动了名称为hadoop_centos
的docker容器。这时候就可以先把包拷贝到容器的对应目录后进入容器:
# 拷贝安装包
docker cp hadoop-2.7.0.tar.gz hadoop_centos:/usr/local
# 进入容器
docker exec -it hadoop_centos /bin/bash
cd /usr/local/
# 解压安装包
tar xvf hadoop-2.7.0.tar.gz
2. 修改相关配置文件
修改一下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的内容,主要指定JAVA_HOME的环境变量,否则启动hadoop时会提示找不到JAVA_HOME的值。
vim /usr/local/hadoop-2.7.0/etc/hadoop/hadoop-env.sh
# 将原来的 export JAVA_HOME=${JAVA_HOME} 改成下面这个
export JAVA_HOME="/etc/alternatives/jre_1.8.0"
3. 指定HADOOP环境变量
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. 启动hdfs和yarn
启动hdfs相关进程:
start-dfs.sh
执行start-dfs.sh
脚本后,hadoop会启动3个和hdfs相关的进程。通过ps -ef | grep hadoop
我们可以看到这几个进程分别是NameNode
、SecondaryNamenode
、Datanode
。如果少了就要注意hdfs是否没有正常启动了。
之后启动yarn的相关进程:
start-yarn.sh
执行脚本后正常会有ResourceManager
和NodeManager
这两个进程。
6. 验证程序已经正确启动
# 新建一个目录
hadoop fs -mkdir /test
# 查看是否有对应目录了
hadoop fs -ls /
# 最后输出
Found 1 items
drwxr-xr-x - root supergroup 0 2018-12-23 14:09 /test
三、hive环境安装
编译hive
hive的编译比hadoop简单一些,获取hive源码后进入目录执行以下命令即可:
# -Dmaven.javadoc.skip=true 记得加上
mvn clean package -DskipTests -Pdist -Dmaven.javadoc.skip=true
安装hive
安装hive之前,必须保证机器上已经有hadoop环境了。因此,安装hive之前请先确保hadoop已经安装完成。
我们可以通过官网获取指定版本的hive安装包,也可以自己编译获取hive的相关版本的安装包。
1. 解压安装包
# 拷贝安装包
docker cp apache-hive-2.1.1-bin.tar.gz hadoop_centos:/usr/local
# 进入容器
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>
如果没加上面这些错误,在启动hive的时候会报以下错误:
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数据库
我们这里先直接使用hive内置的derby作为元数据的数据库。直接用默认的配置就行了,执行以下命令初始化数据库:
schematool -initSchema -dbType derby
初始化后会提示:
# ... 省略一些输出
Initialization script completed
schemaTool completed
4. 配置hive相关环境变量
vim /etc/profile
# 在文本最后加上
export HIVE_HOME="/usr/local/apache-hive-2.1.1-bin"
# 设置PATH变量
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$HIVE_HOME/bin
source /etc/profile
5. 验证
我们先创建一个数据文件放到/usr/local
下,
cd /usr/local
vim test.txt
1,jack
2,hel
3,nack
之后通过hive
命令进入hive交互界面,然后执行相关操作
# 建表
create table test(
id int
,name string
)
row format delimited
fields terminated by ',';
# 导入数据
load data local inpath '/usr/local/test.txt' into table test;
# 查询刚才导入的数据
select * from test;
# 查询结果:
OK
1 jack
2 hel
3 nack
配置mysql作为元数据库
上面的教程我们使用derby作为hive的元数据库,但是在我们实际使用中,更常见的是使用mysql作为元数据库。下面介绍一下如何使用mysql作为元数据库。
1. mysql资源准备
首先我们在mac上启动一个mysql镜像的docker容器:
# 为了让mac可以访问该mysql实例,我们将它的端口映射到3307上
docker run -p 3307:3306 --name mysql5.5 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.5
# 在mac上进入该mysql交互界面,创建一个hive的元数据库
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. 配置修改
之后进入我们之前的容器中,修改hive的相关配置
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>
主要修改数据库url、驱动、用户名、密码,数据库url记得填mysql实例的地址,我使用的mysql实例是在另一个docker容器上,所以直接填那个容器的ip。
之后还要通过wget获取mysql驱动到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. 初始化元数据库
schematool -initSchema -dbType mysql
成功后提示:
# ... 省略一些输出
Initialization script completed
schemaTool completed
4. 验证
参考上一节的验证过程
启动 Hiveserver2
刚才我们都是通过hive命令直接进入hive交互界面,现在我们介绍一下如何启动hiveserver2,并通过beeline连接hiveserver2来进行相关操作。
1. 修改hadoop的一些权限配置
启动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. 后台启动hiveserver2
nohup hiveserver2 &
3. 验证
通过beeline连接
beeline -u jdbc:hive2://127.0.0.1:10000
查询一下之前建立的表看下是否能正常访问
select * from test;