我在使用Hive EMR一段时间后,第一步进入Spark。
我想阅读以下列格式保存到S3的Hive表格:
s3://<bucket>/<rootpath>/date=<date>/fileNames
我可以使用答案in this question,但后来我丢失了dataRows与date
之间的联系,这是因为我没有在文件中保存日期。
是否有一种简单的方法来获取每行数据的文件名?
答案 0 :(得分:0)
您可以使用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__FILE__NAME的虚拟列检索找到记录的文件,例如:
select INPUT__FILE__NAME, id, name from users where ...;
我不确定它是否可行,但您可以尝试在.sql api中使用它。您必须确保您的sqlContext具有hive-site.xml。
答案 1 :(得分:0)
如果您需要文件名中的所有日期,那么您不需要将文件名作为spark和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]
我认为这就是你想要的。它的另一个优点是,您的数据可以在查询时获得分区的性能优势。