-
Notifications
You must be signed in to change notification settings - Fork 2.5k
[HUDI-7170] Implement HFile reader independent of HBase #10241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
8550f66 to
d132592
Compare
596ec9f to
c6833ec
Compare
vinothchandar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! Left some comments
hudi-io/src/main/java/org/apache/hudi/io/compress/CodecPool.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/KeyOnlyKeyValue.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/compress/airlift/HoodieAirliftGzipDecompressor.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/BlockIndexEntry.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileRootIndexBlock.java
Outdated
Show resolved
Hide resolved
vinothchandar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can make this a little more complete, so we don't need changes for other use-cases down the line (for e.g colstats, RLI, ....)
hudi-io/src/main/java/org/apache/hudi/io/compress/builtin/HoodieBuiltInNoneDecompressor.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
3636b93 to
9adc156
Compare
3934af1 to
c5918ee
Compare
|
The README is updated with HFile format description. |
vinothchandar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks in good shape. Can you clarify some of my questions on the code.
hudi-common/src/test/java/org/apache/hudi/io/storage/TestHoodieHFileReaderWriter.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/compress/HoodieCompressionFactory.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/compress/airlift/HoodieAirliftGzipDecompressor.java
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReaderImpl.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileDataBlock.java
Outdated
Show resolved
Hide resolved
hudi-io/src/main/java/org/apache/hudi/io/hfile/HFileReader.java
Outdated
Show resolved
Hide resolved
|
@yihua the question may be navie, is a native writer required to cut out the HBase deps eventually? |
Sorry for the late reply. Yes, we'll also implement native HFile writer. Eventually we'll remove HBase dependencies and use the native HFile reader and writer. HBase index still requires HBase dependencies but that’s going to be optional and not included in the bundle jar. |

Change Logs
This PR adds a Hudi-native HFile reader implementation independent of HBase.
Motivation
Hudi uses HFile format as the base file format for storing various metadata, e.g., file listing, column stats, and bloom filters, in the metadata table (MDT), as HFile format is optimized for range scans and point lookups. HFile format is originally designed and implemented by HBase. Historically, Hudi is tightly coupled with Hadoop ecosystem. Even now, popular engines like Spark, Flink, and platforms like EMR still rely on Hadoop dependencies for various functionality. So Hudi has chosen to directly use the HFile reader implementation provided by HBase.
This approach has a couple of problems:
TrinoFileSystemabstraction independent of Hadoop. Thus, Trino Hudi connector cannot read HFiles and the metadata table based on the current implementation.To address these two problems, one way is to port the relevant code of the HFile reader from HBase to the Hudi repo and maintain it. We have attempted this in #4695, but the LoC is more than 60K, which is large. The main problem is that there is a lot of code irrelevant to HFile that is included but not easy to trim due to the coupling with HBase functionality.
This led us to a better first step: to implement a Hudi-native HFile reader from scratch based on what Hudi really uses and make it independent of HBase library. This PR serves the purpose.
Approach
We follow the HFile format version 3 and only focus on what Hudi uses on the reader side. We summarize a simplified HFile format for Hudi in
hudi-io/hfile_format.md. Our Hudi-native HFile reader follows this format specification. This means that the Hudi-native HFile reader can read the HFiles written by an HBase HFile writer used by Hudi without any problem.The Hudi-native HFile reader provides almost the same semantics as the HBase HFile reader and scanner:
int seekTo(Key key), which enables multiple seeks with sorted keys, and each seek operation should move the cursor to the HFile inside the reader when necessary. This is essential for point lookups, range scan, and prefix lookup.Implementation
This PR introduces a new
hudi-iomodule for I/O related functionality, and the Hudi-native HFile reader implementation sits inside the new module.A new interface
HFileReaderis defined to support reading HFile with seeks. Here are the APIs:int seekTo(Key key): seek to or just before the passed lookup key. The return code indicates whether the key is found and what the current cursor points to:-1: when the lookup key is less than the first key of the file. The cursor points to the first key of the file.0: when the lookup key is found in the file. The cursor points to the matched key in the file.1: when the lookup key is not found, but it's in the range of the file. The cursor points to the greatest key that is less than the lookup key.2: when the lookup key is greater than the last key of the file, EOF is reached. The cursor points to EOF.boolean seekTo(): positions the cursor of this reader at the start of the file.boolean next(): move the cursor to the next entry in the file.Option<KeyValue> getKeyValue(): the key-value pair at the current cursor or position.boolean isSeeked(): whether one of the seek calls is invoked.Option<byte[]> getMetaInfo(UTF8StringKey key): gets info entry from file info block of a HFile.Option<ByteBuffer> getMetaBlock(String metaBlockName): gets the content of a meta block from HFile.long getNumKeyValueEntries(): total number of key-value entries in the HFile.void initializeMetadata(): initializes metadata based on a HFile before other read operations.HFileReaderImplis an implementation ofHFileReader. Here are some important classes created to support theHFileReaderImpl:BlockIndexEntry: represents the index entry of a data (or meta) block in the Data (or Meta) Index stored in the ROOT_INDEX block.HFileBlock: an abstract class representing a block in a HFile. It is extended byHFileDataBlock,HFileMetaBlock,HFileRootIndexBlock, andHFileFileInfoBlockfor different block types.HFileBlockReader: reads and parses one or more HFile blocks based on the start and end offsets.HFileCursor: stores the current position and key-value pair at the position in the HFile. The same instance is used as a position cursor during HFile reading.HFileTrailer: represents a HFile trailer, read first to understand the structure of the HFile.KeyValue: represents a key-value pair in the data block.Key: represents the key part only.UTF8StringKey: represents a UTF8 String key only, with no length information encoded. This is used by lookup key.The high-level algorithm of
seekTobased on a lookup key is:Same as HBase HFile scanner,
seekTo(key)does not support backward seek and the Hudi-native HFile reader throws an exception in this case. Before doing a backward seek, the caller has to callseekTo()again to reposition the cursor to the beginning of the file.Testing
Comprehensive unit tests have been added to
TestHFileReaderto test the new Hudi-native HFile reader. The integration of the Hudi-native HFile reader done by #10330 will also test the HFile reader functionality end-to-end.Impact
Removes dependency on HBase to read HFiles, which makes it much easier for engine integration, along other benefits mentioned above.
Risk level
low
Documentation Update
We have documented the HFile format. We will update the RFC accordingly.
Contributor's checklist