读取从s3划分到spark的hive

ddrv8njm  于 2021-05-29  发布在  Hadoop
关注(0)|答案(2)|浏览(429)

在使用了一段时间的Hive电子病历之后,我正朝着spark迈出第一步。
我想读取以以下格式保存到s3的配置单元表: s3://<bucket>/<rootpath>/date=<date>/fileNames 我可以使用这个问题的答案,但是我会失去数据行与 date ,那是因为我没有在文件中保存日期。
有没有一种简单的方法让文件名包含在每一行数据中?

q0qdq0h2

q0qdq0h21#

如果您只需要从文件名中获取听起来的日期,则不需要像spark和hive那样获取文件名,如果您正确地创建了表,那么hive会自动为您这样做。让我示范一下:


# in hive

hive> create table t1 ( name string) partitioned by  (date string) STORED AS TEXTFILE LOCATION 'your s3 path';

# data.txt contains 'john' and 'jay' in two different lines

hive> load data local inpath 'data.txt' into table t1 PARTITION(date='2015-12-30');
hive> select * from t1;
OK
john    2015-12-30
jay 2015-12-30

# in spark-shell

scala> sqlContext.sql("select * from t1").foreach(println);
[john,2015-12-30]
[jay,2015-12-30]

我想这正是你想要的。它还有另一个优点,即您的数据在查询时可以利用分区的性能优势。

lztngnrs

lztngnrs2#

您可以使用wholetextfiles来读取rdd。这将读取每个文件,文件名作为键,文件的全部内容作为值。从这里开始,您应该能够使用flatmapvalues将每个记录分离为它自己的k/v对。

val input = sc.wholeTextFiles(s3://...)
val inputFlat = input.flatMapValues(line => line.split("\n"))

对于本例,如果路径是/user/hive/date=december/part-0000,part-0000的内容是

Joe December-28 Something
Ryan December-29 AnotherThing

输出如下所示:

input.take(1)
(/user/hive/date=December/part-0000, Joe December-28 Something\n Ryan December-29 AnotherThing)

inputFlat.take(2)
(/user/hive/date=December/part-0000, Joe December-28 Something)
(/user/hive/date=December/part-0000, Ryan December-29 AnotherThing)

我想你可以试试下面的。读取记录可能有点慢,但是在重新分区之后,您可以最大化并行处理

inputFlat.flatMapValues(//some split).repartition(numWorkers)

我们可以尝试的另一个潜在方法是:在配置单元中,可以使用名为input\u file\u name的虚拟列检索记录所在的文件,例如:

select INPUT__FILE__NAME, id, name from users where ...;

我不确定它是否有效,但您可以尝试在.sqlapi中使用它。您必须确保sqlcontext具有hive-site.xml。

相关问题