19

I have multiple small parquet files generated as output of hive ql job, i would like to merge the output files to single parquet file?

what is the best way to do it using some hdfs or linux commands?

we used to merge the text files using cat command, but will this work for parquet as well? Can we do it using HiveQL itself when writing output files like how we do it using repartition or coalesc method in spark?

Shankar
  • 8,529
  • 26
  • 90
  • 159
  • 3
    Using "parquet-tools merge" is not recommended. Parquet cuts its file into row_groups that correspond to HDFS blocks. "Parquet-tools merge" only places row_groups after row_groups without merging them. Finally, you get the same problem. You can find more explication in [this ticket](https://issues.apache.org/jira/browse/PARQUET-1115). You also have more explication about "row_groups" for parquet in this [blog](http://ingest.tips/2015/01/31/parquet-row-group-size/). – Nastasia Aug 22 '18 at 13:50
  • Following the ticket mentioned by @Nastasia, this issue will not be solved (at least for now). Anyhow, the solution provided by the merge-tools is now to emit a warning (https://github.com/apache/parquet-mr/pull/433). – Markus Jun 07 '19 at 11:31

3 Answers3

18

According to this https://issues.apache.org/jira/browse/PARQUET-460 Now you can download the source code and compile parquet-tools which is built in merge command.

java -jar ./target/parquet-tools-1.8.2-SNAPSHOT.jar merge /input_directory/
        /output_idr/file_name

Or using a tool like https://github.com/stripe/herringbone

Gray
  • 115,027
  • 24
  • 293
  • 354
giaosudau
  • 2,211
  • 6
  • 33
  • 64
7

Using duckdb :

import duckdb

duckdb.execute("""
COPY (SELECT * FROM '*.parquet') TO 'merge.parquet' (FORMAT 'parquet');
""")

dridk
  • 180
  • 2
  • 13
5

You can also do it using HiveQL itself, if your execution engine is mapreduce.

You can set a flag for your query, which causes hive to merge small files at the end of your job:

SET hive.merge.mapredfiles=true;

or

SET hive.merge.mapfiles=true;

if your job is a map-only job.

This will cause the hive job to automatically merge many small parquet files into fewer big files. You can control the number of output files with by adjusting hive.merge.size.per.task setting. If you want to have just one file, make sure you set it to a value which is always larger than the size of your output. Also, make sure to adjust hive.merge.smallfiles.avgsize accordingly. Set it to a very low value if you want to make sure that hive always merges files. You can read more about this settings in hive documentation.

Jakub Kukul
  • 12,032
  • 3
  • 54
  • 53