写入时间戳类型数据到Parquet,再用Impala读取

Parquet是一种新型列存储格式,它可以兼容Hadoop生态圈中大多数计算框架(Hadoop、Spark等),被多种查询引擎支持(Hive、Impala、Drill等),并且它是语言和平台无关的。Parquet最初是由Twitter和Cloudera(由于Impala的缘故)合作开发完成并开源,2015年5月从Apache的孵化器里毕业成为Apache顶级项目[1][2]。
用Java读写Parquet格式文件需要以下maven依赖:


    org.apache.parquet
    parquet-column
    1.8.2


    org.apache.parquet
    parquet-common
    1.8.2


    org.apache.parquet
    parquet-encoding
    1.8.2


    org.apache.parquet
    parquet-hadoop
    1.8.2

下面是写入parquet文件说明和关键代码:
Date、Timestamp类型需要保存为int96,否则impala读取出错。
int96为12字节,前8字节表示时间戳对应当天已过去的纳秒数,后4字节表示时间戳当天距离儒略历起始日已过去的天数。
注意前8字节和后4字节都是小端字节序,如果写入时使用大端序将导致读取失败[3][4]。

    // schema定义
    ...
    required int96 timestamp_field;
    ...
    public static byte[] getBytes(int i) {
        byte[] bytes=new byte[4];
        bytes[0]=(byte)((i >> 24) & 0xFF);
        bytes[1]=(byte)((i >> 16) & 0xFF);
        bytes[2]=(byte)((i >> 8) & 0xFF);
        bytes[3]=(byte)(i & 0xFF);
        return bytes;
    }

    public static byte[] getBytes(long i) {
        byte[] bytes=new byte[8];
        bytes[0]=(byte)((i >> 56) & 0xFF);
        bytes[1]=(byte)((i >> 48) & 0xFF);
        bytes[2]=(byte)((i >> 40) & 0xFF);
        bytes[3]=(byte)((i >> 32) & 0xFF);
        bytes[4]=(byte)((i >> 24) & 0xFF);
        bytes[5]=(byte)((i >> 16) & 0xFF);
        bytes[6]=(byte)((i >> 8) & 0xFF);
        bytes[7]=(byte)(i & 0xFF);
        return bytes;
    }

    // 调转字节数组
    public static void flip(byte[] bytes) {
        for(int i=0,j=bytes.length-1;i

这样写入parquet文件后,Impala将可以正确读取对应字段的内容。

参考:
[1] https://parquet.apache.org/
[2] Parquet格式详解:https://blog.csdn.net/yu616568/article/details/50993491
[3] NanosecondsToImpalaTimestamp函数:https://github.com/apache/parquet-cpp/blob/master/src/parquet/arrow/writer.h
[4] Github关于INT96的讨论:https://github.com/apache/parquet-format/pull/49

你可能感兴趣的:(写入时间戳类型数据到Parquet,再用Impala读取)