Spark的int96时间类型
Spark's int96 time type
当你在spark中创建一个时间戳列,并保存到parquet时,你会得到一个12字节的整数列类型(int96);我收集的数据在一天内被分成 6 个字节用于儒略日和 6 个字节用于纳秒。
这不符合任何镶木地板 logical type。然后,parquet 文件中的架构不会指示该列不是整数。
我的问题是,Spark 如何知道加载这样的列作为时间戳而不是大整数?
语义是根据元数据确定的。我们需要一些导入:
import org.apache.parquet.hadoop.ParquetFileReader
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.hadoop.conf.Configuration
示例数据:
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)
和 Hadoop 配置:
val conf = spark.sparkContext.hadoopConfiguration
val fs = FileSystem.get(conf)
现在我们可以访问 Spark 元数据:
ParquetFileReader
.readAllFootersInParallel(conf, fs.getFileStatus(new Path(path)))
.get(0)
.getParquetMetadata
.getFileMetaData
.getKeyValueMetaData
.get("org.apache.spark.sql.parquet.row.metadata")
结果是:
String = {"type":"struct","fields: [
{"name":"id","type":"integer","nullable":false,"metadata":{}},
{"name":"ts","type":"timestamp","nullable":true,"metadata":{}}]}
同样的信息也可以存储在 Metastore 中。
根据官方文档,这用于实现与 Hive 和 Impala 的兼容性:
Some Parquet-producing systems, in particular Impala and Hive, store Timestamp into INT96. This flag tells Spark SQL to interpret INT96 data as a timestamp to provide compatibility with these systems.
并且可以使用 spark.sql.parquet.int96AsTimestamp
属性.
进行控制
当你在spark中创建一个时间戳列,并保存到parquet时,你会得到一个12字节的整数列类型(int96);我收集的数据在一天内被分成 6 个字节用于儒略日和 6 个字节用于纳秒。
这不符合任何镶木地板 logical type。然后,parquet 文件中的架构不会指示该列不是整数。
我的问题是,Spark 如何知道加载这样的列作为时间戳而不是大整数?
语义是根据元数据确定的。我们需要一些导入:
import org.apache.parquet.hadoop.ParquetFileReader
import org.apache.hadoop.fs.{FileSystem, Path}
import org.apache.hadoop.conf.Configuration
示例数据:
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)
和 Hadoop 配置:
val conf = spark.sparkContext.hadoopConfiguration
val fs = FileSystem.get(conf)
现在我们可以访问 Spark 元数据:
ParquetFileReader
.readAllFootersInParallel(conf, fs.getFileStatus(new Path(path)))
.get(0)
.getParquetMetadata
.getFileMetaData
.getKeyValueMetaData
.get("org.apache.spark.sql.parquet.row.metadata")
结果是:
String = {"type":"struct","fields: [
{"name":"id","type":"integer","nullable":false,"metadata":{}},
{"name":"ts","type":"timestamp","nullable":true,"metadata":{}}]}
同样的信息也可以存储在 Metastore 中。
根据官方文档,这用于实现与 Hive 和 Impala 的兼容性:
Some Parquet-producing systems, in particular Impala and Hive, store Timestamp into INT96. This flag tells Spark SQL to interpret INT96 data as a timestamp to provide compatibility with these systems.
并且可以使用 spark.sql.parquet.int96AsTimestamp
属性.