如何在 EMR 上使用 Spark 在 Hive Metastore 中注册 S3 Parquet 文件

How to register S3 Parquet files in a Hive Metastore using Spark on EMR

我正在使用 Amazon Elastic Map Reduce 4.7.1、Hadoop 2.7.2、Hive 1.0.0 和 Spark 1.6.1。

用例:我有一个用于处理数据的 Spark 集群。该数据作为 Parquet 文件存储在 S3 中。我希望工具能够使用在 Hive Metastore 中注册的名称查询数据(例如,查找 foo table 而不是 parquet.`s3://bucket/key/prefix/foo/parquet` 做事风格)。我还希望此数据在 Hive Metastore(一个单独的 RDS 实例)的生命周期内持续存在,即使我拆除 EMR 集群并启动一个连接到同一 Metastore 的新集群也是如此。

问题:如果我做类似 sqlContext.saveAsTable("foo") 的事情,默认情况下会在 Hive Metastore 中创建一个托管的 table(参见 https://spark.apache.org/docs/latest/sql-programming-guide.html)。这些托管 tables 将数据从 S3 复制到 EMR 集群上的 HDFS,这意味着在拆除 EMR 集群后元数据将无用。

解决方案是将 S3 文件注册为外部 table。

sqlContext.createExternalTable("foo", "s3://bucket/key/prefix/foo/parquet")

我还没有想出如何将文件保存到 S3 并将其注册为外部文件 table,但是 createExternalTable 不会增加太多开销。

您不需要为此使用 EMR。启动 Athena,创建一个 table 来读取 Parquet 格式的数据。这是一种比电子病历便宜得多的选择,而且是可持续的。您可以使用 JDBC 通过 Athena 实时访问此数据。

我解决这个问题的方法是: 首先在spark中创建hive table:

schema = StructType([StructField("key", IntegerType(), True),StructField("value", StringType(), True)])
df = spark.catalog \
          .createTable("data1", "s3n://XXXX-Buket/data1",schema=schema)

接下来在Hive中,会出现如上spark创建的table。 (在本例中为 data1)

此外,在另一个 Hive 引擎中,您可以通过创建与在 Spark 中创建的类型相同的外部 table 数据来 link 此数据是 S3: 命令:

CREATE EXTERNAL TABLE data1 (key INT, value String) STORED AS PARQUET LOCATION 's3n://XXXX-Buket/data1’