近日调研了Kudu+Impala大数据存储引擎,在安装和使用的过程中也遇到不少问题,解决起来也是不容易(lz比较菜鸟),在这里记录一下,也当是分享吧。
1.Impala不能创建表,提示权限的问题
具体情况:
[data.beta.com:21000] > create table user_data(user_id string,code string,value string);
Query: create table user_data(user_id string,tag_code string,tag_value string)
ERROR:
ImpalaRuntimeException: Error making 'createTable' RPC to Hive Metastore:
CAUSED BY: MetaException: Got exception: org.apache.hadoop.security.AccessControlException Permission denied: user=impala, access=WRITE, inode="/user/hive/warehouse/user_data":hive:hadoop:drwxr-xr-x
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:319)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.check(FSPermissionChecker.java:292)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:213)
at org.apache.hadoop.hdfs.server.namenode.FSPermissionChecker.checkPermission(FSPermissionChecker.java:190)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1955)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkPermission(FSDirectory.java:1939)
at org.apache.hadoop.hdfs.server.namenode.FSDirectory.checkAncestorAccess(FSDirectory.java:1922)
at org.apache.hadoop.hdfs.server.namenode.FSDirMkdirOp.mkdirs(FSDirMkdirOp.java:71)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.mkdirs(FSNamesystem.java:4150)
at org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.mkdirs(NameNodeRpcServer.java:1109)
at org.apache.hadoop.hdfs.protocolPB.ClientNamenodeProtocolServerSideTranslatorPB.mkdirs(ClientNamenodeProtocolServerSideTranslatorPB.java:633)
at org.apache.hadoop.hdfs.protocol.proto.ClientNamenodeProtocolProtosClientNamenodeProtocol2.callBlockingMethod(ClientNamenodeProtocolProtos.java)
at org.apache.hadoop.ipc.ProtobufRpcEngineServerProtoBufRpcInvoker.call(ProtobufRpcEngine.java:640)
at org.apache.hadoop.ipc.RPCServer.call(RPC.[java:982](http://java:982/))
at org.apache.hadoop.ipc.ServerHandler1.run(Server.[java:2351](http://java:2351/))
at org.apache.hadoop.ipc.ServerHandler1.run(Server.[java:2347](http://java:2347/))
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.[java:422](http://java:422/))
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.[java:1866](http://java:1866/))
at org.apache.hadoop.ipc.ServerHandler.run(Server.java:2345)
权限问题我就不多说了,解决方案:
1.hadoop fs -ls /user/hive/
drwxr-xr-x - hive hadoop 0 2017-11-22 10:55 /user/hive/spark-jars drwxr-xr-x - hive hadoop 0 2018-01-08 14:37 /user/hive/spark-jars-hdp drwxr-xr-x - hive hadoop 0 2017-11-22 10:35 /user/hive/tez
2.hadoop fs -chmod -R 777 /user/hive
3.hadoop fs -ls /user/hive
可以看到都是可读可写了 drwxrwxrwx - hive hadoop 0 2017-11-22 10:55 /user/hive/spark-jars drwxrwxrwx - hive hadoop 0 2018-01-08 14:37 /user/hive/spark-jars-hdp drwxrwxrwx - hive hadoop 0 2017-11-22 10:35 /user/hive/tez
参考:http://orax.blog.sohu.com/305504807.html
2.表查询错误(文件格式不对)
错误详情:
ERROR: AnalysisException: Unrecognized table type for table: data_takeaway.dim_store_sku_info
CAUSED BY: TableLoadingException: Unrecognized table type for table: data_takeaway.dim_store_sku_info
一直以为是我有什么配置搞的不太稳妥,检查了半天,有一张表突然就可以查了。但是又发现有的表不能查,还是报上面的错。
这是因为:Impala不支持ORC的表,不过我们数仓表基本都是ORC格式的,这就很尴尬了。
那么Impala到底支持哪些文件格式呢? 官方文档:http://impala.apache.org/docs/build/impala-2.8.pdf
文档大约第640页说明:
Impala暂时支持Parquet、Text、Avro、RCFile 、SequenceFile,巧得很,ORC固然是好,但是Impala并不支持。
此外,Impala支持以下压缩编解码器
Snappy(Impala推荐使用的压缩格式,因为有效平衡了压缩比和减压速度,瞬间压缩速度很快,但是空间来说,Gzip可以节省更多空间,Snappy压缩支持Impala 2.0及更高版本中的文本文件)
Gzip(推荐在最高压缩级别时使用是最理想的,可以节省最多的存储空间,支持Impala 2.0及更高版本中的文本文件)
Deflate(不支持文本文件)
Bzip2(支持Impala 2.0及更高版本中的文本文件)
LZO(只支持Text. Impala可以查询LZO压缩的文本表,但目前无法创建或插入数据,如果需要的话可以在Hive中执行这些操作。)
参考文档:https://groups.google.com/a/cloudera.org/forum/#!topic/impala-user/ttVgCVEWSeo
3.查询错误(表文件压缩格式不支持)
Impala select查询错误
ERROR:
TableLoadingException: Failed to load metadata for table: test_text_compress1
CAUSED BY: RuntimeException: Expected compressed text file with {.lzo,.gzip,.snappy,.bz2} suffix: 000001_0.deflate
查看表的存储文件
$ hdfs dfs -lsr /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx
-rwxrwxrwx 3 root hdfs 261568095 2019-01-07 15:59 /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx/000000_0.deflate
-rwxrwxrwx 3 root hdfs 97496501 2019-01-07 15:54 /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx/000001_0.deflate
果然文件是被压缩成了.deflate格式的文件了。但是只是其中的一个分区是这个格式,其他的都是正常的,Impala不识别.deflate压缩格式,所以报错了。 impala支持的压缩格式包括{.lzo,.gzip,.snappy,.bz2}四种,所以需要使用到Impala的表应该是需要设置成这几种压缩格式,或者说,不用压缩。
Impala支持的几种压缩格式参考:https://www.cloudera.com/documentation/enterprise/5-11-x/topics/impala_file_formats.html
那么需要怎么去调整过来呢?
首先在hive里面,设置压缩格式
如果需要压缩MapReduce中间文件(可以不用设置)
set hive.exec.compress.intermediate=true
set mapreduce.map.output.compression.codec= org.apache.hadoop.io.compress.SnappyCodec
set mapreduce.map.output.compression.codec=com.hadoop.compression.lzo.LzoCodec;
最终落表的压缩格式设置:
set hive.exec.compress.output=true
set mapred.output.compression.codec=org.apache.hadoop.io.compress.SnappyCodec
把之前有错误的分区(xxxx)数据重新刷一遍:
insert overwrite app_rpt_day_v1 parition(pt=xxxx) select a,b,c from temp_table
刷完成了之后去查看一下存储文件的格式
$ hdfs dfs -lsr /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx
-rwxrwxrwx 3 root hdfs 261568095 2019-01-07 16:34 /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx/000000_0.snappy
-rwxrwxrwx 3 root hdfs 97496501 2019-01-07 16:34 /apps/hive/warehouse/app_rpt_day_v1/pt=xxxx/000001_0.snappy
可以看到文件的压缩格式已经是snappy,在impala-shell中刷新一下表就可以了:
invalidate metadata app_rpt_day_v1;
再通过查询语句查询一波,OK,搞定。
4.Impala创建新表出错
创建语句
CREATE TABLE foo (key INT, value STRING)
TBLPROPERTIES(
'storage_handler' = 'com.cloudera.kudu.hive.KuduStorageHandler',
'kudu.table_name' = 'foo',
'kudu.master_addresses' = '10.255.206.155',
'kudu.key_columns' = 'key');
报错:ERROR: AnalysisException: A data distribution must be specified using a DISTRIBUTE BY clause.
修改为:
CREATE TABLE foo (key INT, value STRING)
DISTRIBUTE BY HASH (key) INTO 16 BUCKETS
TBLPROPERTIES(
'storage_handler' = 'com.cloudera.kudu.hive.KuduStorageHandler',
'kudu.table_name' = 'foo',
'kudu.master_addresses' = '10.255.206.155',
'kudu.num_tablet_replicas' = '1',
'kudu.key_columns' = 'key');
报错:Not enough live tablet servers to create a table with the requested replication factor 3. 1 tablet servers are alive.
修改为:
CREATE TABLE foo (key INT, value STRING)
DISTRIBUTE BY HASH (key) INTO 16 BUCKETS
TBLPROPERTIES(
'storage_handler' = 'com.cloudera.kudu.hive.KuduStorageHandler',
'kudu.table_name' = 'foo',
'kudu.master_addresses' = '10.255.206.155',
'kudu.key_columns' = 'key');
修改配置文件/etc/kudu/conf.dist/master.gflagfile
添加--default_num_replicas=1 默认的副本数量,一般和集群的节点数量相同,必须要小于等于集群节点数量,否则会报错。
重启:
$ sudo service kudu-master restart
$ sudo service kudu-tserver restart