问题导读
1.hive什么情况下会遇到并发问题?
2.遇到并发问题,该如何解决?
3.hive除了本文提到的访问方式,还有没有其他访问方式?
前言
使用hive,我们很多情况下会并发调用hive程序,将sql任务转换成mapreuce提交到hadoop集群中,而在本人使用hive的过程中,发现并发调用hive有几个问题,在这个和大家分享下.
正文
默认安装hive,hive是使用derby内存数据库保存hive的元数据,这样是不可以并发调用hive的,需要配置为使用mysql保存hive的元数据。
运行hive,可以有以下访问方式:
1.hiveserver:hive以thrift服务的服务器形式运行,允许不同的语言编写客户端进行访问,通过thrift,jdbc,odbc连接器和hive服务器与hive通信,这种方式很适合java编程人员通过jdbc接口去访问hive,但是在实践中,发现并发调用时,很容易出现hiveserver无故宕机,没有jvm的dump文件,hiveserver的程序也毫无输出。
2.metastore:
2.1.内嵌metastore:默认情况下,metastore和hive是运行在同一个进程里,这种方式经过测试,在并发中是最稳定的,使用这种方式,暂时没有出现问题。
2.2.远程metastore:通过配置hive.metastore.local为false,让metastore作为一个单独的进程运行,hive客户端都要连接远程metastore才能执行任务,但是在实践中,一样很容易出现远程metastore无故宕机,同样没有jvm的dump文件,远程metastore程序也毫无输出。
如果你是多个机器安装了hive,多个机器共享同一个mysql元数据,那么默认情况下,在并发调用时,会偶尔发生hive报DELETEME找不到的错误,异常可以参考http://mail-archives.apache.org/mod_mbox/hive-user/201107.mbox/%3C4F6B25AFFFCAFE44B6259A412D5F9B1033183876@ExchMBX104.netflix.com%3E
这个错误是hive使用的datanucleus框架的bug,在hive中会去取schme name和catalog,是第三方的库datanucleus在操作,可以看到它创建DELETEME123213一些随机数字的表,然后删掉。。目的就为了去获取schme name和catalog。而多个机器在并发过程中,datanucleus发现有DELETEME表,会删除,这个会导致创建了DELETEME的hive进程在访问mysql过程中报错。
要解决这个问题,需要做以下配置:
- <property>
- <name>datanucleus.fixedDatastore</name>
- <value>true</value>
- </property>
- <property>
- <name>datanucleus.autoCreateSchema</name>
- <value>false</value>
- </property>
复制代码
但是要注意:这个配置需要在让hive在第一次初始化好后,才能启动,因为第一次会自动创建元数据。
但是,这个配置会导致hive不会自动创建元数据,而第一次初始化时,不是全部的元数据会建好的,所以这个配置需要折中平衡,建议是没有并发调用不启动这个配置,如果有并发调用启动,但是最好配置两种hive实例,一种不启动这个配置,作为日常的建表维护,一种作为定时任务,并发调用hive。
hive的并发调用,是很容易遇到问题的,要小心处理。
总结
个人经验,如果需要并发调用hive,首先要配置hive的元数据为mysql数据库,最好是通过内嵌metastore的方式去调用hive,通过执行 $HIVE_HOME/bin/hive -S -e "<hive sql>",再从管道获取hive的输出,是本人觉得最稳定安全的方式。
备注:执行sql做分析计算,以local的shell方式调用是没啥问题,但是在load data的时候,并发调用依然有问题,hive stats设置为mysql依然无果,只能将load data的代码以synchroize的方式调用,规避并发的问题。
http://www.cnblogs.com/ggjucheng/archive/2012/07/25/2608633.html
|