如何制作一个自动更新Hive的表

时间:2015-08-26 19:48:57

标签: hive hdfs hiveql

我在Hive中创建了一个外部表,它使用来自HDFS中Parquet商店的数据。

删除HDFS中的数据时,表中没有数据。当数据再次插入HDFS中的同一位置时,表格不会更新以包含新数据。如果我将新记录插入到包含数据的现有表中,则在运行Hive查询时不会显示新数据。

我如何在Hive中创建表:

CREATE EXTERNAL TABLE nodes (id string) STORED AS PARQUET LOCATION "/hdfs/nodes";

相关错误:

Error: java.io.FileNotFoundException: File does not exist: /hdfs/nodes/part-r-00038-2149d17d-f890-48bc-a9dd-5ea07b0ec590.gz.parquet

我看过几篇帖子说明外部表格中应包含最新数据,例如here。但是,对我来说情况并非如此,我也不知道发生了什么。

我再次将相同的数据插入数据库,并查询该表。它包含与以前相同数量的数据。然后我创建了一个具有不同名称的相同表。它的数据量是其中的两倍,这是合适的数量。

问题可能在于Metastore数据库。我使用PostgreSQL而不是Derby作为数据库。

相关信息:

  • Hive 0.13.0
  • Spark Streaming 1.4.1
  • PostgreSQL 9.3
  • CentOS 7

编辑: 检查Parquet文件后,我发现部件文件看起来似乎是不兼容的文件名。 -rw-r--r-- 3 hdfs hdfs 18702811 2015-08-27 08:22 /hdfs/nodes/part-r-00000-1670f7a9-9d7c-4206-84b5-e812d1d8fd9a.gz.parquet -rw-r--r-- 3 hdfs hdfs 18703029 2015-08-26 15:43 /hdfs/nodes/part-r-00000-7251c663-f76e-4903-8c5d-e0c6f61e0192.gz.parquet -rw-r--r-- 3 hdfs hdfs 18724320 2015-08-27 08:22 /hdfs/nodes/part-r-00001-1670f7a9-9d7c-4206-84b5-e812d1d8fd9a.gz.parquet -rw-r--r-- 3 hdfs hdfs 18723575 2015-08-26 15:43 /hdfs/nodes/part-r-00001-7251c663-f76e-4903-8c5d-e0c6f61e0192.gz.parquet

这些文件是导致Hive在上述错误中无法找到错误的文件。这意味着外部表不是动态的,接受目录中的任何文件(如果你在HDFS中调用它),而是可能只是在创建目录时跟踪目录中的镶木地板文件列表。

示例Spark代码: nodes.foreachRDD(rdd => { if (!rdd.isEmpty()) sqlContext.createDataFrame(rdd.map( n => Row(n.stuff), ParquetStore.nodeSchema) .write.mode(SaveMode.Append).parquet(node_name) })

nodeSchema是架构,node_name是" / hdfs / nodes"

查看关于获取Hive external tables to detect new files.

的其他问题

2 个答案:

答案 0 :(得分:1)

为了让Hive更新其表,我不得不求助于使用Hive的分区功能。通过在每次Spark运行期间创建一个新分区,我在/hdfs/nodes目录内部创建了一系列目录,如下所示:

/hdfs/nodes/timestamp=<a-timestamp>/<parquet-files>
/hdfs/nodes/timestamp=<a-different-timestamp>/<parquet-files>

然后,在每个Spark作业完成后,我在我的Spark作业中使用MSCK REPAIR TABLE nodes运行Hive命令HiveContext,它找到新的分区并更新表。

我意识到这不是自动的,但它至少有效。

答案 1 :(得分:0)

好的,你可能需要将文件封装在一个文件夹中。 Hive外部表必须映射到可能有多个文件的文件夹。

尝试将文件写入:/ path / to / hdfs / nodes / file 然后将外部表映射到/ path / to / hdfs / nodes

所以在文件夹节点中你只有镶木地板文件,它应该有效