apache / apache/parquet-java

Cannot read row group larger than 2GB

オープン
#2,057 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
Component: Java Component: Parquet Priority: Major Type: bug
主要言語
Java
スター
3.1k
フォーク
1.6k
平均マージ
3日 12時間
マージ済み PR(30日)
33

説明

Parquet MR 1.8.2 does not support reading row groups which are larger than 2 GB. See:https://github.com/apache/parquet-mr/blob/parquet-1.8.x/parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetFileReader.java#L1064

We are seeing this when writing skewed records. This throws off the estimation of the memory check interval in the InternalParquetRecordWriter. The following spark code illustrates this:
```
/**
* Create a data frame that will make parquet write a file with a row group larger than 2 GB. Parquet
* only checks the size of the row group after writing a number of records. This number is based on
* average row size of the already written records. This is problematic in the following scenario:
* - The initial (100) records in the record group are relatively small.
* - The InternalParquetRecordWriter checks if it needs to write to disk (it should not), it assumes
* that the remaining records have a similar size, and (greatly) increases the check interval (usually
* to 10000).
* - The remaining records are much larger then expected, making the row group larger than 2 GB (which
* makes reading the row group impossible).
*
* The data frame below illustrates such a scenario. This creates a row group of approximately 4GB.
*/
val badDf = spark.range(0, 2200, 1, 1).mapPartitions { iterator =>
var i = 0
val random = new scala.util.Random(42)
val buffer = new Array[Char](750000)
iterator.map { id =>
// the first 200 records have a length of 1K and the remaining 2000 have a length of 750K.
val numChars = if (i < 200) 1000 else 750000
i += 1

// create a random array
var j = 0
while (j < numChars) {
// Generate a char (borrowed from scala.util.Random)
buffer(j) = (random.nextInt(0xD800 - 1) + 1).toChar
j += 1
}

// create a string: the string constructor will copy the buffer.
new String(buffer, 0, numChars)
}
}
badDf.write.parquet("somefile")
val corruptedDf = spark.read.parquet("somefile")
corruptedDf.select(count(lit(1)), max(length($"value"))).show()
```
The latter fails with the following exception:
```
java.lang.NegativeArraySizeException
at org.apache.parquet.hadoop.ParquetFileReader$ConsecutiveChunkList.readAll(ParquetFileReader.java:1064)
at org.apache.parquet.hadoop.ParquetFileReader.readNextRowGroup(ParquetFileReader.java:698)
...
```

-This seems to be fixed by commit https://github.com/apache/parquet-mr/commit/6b605a4ea05b66e1a6bf843353abcb4834a4ced8 in parquet 1.9.x. Is there any chance that we can fix this in 1.8.x?-

**Reporter**: [Herman van Hövell](https://issues.apache.org/jira/secure/ViewProfile.jspa?name=hvanhovell)

**Note**: *This issue was originally created as [PARQUET-980](https://issues.apache.org/jira/browse/PARQUET-980). Please see the [migration documentation](https://issues.apache.org/jira/browse/PARQUET-2502) for further details.*

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

parquet-hadoop/src/main/java/org/apache/parquet/hadoop/ParquetFileReader.java の 1064 行目から始め、動作を commit 6b605a4ea05b66e1a6bf843353abcb4834a4ced8 と比較してください。レポートにある Spark の例を使って問題を再現し、その後、parquet 1.8.x が結果として生成された row group を NegativeArraySizeException なしで読み取れることを確認してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
java, scala
領域
data-engineering
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。