Kinesis firehose将文件的持久性(在本例中为时间序列JSON)管理到由YYYY / MM / DD / HH划分的文件夹层次结构(直到24编号中的小时)......很棒。
如何使用Spark 2.0然后我可以读取这些嵌套的子文件夹并从所有叶子json文件创建一个静态Dataframe?数据框阅读器是否有“选项”?
我的下一个目标是将其作为流式传输DF,其中Firehose持久保存到s3中的新文件自然会成为使用Spark 2.0中新结构化流媒体的流数据帧的一部分。我知道这都是实验性的 - 希望有人之前使用S3作为流媒体文件源,其中数据被分成如上所述的文件夹。当然更喜欢直接使用Kinesis流,但是这个连接器上没有日期,所以Firehose-> S3是临时的。
ND:我正在使用数据库,它将S3安装到DBFS中,但当然可以很容易地成为EMR或其他Spark提供商。很高兴看到一个笔记本电脑,如果一个可分享的例子。
干杯!
答案 0 :(得分:6)
我可以读取嵌套的子文件夹并从所有叶子JSON文件创建静态DataFrame吗? DataFrame阅读器有选项吗?
是的,因为您的目录结构是常规的(YYYY/MM/DD/HH
),您可以使用下面的通配符字符给叶子节点提供路径
val spark: SparkSession = SparkSession.builder.master("local").getOrCreate
val jsonDf = spark.read.format("json").json("base/path/*/*/*/*/*.json")
// Here */*/*/*/*.json maps to YYYY/MM/DD/HH/filename.json
当然,更喜欢直接使用Kinesis流,但是此连接器上没有2.0的日期,所以Firehose-> S3是临时的。
我可以看到Kinesis integration with Spark Streaming有一个图书馆。因此,您可以直接读取流数据并在其上执行SQL操作,而无需从S3读取。
groupId = org.apache.spark
artifactId = spark-streaming-kinesis-asl_2.11
version = 2.0.0
使用Spark Streaming和SQL
的示例代码import org.apache.spark.streaming.Duration
import org.apache.spark.streaming.kinesis._
import com.amazonaws.services.kinesis.clientlibrary.lib.worker.InitialPositionInStream
val kinesisStream = KinesisUtils.createStream(
streamingContext, [Kinesis app name], [Kinesis stream name], [endpoint URL],
[region name], [initial position], [checkpoint interval], StorageLevel.MEMORY_AND_DISK_2)
kinesisStream.foreachRDD { rdd =>
// Get the singleton instance of SparkSession
val spark = SparkSession.builder.config(rdd.sparkContext.getConf).getOrCreate()
import spark.implicits._
// Convert RDD[String] to DataFrame
val jsonDf = rdd.toDF() // or rdd.toDF("specify schema/columns here")
// Create a temporary view with DataFrame
jsonDf.createOrReplaceTempView("json_data_tbl")
//As we have DataFrame and SparkSession object we can perform most
//of the Spark SQL stuff here
}
答案 1 :(得分:3)
完全披露:我为Databricks工作,但我不代表Stack Overflow。
如何使用Spark 2.0然后我可以读取这些嵌套的子文件夹并从所有叶子json文件创建一个静态Dataframe?有没有“选择”'到dataframe reader?
DataFrameReader支持加载序列。请参阅def json(paths: String*): DataFrame的文档。您可以指定序列,使用globbing模式或以编程方式构建它(推荐):
val inputPathSeq = Seq[String]("/mnt/myles/structured-streaming/2016/12/18/02", "/mnt/myles/structured-streaming/2016/12/18/03")
val inputPathGlob = "/mnt/myles/structured-streaming/2016/12/18/*"
val basePath = "/mnt/myles/structured-streaming/2016/12/18/0"
val inputPathList = (2 to 4).toList.map(basePath+_+"/*.json")
我知道这都是实验性的 - 希望有人之前使用S3作为流媒体文件源,其中数据被分区为如上所述的文件夹。当然更喜欢直接使用Kinesis流,但是这个连接器上没有日期,所以Firehose-> S3是临时的。
由于您正在使用DBFS,因此我假设已从Firehose传输数据的S3存储桶已经安装到DBFS。如果您需要帮助mounting your S3 bucket to DBFS,请查看Databricks文档。获得上述输入路径后,您只需将文件加载到静态或流数据帧中即可:
<强>静态强>
val staticInputDF =
spark
.read
.schema(jsonSchema)
.json(inputPathSeq : _*)
staticInputDF.isStreaming
res: Boolean = false
<强>流强>
val streamingInputDF =
spark
.readStream // `readStream` instead of `read` for creating streaming DataFrame
.schema(jsonSchema) // Set the schema of the JSON data
.option("maxFilesPerTrigger", 1) // Treat a sequence of files as a stream by picking one file at a time
.json(inputPathSeq : _*)
streamingCountsDF.isStreaming
res: Boolean = true
大部分内容直接来自Databricks documentation on Structured Streaming。甚至还有一个笔记本示例,您可以直接导入Databricks。