CDH5 hadoop-hive-habse单机版配置
一、安装环境:
OS:CentOS6.5 64位
JDK:jdk-7u72-linux-x64
hadoop:hadoop-2.3.0-cdh5.0.0.
hbase:hbase-0.96.1.1-cdh5.0.0.
hive:hive-0.12.0-cdh5.0.0.tar
我所用的都是基于CDH5.0.0的,使用CDH的发行版不会存在各个组件间不兼容,导致启动失败等异常。
CDH的其他版本可以在这里下载http://archive-primary.cloudera.com/cdh5/cdh/5/
注意下载各个组件的时候其CDH的版本号一定都要相同。
文章中所有安装包和第三方jar包和配置文件都可以在这里下载到
http://pan.baidu.com/s/1pJDjHQN
二、基础准备
1.首先安装好linux系统,我这里的是:CentOS6.5,推荐为hadoop相关的操作再专门建立一个用户,因为root用户权限太大了
用root用户在shell下运行:
//创建一个叫hadoop的用户
>useradd hadoop
//给hadoop设置密码
>passwd hadoop
2.安装jdk,jdk就用root安装好了,linux下配置jdk的方式这里就不细说了,这里用rpm安装
>rpm -ivh jdk-7u72-linux-x64.rpm
然后配置jdk环境变量,我把我的/etc/profile文件贴出来
JAVA_HOME=/usr/java/jdk1.7.0_72
HIVE_HOME=/home/hadoop/hive-0.12.0-cdh5.0.0
HADOOP_HOME=/home/hadoop/hadoop-2.3.0-cdh5.0.0
PATH=$JAVA_HOME/bin:$PATH:$HIVE_HOME/bin:$HADOOP_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$HIVE_HOME/lib
export JAVA_HOME
export HIVE_HOME
export HADOOP_HOME
export PATH
export CLASSPATH
记得source一下
>source /etc/profile
这里已经包括了后面要用到的hadoop和hive的安装目录,就用我们之前建立的hadoop用户安装hadoop、hbase、hive即可。所以它们都在/home/hadoop下。
三、安装hadoop
1.首先需要安装的是hadoop,先上传安装包再解压
用hadoop用户把hadoop、hbase、hive的tar.gz文件都上传到/home/hadoop下
2.解压hadoop-2.3.0-cdh5.0.0.tar.gz
>tar -xzvf ./hadoop-2.3.0-cdh5.0.0.tar.gz
这样hadoop就被安装到了/home/hadoop/hadoop-2.3.0-cdh5.0.0目录下,如果刚才在/etc/profile里没有配置HADOOP_HOME就加进去,别忘了source。
3.下一步就是配置hadoop了
注意所有cmd后缀的文件都是windows下的配置文件,对应Linux下的是sh文件,另外hadoop生态系统中的所有组件的配置文件都遵循一个统一的规则,就是如果是xxx-default.xml则是全局的配置,xxx-site.xml则是个性化的配置,这两种文件里的配置要素完全一样,但是如果xxx-site.xml里存在配置,则会覆盖掉xxx-default.xml中同样标签内的配置,如果site.xml中没有,则会以default.xml中的配置为准。
hadoop的主要配置文件到在hadoop-2.3.0-cdh5.0.0/etc这个目录下,我们需要配置以下几个文件
hadoop-env.sh
core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml
这五个文件都在hadoop-2.3.0-cdh5.0.0/etc/hadoop这个目录下
配置hadoop-env.sh,27行,因为hadoop是java开发的,运行时需要jdk,根据自己的jdk路径,加上即可,别的没有了。
export JAVA_HOME=/usr/java/jdk1.7.0_72
配置core-site.xml
<configuration>
<property>
<name>fs.default.name</name>
<value>hdfs://localhost:8020</value>
</property>
</configuration>
加上这一段即可,用来表明hdfs的访问地址,我没有修改hosts文件,所以这里就直接写localhost即可,端口可以自己定义,我这里用8020。
配置hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>/home/hadoop/dfs/data</value>
</property>
</configuration>
dfs.replication指定数据的副本数,这里是单机的,默认是3,我们改为1即可
dfs.namenode.name.dir指定namenode的路径
dfs.datanode.data.dir指定datanode的路径
这2个路径不用预先创建,后面格式化的时候会自动创建。
配置mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
CDH5的版本是基于apache hadoop2.0的,所以引入了yarn协助hadoop进行分布式计算。
把这一段复制进去就行了。
配置yarn-site.xml
<configuration>
<!-- Site specific YARN configuration properties -->
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
把这一段复制进去就行。
4.格式化hdfs文件系统
第一次使用时在启动之前要进行格式化,之后就不用了,直接启动即可。一旦格式化,会删除hdfs上的所有数据,格式化的时候只需要针对namenode即可。
进入到hadoop-2.3.0-cdh5.0.0/bin目录下,执行
>./hadoop namenode -format
如果正确,可以看到之前配置的namenode的目录/home/hadoop/dfs/name被自动创建了出来。
5.启动hadoop
以上步骤都没有问题,就可以启动hadoop了,启动命令在hadoop-2.3.0-cdh5.0.0/sbin目录下,sbin目录下包含了所有hadoop各个部分的启动和停止命令,其中start-all和stop-all命令用于启动和停止所有相关部分。可以直接通过运行start-all来启动hadoop,但我推荐各个单独启动,如果有异常也方便定位哪部分出错,便于排查。
我们先运行一下jps目录看下java线程有哪些
>jps
在sbin目录下依次启动
启动namenode: ./hadoop-daemon.sh start namenode
如图,启动日志会生成在hadoop-2.3.0-cdh5.0.0/logs目录下,如果出错,可以查看日志排查。正确启动了以后,再用jps命令查看,会看到多了一个NameNode的进程。
启动datanode: ./hadoop-daemon.sh start datanode
如果,同样会看到生成的日志,用jps查看后多了一个DataNode进程。
此时,在linux上打开浏览器,访问http://localhost:50070或者在客户机上访问
http://linuxip:50070,可以看到web页面
如果不行请关闭linux防火墙等。
启动yarn:./start-yarn.sh
因为我没有配置ssh免密码登录,所以启动的时候需要输入hadoop用户的密码,成功之后再用jps查看多了ResourceManager和NodeManager两个进程。
此时,在linux上打开浏览器,访问http://localhost:8088或者在客户机上访问
至此,hadoop就已经启动成功了。可以发现之前配置的datanode的目录/home/hadoop/dfs/data也已经自动创建了出来。
6.上传文件到hdfs
我们从linux本地文件系统上上传一个文件到hdfs中
cd到hadoop-2.3.0-cdh5.0.0/bin目录下
>hadoop fs -put /home/hadoop/Desktop/1.txt /
把事先准备的1.txt上传到hdfs的根目录下,然后查看
>hadoop fs -ls /
如图,可以看到上传上来的1.txt。
7.停止hadoop
cd到sbin目录下。
>./stop-all.sh
同样因为没有配置ssh免密码,在停止的时候有几次需要输入密码。
之后再运行jps,发现已经没有hadoop的线程了。
一旦停止后,浏览器中也访问不到页面了。
四、安装HBase
1.解压hbase-0.96.1.1-cdh5.0.0.tar.gz
>tar -xzvf ./hbase-0.96.1.1-cdh5.0.0.tar.gz
这样HBase就安装在了/home/hadoop/hbase-0.96.1.1-cdh5.0.0目录下。
2.配置HBase
HBase的配置文件都在hbase-0.96.1.1-cdh5.0.0/conf目录下,需要配置如下文件: hbase-site.xml
hbase-env.sh
配置hbase-site.xml
<configuration>
<property>
<name>hbase.rootdir</name>
<value>hdfs://localhost:8020/hbase</value>
</property>
</configuration>
注意这里的hdfs://localhost:8020/hbase是和hadoop中的core-site.xml下的fs.default.name的值hdfs://localhost:8020对应的。只需要再加一个后缀/hbase即可。
配置hbase-env.sh
第29行附近,
export JAVA_HOME=/usr/java/jdk1.7.0_72
指向JDK的目录。
第122行附近,
export HBASE_MANAGES_ZK=true
指定HBase是否自己管理zookeeper,因为我们这里是单机版,并且并没有安装zk,所以选true。
3.启动HBase
启动前先要启动hadoop,然后进入hbase-0.96.1.1-cdh5.0.0/bin
>./start-hbase.sh
成功后使用jps命令查看
发现多了HMaster,就是HBase的进程。还可以使用
>./hbase hbck
命令查看HBase的状态,如果正常会显示Status: OK。
HBase也有web接口页面,但要先启动HBase REST服务
>./hbase rest start
如果成功则可以访问linux上的HBase REST服务,地址为http://linuxip:60010/,方法和之前访问hadoop的web页面相同。
此时再运行jps,可以看到多了一个RESTServer进程。
4.创建HBase表
我们创建一张表试试,在hbase-0.96.1.1-cdh5.0.0/bin目录下执行
>./hbase shell
如果成功会进入HBase的shell操作界面,如下图
创建表
>create 'table1','col1'
注意结尾没有分号
再用list命令查看已经存在的表
>list
可以看到刚创建的表table1。
此时在web页面上也可以看到
5.停止HBase
退出shell
>quit
在shell下运行quit命令即可,如下图
停止HBase服务
在hbase-0.96.1.1-cdh5.0.0/bin目录下运行
>./stop-hbase.sh
再运行jps,发现已经没有HMaster进程了,虽然RESTServer进程还在,但因为HBase已经停止了,HBase的web页面也打不开了。
五、安装hive
1.解压hive-0.12.0-cdh5.0.0.tar.gz
>tar -xzvf ./hive-0.12.0-cdh5.0.0.tar.gz
这样hive就安装在/home/hadoop/hive-0.12.0-cdh5.0.0目录下了。
2.配置hive
hive的配置文件在hive-0.12.0-cdh5.0.0/conf和hive-0.12.0-cdh5.0.0/bin目录下,需要配置如下文件:
hive-config.sh
hive-default.xml
hive-site.xml
hive-env.sh
配置 hive-config.sh
hive-config.sh在hive-0.12.0-cdh5.0.0/bin目录下,在70行最后加上如下配置
JAVA_HOME=/usr/java/jdk1.7.0_72
HIVE_HOME=/home/hadoop/hive-0.12.0-cdh5.0.0
HADOOP_HOME=/home/hadoop/hadoop-2.3.0-cdh5.0.0
PATH=$JAVA_HOME/bin:$PATH:$HIVE_HOME/bin:$HADOOP_HOME/bin
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$HIVE_HOME/lib:/home/hadoop/hbase-0.96.1.1-cdh5.0.0/lib
export JAVA_HOME
export HIVE_HOME
export HADOOP_HOME
export PATH
export CLASSPATH
配置hive-default.xml
这个只需要把hive-default.xml.template重命名成hive-default.xml即可
>mv hive-default.xml.template hive-default.xml
配置hive-site.xml
hive-site.xml里的配置会覆盖掉hive-default.xml中的配置,这里主要有2处需要注意,一处是确定hive使用什么样的元数据库,一处是如果要想启动hive的web管理页面,需要配置hive的web端war包。
因为hive的元数据库可以用自身的derby,也可以用mysql,选择用什么数据库在130行和136行附近,默认的是derby的配置,如果想用mysql可以把
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:derby:;databaseName=metastore_db;create=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>org.apache.derby.jdbc.EmbeddedDriver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
改成
<property>
<name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value>
<description>JDBC connect string for a JDBC metastore</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.jdbc.Driver</value>
<description>Driver class name for a JDBC metastore</description>
</property>
还有160行附近填写数据库的用户名和密码。
并且把mysql的jdbc驱动jar包放在hive-0.12.0-cdh5.0.0/lib目录下。我这里用的是mysql。因为如果用derby的话一次只能有一个用户链接使用hive,mysql则没有限制。另外注意要修改mysql的访问权限,让hive可以本地访问mysql。不然可能会报java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)错误。
如果要启用hive的web管理页面,在hive-site.xml的724行附近把
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi-@VERSION@.war</value>
<description>This sets the path to the HWI war file, relative to ${HIVE_HOME}. </description>
</property>
改成
<property>
<name>hive.hwi.war.file</name>
<value>lib/hive-hwi-0.12.0-cdh5.0.0.war</value>
<description>This sets the path to the HWI war file, relative to ${HIVE_HOME}. </description>
</property>
因为CDH5.0的版本中没有自带hive-hwi-0.12.0-cdh5.0.0.war(apache以前的老版本可能会自带此war包),所以需要下载hive的源代码,自己编译成war。我已经把这篇文章中所讲的对应版本的war包编译好了,下载下来后放在hive-0.12.0-cdh5.0.0/lib目录下即可。
配置hive-env.sh
>mv hive-env.sh.template hive-env.sh
先从模版文件复制出hive-env.sh,再编辑hive-env.sh,从48行开始修改如下
HADOOP_HOME=/home/hadoop/hadoop-2.3.0-cdh5.0.0
# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/home/hadoop/hive-0.12.0-cdh5.0.0/conf
# Folder containing extra ibraries required for hive compilation/execution can be controlled by:
export HIVE_AUX_JARS_PATH=/home/hadoop/hive-0.12.0-cdh5.0.0/lib
3.启动hive
先启动好hadoop,再启动HBase,如果不需要通过hive使用HBase,可以不启动HBase最后启动hive。hive的启动命令在hadoop/hive-0.12.0-cdh5.0.0/bin目录下。启动hive时有几种不同的命令:
./hive 直接启动hive,进入到hive的命令行下,在命令行模式下进行hive操作
./hive -hiveconf hive.root.logger=DEBUG,console 带日志启动hive,还是在命令行模式下使用hive,但是会输出详细的信息,调试错误时非常有用
./hive --service hwi 带web接口启动hive,此时可以在浏览器打开hive的管理页面,前提是部署了hive-hwi-0.12.0-cdh5.0.0.war。
./hive --service hiveserver 如果要在java代码里调用hive,必须这样启动
我用第二种方式启动,进入命令行
>./hive -hiveconf hive.root.logger=DEBUG,console
启动成功后用jps查看,会看到一个RunJar进程。
如果启动多个hvie或者以多种方式启动hive,会看到相应数目的RunJar进程。
4.停止hive
在shell下直接输入quit命令
>quit;
注意hive的命令结尾要加分号,和hbase不同。
这个时候再用jps命令就看不到RunJar进程了。
5.创建hive表
5.1外部表
创建外部表的时候hive只保存表的元数据,可以在hbase中先创建一个表,然后在hive里创建一个外部表来关联hbase中的表。现在我们先创建一个hbase的表。
进入到hbase的shell下执行:
>create 'member','id','address'
>put 'member','r1','id:address','dabaojiao'
要用hive关联hbase的表需要把hbase/lib和hadoop/share/hadoop/common/lib下的一些jar包拷贝到hive/lib目录下。
Hbase下的
hbase-client-0.96.1.1-cdh5.0.0.jar,
hbase-server-0.96.1.1-cdh5.0.0.jar,
hbase-common-0.96.1.1-cdh5.0.0.jar,
hbase-protocol-0.96.1.1-cdh5.0.0.jar,
htrace-core-2.01.jar
Hadoop下的
hadoop-common-2.3.0-cdh5.0.0.jar
复制完后要重启hive。
进入hive的shell,关联hbase中的member表,注意此时hbase一定要启动哦。
在shell下输入
>CREATE EXTERNAL TABLE hbase_member(key string, value string)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = "id:address")
TBLPROPERTIES("hbase.table.name" = "member");
如果不成功就用日志模式启动hive,会有详细的错误堆栈信息,关联hbase表时比较常见的异常是ClassNotFoundException和ClassNotFoundException。这是因为缺少了hadoop或者hbase的jar包,只要找到这些jar包拷贝到hive/lib目录下即可。
5.2内部表
hbase中没有创建表,直接在hive中创建内部表,间接在hbase中创建出表
>create table hbase_table_1(key int, value string)
stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
with serdeproperties ("hbase.columns.mapping" = ":key,cf1:val")
tblproperties ("hbase.table.name" = "xyz");
6.使用serde导入json到hive中:
实际使用时可能会有这样的场景,就是把json格式的文件数据导入到hive中,可以通过serde的方式,常见的有2种serde分别介绍下。
6.1通过hive-json-serde-0.2.jar(google code)导入:把hive-json-serde-0.2.jar拷贝到hive/lib下
执行建表
CREATE TABLE thxd
(
callType STRING,
callMobile STRING,
callTime STRING,
callTimeCost STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.JsonSerde'
STORED AS TEXTFILE;
再导入json文件
LOAD DATA LOCAL INPATH "/home/hadoop/thxd.txt" OVERWRITE INTO TABLE thxd;
注意1)thxd.txt是在linux文件系统上的,不是hdfs里,所以从local导入。也可以从hdfs里导入。
2)txhd.txt里并不是合法的json格式,如果改成合法的hive-json-serde-0.2.jar将无法工作。
7.2通过https://github.com/rcongiu/Hive-JSON-Serde 的serde
把json-serde-1.3-jar-with-dependencies.jar拷贝到hive/lib
>CREATE TABLE complex_json (
DocId string,
User struct<Id:int,
Username:string,
Name: string,
ShippingAddress:struct<Address1:string,
Address2:string,
City:string,
State:string>,
Orders:array<struct<ItemId:int,
OrderDate:string>>>
)
ROW FORMAT SERDE'org.openx.data.jsonserde.JsonSerDe';
>LOAD DATA LOCAL INPATH'/home/hadoop/test.json' OVERWRITE INTO TABLE complex_json;
>SELECT User.Orders FROM complex_json;
8.通过内置函数json_tuple和get_json_object导入json进入hive
由于get_json_object效率低下,官方推荐使用json_tuple
8.1通过json_tuple导入
8.1.1先建表:
>CREATE TABLE thxd_json ( json string );
8.1.2导入数据(这个是标准的json格式文件,后缀名没关系,但格式要对。可在http://www.bejson.com/在线检查json格式)
>LOAD DATA LOCAL INPATH '/home/hadoop/test.json' INTO TABLE json_table;
8.1.3使用json_tuple查询
>select v1.code, v1.errorDescription, v2.callMobile, v2.callTimeCost
from thxd_json jt
LATERAL VIEW json_tuple(jt.json,'code','errorDescription','dataObject') v1
as code, errorDescription, dataObject
LATERAL VIEW json_tuple(v1.dataObject,'callMobile','callTimeCost') v2
as callMobile, callTimeCost;