pub struct Hdfs { /* private fields */ }
services-hdfs
only.Expand description
A distributed file system that provides high-throughput access to application data.
§Capabilities
This service can be used to:
- stat
- read
- write
- create_dir
- delete
- copy
- rename
- list
-
presign - blocking
- append
§Differences with webhdfs
Webhdfs is powered by hdfs’s RESTful HTTP API.
§Features
HDFS support needs to enable feature services-hdfs
.
§Configuration
root
: Set the work dir for backend.name_node
: Set the name node for backend.kerberos_ticket_cache_path
: Set the kerberos ticket cache path for backend, this should be gotten byklist
afterkinit
user
: Set the user for backendenable_append
: enable the append capacity. Default is false.
Refer to HdfsBuilder
’s public API docs for more information.
§Environment
HDFS needs some environment set correctly.
JAVA_HOME
: the path to java home, could be found viajava -XshowSettings:properties -version
HADOOP_HOME
: the path to hadoop home, opendal relays on this env to discover hadoop jars and setCLASSPATH
automatically.
Most of the time, setting JAVA_HOME
and HADOOP_HOME
is enough. But there are some edge cases:
- If meeting errors like the following:
error while loading shared libraries: libjvm.so: cannot open shared object file: No such file or directory
Java’s lib are not including in pkg-config find path, please set LD_LIBRARY_PATH
:
export LD_LIBRARY_PATH=${JAVA_HOME}/lib/server:${LD_LIBRARY_PATH}
The path of libjvm.so
could be different, please keep an eye on it.
- If meeting errors like the following:
(unable to get stack trace for java.lang.NoClassDefFoundError exception: ExceptionUtils::getStackTrace error.)
CLASSPATH
is not set correctly or your hadoop installation is incorrect.
To set CLASSPATH
:
export CLASSPATH=$(find $HADOOP_HOME -iname "*.jar" | xargs echo | tr ' ' ':'):${CLASSPATH}
- If HDFS has High Availability (HA) enabled with multiple available NameNodes, some configuration is required:
- Obtain the entire HDFS config folder (usually located at HADOOP_HOME/etc/hadoop).
- Set the environment variable HADOOP_CONF_DIR to the path of this folder.
export HADOOP_CONF_DIR=<path of the config folder>
- Append the HADOOP_CONF_DIR to the
CLASSPATH
export CLASSPATH=$HADOOP_CONF_DIR:$HADOOP_CLASSPATH:$CLASSPATH
- Use the
cluster_name
specified in thecore-site.xml
file (located in the HADOOP_CONF_DIR folder) to replace namenode:port.
builder.name_node("hdfs://cluster_name");
§macOS Specific Note
If you encounter an issue during the build process on macOS with an error message similar to:
ld: unknown file type in $HADOOP_HOME/lib/native/libhdfs.so.0.0.0
clang: error: linker command failed with exit code 1 (use -v to see invocation)
This error is likely due to the fact that the official Hadoop build includes the libhdfs.so file for the x86-64 architecture, which is not compatible with aarch64 architecture required for MacOS.
To resolve this issue, you can add hdrs as a dependency in your Rust application’s Cargo.toml file, and enable the vendored feature:
[dependencies]
hdrs = { version = "<version_number>", features = ["vendored"] }
Enabling the vendored feature ensures that hdrs includes the necessary libhdfs.so library built for the correct architecture.
§Example
§Via Builder
use std::sync::Arc;
use anyhow::Result;
use opendal::services::Hdfs;
use opendal::Operator;
#[tokio::main]
async fn main() -> Result<()> {
// Create fs backend builder.
let mut builder = Hdfs::default()
// Set the name node for hdfs.
// If the string starts with a protocol type such as file://, hdfs://, or gs://, this protocol type will be used.
.name_node("hdfs://127.0.0.1:9000")
// Set the root for hdfs, all operations will happen under this root.
//
// NOTE: the root must be absolute path.
.root("/tmp")
// Enable the append capacity for hdfs.
//
// Note: HDFS run in non-distributed mode doesn't support append.
.enable_append(true);
// `Accessor` provides the low level APIs, we will use `Operator` normally.
let op: Operator = Operator::new(builder)?.finish();
Ok(())
}
Implementations§
source§impl HdfsBuilder
impl HdfsBuilder
sourcepub fn root(self, root: &str) -> Self
pub fn root(self, root: &str) -> Self
Set root of this backend.
All operations will happen under this root.
sourcepub fn name_node(self, name_node: &str) -> Self
pub fn name_node(self, name_node: &str) -> Self
Set name_node of this backend.
Valid format including:
default
: using the default setting based on hadoop config.hdfs://127.0.0.1:9000
: connect to hdfs cluster.
sourcepub fn kerberos_ticket_cache_path(
self,
kerberos_ticket_cache_path: &str,
) -> Self
pub fn kerberos_ticket_cache_path( self, kerberos_ticket_cache_path: &str, ) -> Self
Set kerberos_ticket_cache_path of this backend
This should be configured when kerberos is enabled.
sourcepub fn enable_append(self, enable_append: bool) -> Self
pub fn enable_append(self, enable_append: bool) -> Self
Enable append capacity of this backend.
This should be disabled when HDFS runs in non-distributed mode.
sourcepub fn atomic_write_dir(self, dir: &str) -> Self
pub fn atomic_write_dir(self, dir: &str) -> Self
Set temp dir for atomic write.
§Notes
- When append is enabled, we will not use atomic write to avoid data loss and performance issue.
Trait Implementations§
source§impl Builder for HdfsBuilder
impl Builder for HdfsBuilder
source§impl Debug for HdfsBuilder
impl Debug for HdfsBuilder
source§impl Default for HdfsBuilder
impl Default for HdfsBuilder
source§fn default() -> HdfsBuilder
fn default() -> HdfsBuilder
Auto Trait Implementations§
impl Freeze for HdfsBuilder
impl RefUnwindSafe for HdfsBuilder
impl Send for HdfsBuilder
impl Sync for HdfsBuilder
impl Unpin for HdfsBuilder
impl UnwindSafe for HdfsBuilder
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CompatExt for T
impl<T> CompatExt for T
§impl<T> Conv for T
impl<T> Conv for T
§impl<T> FmtForward for T
impl<T> FmtForward for T
§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.§fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
fn fmt_list(self) -> FmtList<Self>where
&'a Self: for<'a> IntoIterator,
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T
in a tonic::Request
§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read more§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.§impl<T> Pointable for T
impl<T> Pointable for T
§impl<T> Tap for T
impl<T> Tap for T
§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read more§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read more§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read more§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read more§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read more§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read more§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.