Skip to content

feat(storage): Add HDFS support via opendal services-hdfs (libhdfs) - #3515

Draft
comphead wants to merge 2 commits into
apache:mainfrom
comphead:feat-storage-hdfs-libhdfs
Draft

comphead wants to merge 2 commits into
apache:mainfrom
comphead:feat-storage-hdfs-libhdfs

Conversation

@comphead

@comphead comphead commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Which issue does this PR close?

What changes are included in this PR?

#1130 agreed to ship both HDFS clients (consensus). #3111 added hdfs-native. This PR adds libhdfs as a second transport. The hdfs-native backend and the iceberg crate are unchanged.

  • A new opendal-hdfs feature (OpenDAL's services-hdfs, experimental, not in opendal-all) adds OpenDalStorageFactory::Hdfs and OpenDalStorage::Hdfs.
  • Hadoop's Java client reads its configuration from CLASSPATH, so nameservices, HA and Kerberos work as in Hadoop. No hdfs.* or hadoop.* property applies.
  • The backend passes hdfs://<authority>/ to libhdfs as written and caches one operator per NameNode. Authority-less paths use hdfs:///, which fails like Hadoop when fs.defaultFS is not HDFS. libhdfs's default would fall back to the local disk.
  • OpenDalResolvingStorageFactory still routes hdfs:// to hdfs-native.

Why both: through OpenDAL, hdfs-native looks up delegation tokens for a synthetic nameservice, so it misses the tokens Spark executors and YARN containers carry. libhdfs uses the JVM's credentials.

Costs: building needs a JDK, and binaries built with the feature need $JAVA_HOME/lib/server on the library path. The tests job sets it. The feature does not build on Windows, where hdrs does not compile, so the Windows build job leaves it out, as OpenDAL's CI does.

Are these changes tested?

  • Two unit tests cover path mapping, delete_stream keys and relativize_path. A mutation check of the new code caught all 7 mutations.
  • Three integration tests run against the HDFS fixture: read and write, deletes, and an authority-less path. CI loads Hadoop's jars from the fixture's image, and they pass there.
  • make check-clippy, cargo fmt, taplo, cargo machete and public-api.txt pass locally.

AI Disclosure

Developed with AI assistance (Claude Code), which drafted the code, tests and this description. I reviewed the changes.

Add an `opendal-hdfs` feature that serves `hdfs://` paths through
OpenDAL's `services-hdfs`, libhdfs over JNI, next to `hdfs-native` as
apache#1130 agreed. Only the transport differs. Hadoop's Java client reads its
configuration from CLASSPATH and resolves nameservices, HA, Kerberos and
`fs.defaultFS` itself, so the backend maps a path to the NameNode URI
`FileSystem.get` takes and caches one operator per NameNode. The
`hdfs-native` backend and the `iceberg` crate are unchanged.
@comphead
comphead force-pushed the feat-storage-hdfs-libhdfs branch from 6d6c7bb to 2b4f03d Compare October 23, 2026 00:36
`hdrs` 0.3.4, the libhdfs binding behind `opendal-hdfs`, does not compile
on Windows: it uses the Unix-only `libc::O_CLOEXEC` and assumes a 64-bit
`tTime`. OpenDAL's own CI leaves `services-hdfs` out of its Windows build
as well.
@comphead

Copy link
Copy Markdown
Collaborator Author

I'm planning to test this on the real cluster with kerberos protected

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant