mdu*_*ant 5 datetime apache-spark parquet
在spark中创建时间戳列并保存到镶木地板时,会得到一个12字节的整数列类型(int96); 我收集的数据分为6个字节的Julian日和6个字节的纳秒,在一天内.
这不符合任何镶木地板逻辑类型.然后,镶木地板文件中的模式不会指示列是除整数之外的任何内容.
我的问题是,Spark如何知道将这样的列加载为时间戳而不是大整数?
语义是基于元数据确定的。我们需要一些进口:
import org.apache.parquet.hadoop.ParquetFileReader
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.hadoop.conf.Configuration
Run Code Online (Sandbox Code Playgroud)
示例数据:
val path = "/tmp/ts"
Seq((1, "2017-03-06 10:00:00")).toDF("id", "ts")
.withColumn("ts", $"ts".cast("timestamp"))
.write.mode("overwrite").parquet(path)
Run Code Online (Sandbox Code Playgroud)
和 Hadoop 配置:
val conf = spark.sparkContext.hadoopConfiguration
val fs = FileSystem.get(conf)
Run Code Online (Sandbox Code Playgroud)
现在我们可以访问 Spark 元数据:
ParquetFileReader
.readAllFootersInParallel(conf, fs.getFileStatus(new Path(path)))
.get(0)
.getParquetMetadata
.getFileMetaData
.getKeyValueMetaData
.get("org.apache.spark.sql.parquet.row.metadata")
Run Code Online (Sandbox Code Playgroud)
结果是:
String = {"type":"struct","fields: [
{"name":"id","type":"integer","nullable":false,"metadata":{}},
{"name":"ts","type":"timestamp","nullable":true,"metadata":{}}]}
Run Code Online (Sandbox Code Playgroud)
等效信息也可以存储在 Metastore 中。
根据官方文档,这是用于实现与 Hive 和 Impala 的兼容性:
一些 Parquet 生成系统,特别是 Impala 和 Hive,将时间戳存储到 INT96 中。该标志告诉 Spark SQL 将 INT96 数据解释为时间戳,以提供与这些系统的兼容性。
并且可以使用spark.sql.parquet.int96AsTimestamp属性来控制。
| 归档时间: |
|
| 查看次数: |
4926 次 |
| 最近记录: |