flink写parquet解决timestamp时间格式字段问题

背景

        Apache Parquet 是一种开源的列式数据文件格式,旨在实现高效的数据存储和检索。它提供高性能压缩和编码方案(encoding schemes)来批量处理复杂数据,并且受到许多编程语言和分析工具的支持。

        在我们通过flink写入parquet文件的时候,会遇到timestamp时间格式写入的问题。flink官方sdk提供的avro定义转换为parquet文件字段定义是没有timestamp类型的,得另找方法解决。

parquet的时间字段

        parquet字段定义存在如下几种类型:

  • BOOLEAN: 1 bit boolean
  • INT32: 32 bit signed ints
  • INT64: 64 bit signed ints
  • INT96: 96 bit signed ints
  • FLOAT: IEEE 32-bit floating point values
  • DOUBLE: IEEE 64-bit floating point values
  • BYTE_ARRAY: 任意长度 byte 数组

        其中timestamp使用int96类型进行存储,只有使用int96按照指定格式存储时间格式,我们才可以通过hive,sparksql等计算引擎读取正确的时间数据。

flink2parquet

      flink官方提供的写入parquet的处理方式如下:

    String avroSchema = "";

    //构建parquet格式定义
    Schema schema = new Schema.Parser().parse(avroSchema);


    BulkWriter.Factory<GenericRecord> writerFactory = ParquetAvroWriters.forGenericRecord(schema);

    org.apache.flink.connector.file.sink.FileSink fileSink = org.apache.flink.connector.file.sink.FileSink.forBulkFormat(
                    new org.apache.flink.core.fs.Path("hdfs://xxxxx/xx/xx"), writerFactory)
            .withRollingPolicy(OnCheckpointRoll
### 如何使用 Flink 将流数据入 Hive #### 配置依赖项 为了使 Flink 能够与 Hive 交互,需要引入必要的 Maven 依赖项。以下是所需的依赖项列表: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-hive_${scala.binary.version}</artifactId> <version>${flink.version}</version> </dependency> <dependency> <groupId>org.apache.hive</groupId> <artifactId>hive-exec</artifactId> <version>3.1.2</version> </dependency> ``` 这些依赖项提供了 Flink 和 Hive 的集成支持[^2]。 --- #### 初始化 Hive Catalog Flink 提供了 `HiveCatalog` 类用于连接 Hive 元存储。以下是一个典型的初始化过程: ```java String name = "myhive"; String defaultDatabase = "default"; String hiveConfDir = "/path/to/hive/conf"; // 替换为实际路径 String version = "3.1.2"; HiveCatalog hiveCatalog = new HiveCatalog(name, defaultDatabase, hiveConfDir, version); tEnv.registerCatalog("myhive", hiveCatalog); // 设置默认目录和数据库 tEnv.useCatalog("myhive"); tEnv.useDatabase("db1"); // 设置 SQL 方言为 HIVE tEnv.getConfig().setSqlDialect(SqlDialect.HIVE); ``` 这段代码注册了一个名为 `myhive` 的 Hive 目录,并将其设置为当前环境的默认目录[^1]。 --- #### 定义 Kafka 数据源 假设输入数据来自 Kafka,则可以通过定义一个 Kafka 表来接收数据。以下是一个示例: ```sql CREATE TABLE kafka_source_table ( userId STRING, amount DOUBLE, ts TIMESTAMP(3), WATERMARK FOR ts AS ts - INTERVAL '5' SECOND -- 添加水印以处理乱序事件 ) WITH ( 'connector' = 'kafka', 'topic' = 'input_topic', 'properties.bootstrap.servers' = 'localhost:9092', 'format' = 'json' ); ``` 此表定义指定了 Kafka 连接器以及 JSON 格式的解析方式[^3]。 --- #### 插入数据到 Hive 表 一旦 Kafka 数据源准备就绪,就可以通过 SQL 查询将数据插入到目标 Hive 表中。例如: ```sql INSERT INTO db1.fs_table SELECT userId, amount, DATE_FORMAT(ts, 'yyyy-MM-dd') AS day, DATE_FORMAT(ts, 'HH') AS hour, DATE_FORMAT(ts, 'mm') AS minute FROM kafka_source_table; ``` 这条语句从 `kafka_source_table` 中提取数据,并按指定格式转换后插入到 Hive 表 `fs_table` 中。 --- #### 执行任务 最后一步是执行查询操作: ```java tEnv.executeSql(insertSql).print(); ``` 这将启动作业并将数据持续入 Hive 表[^4]。 --- #### 自动创建 Hive 表(可选) 如果目标 Hive 表尚未存在,Flink 支持动态创建表。例如,在上述 INSERT 操作之前运行如下 DDL 命令即可: ```sql CREATE TABLE IF NOT EXISTS db1.fs_table ( userId STRING, amount DOUBLE, day STRING, hour STRING, minute STRING ) PARTITIONED BY (day) STORED AS PARQUET; ``` 这样可以确保即使表不存在也不会中断流程[^5]。 --- ### 注意事项 1. **分区策略**:对于大规模数据集,建议合理设计分区字段以优化性能。 2. **文件格式**:推荐使用 Parquet 或 ORC 等列式存储格式提升压缩率和查询效率。 3. **资源管理**:确保集群有足够的计算资源应对实时入需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路边草随风

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值