Java动态生成parquet格式数据并导入Hive

前言:

        在实际项目中,分别使用Hive、SparkSQL、Impala对ORC、Parquet格式数据进行性能查询测试后(Impala 3.1版本之后才可以使用ORC格式),发现Impala对Parquet数据进行查询聚合效率最高,就对后续的数据存储有了Parquet格式存储需求。

1.Java动态生成Parquet文件

本样例是根据动态传参在本地(也可以直接在HDFS上)生成Parquet文件,具体原理如下:

1.根据传入参数组合parquet的schema信息;

    /**
     * 组合parquet的schema信息 
     * @param columnTypeMap eg:<name,string>
     * @return
     */
    private static String getFinalSchemaStr(Map<String, String> columnTypeMap) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("message schema {");
        for (Map.Entry<String, String> stringStringEntry : columnTypeMap.entrySet()) {
            stringBuilder.append("optional ");
            String tpye = getParquetType(stringStringEntry.getValue());
            stringBuilder.append(tpye+" "+stringStringEntry.getKey()+";");
        }
        stringBuilder.append("}");
        return stringBuilder.toString();
    }


    /**
     * 获取Parquet格式数据匹配类型(字段类型匹配可以丰富)
     * @param value
     * @return
     */
    private static String getParquetType(String value) {
        switch (value){
            case "string":
                return "binary";
            case "int":
                return "int32";
            case "double":
                return "double";
            case "date":
                return "int96";
            default:
                return "binary";
        }
    }

 2.生成Parquet格式文件写入本地,具体参数见注释,此处异常抛出不处理,数值类型可以扩展;

    /**
     *
     * @param targetPath parquet文件存储位置
     * @param resultDatas 结果数据
     * @param columns 列名list
     * @param columnTypeMap Map<列名,类型>
     * @throws Exception
     */
    public static void parquetWriter(String targetPath, List<String[]> resultDatas, List<String> columns, LinkedHashMap<String, String> columnTypeMap) throws Exception {
        String schemaStr = getFinalSchemaStr(columnTypeMap);
        MessageType schema = MessageTypeParser.parseMessageType(schemaStr);
//        Path file = new Path("C:\\Temp\\test3.parq");
        Path file = new Path(targetPath);
        ExampleParquetWriter.Builder builder = ExampleParquetWriter
                .builder(file).withWriteMode(ParquetFileWriter.Mode.OVERWRITE)
                .withWriterVersion(ParquetProperties.WriterVersion.PARQUET_1_0)
                .withCompressionCodec(CompressionCodecName.SNAPPY)
                //.withConf(configuration)
                .withType(schema);
        ParquetWriter<Group> writer = builder.build();
        SimpleGroupFactory groupFactory = new SimpleGroupFactory(schema);
        for (String[] resultData : resultDatas) {
            Group group = groupFactory.newGroup();
            for (int i = 0; i < resultData.length; i++) {
                String columnType = columnTypeMap.get(columns.get(i));
                String value = resultData[i];
                if (columnType.equals("string")){
                    group.append(columns.get(i),value);
                }
                if (columnType.equals("int")){
                    group.append(columns.get(i),Integer.parseInt(value));
                }
                if (columnType.equals("double")){
                    group.append(columns.get(i),Double.parseDouble(value));
                }
                if (columnType.equals("date")){
                    DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    group.append(columns.get(i),sdf.parse(value).getTime());
                }
            }
            writer.write(group);
        }
        writer.close();
    }

2.把生成的Parquet导入Hive数仓中

        在第一步中可以直接将数据写入Hive在HDFS上的存储位置,此步骤仅记录另一种实现方法过程,即在Hive中建表并直接将数据load到Hive中,整个过程也可以在java中直接实现,此处不再赘述。

1.在Hive中创建表存储Parquet格式数据:

create table table_name1
(id string, name string, score double) 
STORED AS PARQUET;

或

create table table_name1
(id string, name string, score double) 
partitioned by (dt string) 
STORED AS PARQUET;

2.将数据load到Hive中:

<1>load本地数据

load data local inpath '/path/test.parquet' into table default.table_name1;

<2>load HDFS路径数据

load data inpath '/path/test.parquet' into table default.table_name1;

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
生成Parquet格式文件需要使用Parquet工具包,以下是使用Java生成Parquet格式文件的示例代码: ```java import org.apache.hadoop.fs.Path; import org.apache.parquet.column.ParquetProperties; import org.apache.parquet.example.data.Group; import org.apache.parquet.example.data.simple.SimpleGroupFactory; import org.apache.parquet.hadoop.ParquetFileWriter.Mode; import org.apache.parquet.hadoop.ParquetWriter; import org.apache.parquet.hadoop.example.GroupWriteSupport; import org.apache.parquet.hadoop.metadata.CompressionCodecName; public class GenerateParquetFile { public static void main(String[] args) throws Exception { String fileName = "example.parquet"; // Create a Group object SimpleGroupFactory groupFactory = new SimpleGroupFactory(GroupWriteSupport.getSchema()); Group group = groupFactory.newGroup() .append("id", 1) .append("name", "Tom") .append("age", 25) .append("score", 89.5f); // Create a ParquetWriter object Path path = new Path(fileName); GroupWriteSupport writeSupport = new GroupWriteSupport(); ParquetWriter<Group> writer = new ParquetWriter<>(path, writeSupport, CompressionCodecName.SNAPPY, ParquetWriter.DEFAULT_BLOCK_SIZE, ParquetWriter.DEFAULT_PAGE_SIZE, ParquetWriter.DEFAULT_PAGE_SIZE, true, false, ParquetProperties.WriterVersion.PARQUET_2_0, Mode.CREATE); // Write the Group object to the Parquet file writer.write(group); // Close the ParquetWriter object writer.close(); } } ``` 这段代码使用SimpleGroupFactory创建了一个Group对象,然后使用ParquetWriter将该对象写入Parquet文件中。需要注意的是,需要使用GroupWriteSupport类指定Parquet schema。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值