1. 问题背景
在构建的大数据平台上(相关组件版本Hadoop 2.8, hive 1.2.2, hbase 1.2.6) 利用hive-hbase-handler.jar实现hive和hbase的数据互通时,在hive中输入命令后总是报错,
先是Cannot find class 'org.apache.hadoop.hive.bhase.HBaseStorageHandler, 通过tar -tf $HIVE_HOME/lib/hive-hbase-handler.jar确认这个类存在后,继续执行,又报
FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. org.apache.hadoop.hbase.HTableDescriptor.addFamily(Lorg/apache/hadoop/hbase/HColumnDescriptor;)V
通过搜索的结果居然是,hive1.2版本只支持hbase 0.94及更低版本,hbase1.2.6需要hive 2.x才支持。如果要支持hbase1.2.6, 需要重新编译hive 才行。详见hive社区关于针对问题的讨论及问题跟踪:https://issues.apache.org/jira/browse/HIVE-10990
刚要从apache hive下源代码,浏览中发现hive已经有2.x版本了,最高已到2.3,考虑到兼容等保险期间,果断下载了hive-2.1.1 http://mirrors.hust.edu.cn/apache/hive/stable-2/
于是原本要源码编码就省掉了,转为hive升级并与先前meta数据兼容。
2. 升级步骤
2.1 环境变量设置和目录创建
备份原来的hive-1.2.2, 并把新下的包解压至原目录下,改名为hive, 如绝对路径 /home/hadoop/bigdata/hive
因路径和先前保持一致,HIVE_HOME, PATH原来的设置都不用改,HDFS中hive warehouse的目录等也都不用改,只需要在新的hive 目录下创建配置中使用到的几个目录即可,如iotmp, log,
2.2 mysql 相关的修改 ( mysql本身没改,原来设置的数据库用户、授权等本次都不受影响)
2.2.1 metadata升级
hive 的metadata存在mysql中,对应的metadata版本也是1.2.2的,升级后启动hive时会作metadata版本检查,我们需要对metadata进行升级。好在hive中已自带了各个版本的升级脚本,在hive/scripts/metastore/upgrade/mysql/ 中没有1.2 --> 2.1的,但有1.2->2.0, 2.0->2.1的,可以直接使用。对应目录下还有README说明。
简单来说,操作如下:省略原metadata备份的过程,主要是防止升级过程中出错导致数据丢失,再就是可以作为升级后的版本确认是否真正升级成功到了2.1.
进入 hive/scripts/metastore/upgrade/mysql目录,然后在命令行中hive登录,show databases; use metadata ;
> source /home/hadoop/bigdata/hive/scripts/metastore/upgrade/mysql/upgrade-1.2.0-to-2.0.0.mysql.sql // 使用$HIVE_HOME无效,报找不到文件,用绝对路径没问题
> source /home/hadoop/bigdata/hive/scripts/metastore/upgrade/mysql/upgrade-2.0.0-to-2.1.0.mysql.sql
看到界面上显示一系列的升级日志并且过程不报错,基本就说明metadata升级成了。
备注:如果是新的metadata,不涉及升级过程,需要合作 hive的 schematool进行初始化: schematool -dbType mysql -initSchema
2.2.2 安装mysql ODBC jar
把原hive/lib下mysql-connector相关的包copy进新hive/lib, 结果如下:
-rw-r--r-- 1 hadoop hadoop 915836 1月 1 2014 lib/mysql-connector-java-5.1.28.jar
lrwxrwxrwx 1 hadoop hadoop 31 6月 13 11:17 lib/mysql-connector-java.jar -> mysql-connector-java-5.1.28.jar
lrwxrwxrwx 1 hadoop hadoop 24 6月 13 11:17 lib/mysql.jar -> mysql-connector-java.jar
2.3 hive相关配置
2.3.1
cp hive-default.xml.template hive-site.xml
cp hive-env.sh.template hive-env.sh
cp hive-exec-log4j2.properties.template hive-exec-log4j2.properties
2.3.2 hive-env.sh
# Set HADOOP_HOME to point to a specific hadoop install directory
export HADOOP_HOME=/home/hadoop/bigdata/hadoop
# Hive Configuration Directory can be controlled by:
export HIVE_CONF_DIR=/home/hadoop/bigdata/hive/conf
2.3.3 hive-exec-log4j2.properties
# list of properties
property.hive.log.level = INFO
property.hive.root.logger = INFO,DRFA
property.hive.log.dir = /home/hadoop/bigdata/hive/log
property.hive.log.file = hive.log
property.hive.perflogger.log.level = INFO
hive 1.x and 2.x的属性名称设置修改较大,基本含义和功能没变,容易找到。原来设置的hive.log.htreshold=ALL没找到了,可能不需要了吧。
2.3.4 hive-site.xml 这是重点,所有重要的设置都在这里,默认有3千多行,足见功能丰富,找相关的设置即可
JDBC connect string for a JDBC metastore.
To use SSL to encrypt/authenticate the connection, provide database-specific SSL flag in the connection URL.
For example, jdbc:postgresql://myhost/db?ssl=true for postgres database.
// 这个属性的设置有些要注意的地方,如file:///后台必须是三个/ ; 各个jar对应的file串间不能有空格,否则执行时会报错
2.3.5 启动metastore服务和hiveserver2服务
因为hive warehouse设置在HDFS上,需要启动这两个服务,尤其hiveserver2服务,否则启动hive时会报错
Exception in thread "main" java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient
Caused by: MetaException(message:Could not connect to meta store using any of the URIs provided. Most recent failure: org.apache.thrift.transport.TTransportException: java.net.ConnectException: Connection refused (Connection refused)
master上执行: nohup hive --service metastore &
slave01上执行: nohup hive --service hiveserver2 &
ps -ef | grep Hive 可查看服务是否都正常启动
3. 启动hive, hbase并建表加数据实现互通
启动Hive 并执行
hive> create table hbase_table_city (level int, city string)
hive> stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
hive> with SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val") // level 对应于rowkey, city对应于cf1:val , hbase中put时引用的即是'cf1:val'. 多列族时在后面追加,也是此种对应关系
hive> tblproperties ("hbase.table.name" = "t_city");
hive > select * from bhase_table_city; ///目前只是个空表
启动hbase并执行 scan 't_city'
hbase(main):021:0> scan 't_city'
ROW COLUMN+CELL
0 row(s) in 0.0190 seconds
hbase(main):022:0> put 't_city', 1, 'cf1:val', 'Beijing'
0 row(s) in 0.0100 seconds
hbase(main):023:0> scan 't_city'
ROW COLUMN+CELL
1 column=cf1:val, timestamp=1504782348589, value=Beijing
1 row(s) in 0.0260 seconds
hbase(main):024:0> put 't_city', 2, 'cf1:val', 'Shanghai'
0 row(s) in 0.0190 seconds
hbase(main):025:0> put 't_city', 3, 'cf1:val', 'Guangzhou'
0 row(s) in 0.0060 seconds
hbase(main):026:0> put 't_city', 4, 'cf1:val', 'Hangzhou'
0 row(s) in 0.0050 seconds
hbase(main):027:0> put 't_city', 5, 'cf1:val', 'Shenzhen'
0 row(s) in 0.0050 seconds
hbase(main):028:0> scan 't_city'
ROW COLUMN+CELL
1 column=cf1:val, timestamp=1504782348589, value=Beijing
2 column=cf1:val, timestamp=1504782376991, value=Shanghai
3 column=cf1:val, timestamp=1504782385734, value=Guangzhou
4 column=cf1:val, timestamp=1504782392031, value=Hangzhou
5 column=cf1:val, timestamp=1504782400458, value=Shenzhen
5 row(s) in 0.0320 seconds
Hbase中创建表和插入的数据均存在hBase数据库内部(不同于hive只是个数仓的客户工具,本身不存数据,它所操作的数据都存在HDFS中),底层文件即HFile, 也存在HDFS中,路径为http://localhost:50070/explorer.html#/hbase/data/default, 可看到t_city表和其它创建于HBase中的表。
再返回hive中执行 hive > select * from bhase_table_city; 数据已经存在了。
OK
1 Beijing
2 Shanghai
3 Guangzhou
4 Hangzhou
5 Shenzhen
至此,hive1.2->2.1 升级完成,保证了数据兼容,并实现了与hbase的数据互通。不得不说,这些组件和工具确实很强大!!!
附录:
hive社区关于针对问题背景中问题的讨论及问题跟踪:https://issues.apache.org/jira/browse/HIVE-10990
hive 2.1的下载镜像:http://mirrors.hust.edu.cn/apache/hive/stable-2/