fuse_dfs を使用して、HDFS 内のファイルをローカル ファイル システムにマップします (コンパイル + チュートリアルを使用)

Hadoop の HDFS は非常に成功した分散ファイル システムであり、多くの企業が分散プロトタイプ システムを構築する際の基盤となるファイル システムとして使用しています。

残念ながら、HDFS の操作には、hdfs dfs -ls / など HDFS の読み取りと書き込みがローカル ファイルの読み取りと書き込みと同じくらい簡単になるように、HDFS をハード ディスク上のフォルダーとドライブ文字にマップする方法はありますか? はい、それが Hadoop に付属の fuse_dfs ツールです。このツールを使用して、HDFS をローカル ファイル システムにマウントし、通常のファイルの読み書きで HDFS を操作できます。

このツールをコンパイルして使用する方法を紹介しましょう。

⚠️注:このツールの使用方法は、Hadoop v2 と v3 で大きく異なります。一部の記事 (この記事など) では、v3 には適用されなくなった v2 の操作手順が紹介されています。

この記事の内容は主に、sleeplessbeastie によるこのブログ投稿からのものです.読者は、このブログ投稿を参照して、fuse_dfs を使用することもできます。

fuse_dfs をコンパイルします。

1. まず、JDK と Hadoop をインストールする必要がありますHadoop のインストールに関するオンライン チュートリアルは多数あるため、この記事の範囲外です。インストール後、 root 以外のユーザーを作成する必要があります。このユーザーの下で、インストールされている Hadoopバージョンと一致するソース コード パッケージを取得し、ダウンロードして解凍します。

# 获取对应版本的源码。你需要到 Hadoop 官网手动下载,获取最新的源码包链接;
wget https://dlcdn.apache.org/hadoop/common/hadoop-3.3.4/hadoop-3.3.4-src.tar.gz

# 解压 Hadoop 源码
tar xvf hadoop-3.3.4-src.tar.gz

# 进入到解压好的文件夹中
cd hadoop-3.3.4-src

2. Docker をインストールします。

# 使用 Docker 官方提供的一键安装脚本
curl -fsSL https://get.docker.com -o - | sudo bash

3. コンパイル環境に入ります。Hadoop には Docker ベースのコンパイル環境が用意されており、次のスクリプトを実行するだけで、Docker イメージが自動的にビルドされ、コンパイルに必要なさまざまなパッケージがインストールされ、コンテナーに入ります。

./start-build-env.sh

⚠️ このステップでは、現在のユーザーが root でないことを確認する必要があります。そうしないと、不可解なエラーが報告されます。

4. コンテナーに入ると、~/.m2 フォルダーの所有者が実際には root であることがわかります。これにより、後で Maven が正しく実行されなくなるので、修正しましょう。

chown -R $(whoami):$(whoami) ~/.m2

5. HOME ディレクトリに hadoop フォルダを入力します。

cd ~/hadoop

6. Maven を呼び出して、Hadoop ソース コードをコンパイルします。Maven は既に Docker イメージにインストールされているため、手動でインストールする必要はありません。このステップは少し時間がかかるかもしれません. 高速化するには海外のサーバーを使用するのが最善です. 私のマシンで初めてコンパイルするのに 36 分かかりました:

mvn package -Pnative -Drequire.fuse=true -DskipTests -Dmaven.javadoc.skip=true

7. 現在のコンテナーの ID を確認し、記録します。Docker では、デフォルトで、ホスト名はコンテナーの ID です。

cat /etc/hostname

8. fuse_dfs 実行可能ファイルのアドレスを見つけます。

sudo find / -name 'fuse_dfs'

私のマシンと Hadoop バージョン 3.2.2 では、見つかったアドレスは次のとおりです。

/home/ipid/hadoop/hadoop-hdfs-project/hadoop-hdfs-native-client/target/main/native/fuse-dfs/fuse_dfs

9. fuse_dfs 実行可能ファイルがあるディレクトリを入力し、依存するバイナリ ライブラリを確認します。

ldd fuse_dfs

私のマシンの出力は次のとおりです。

linux-vdso.so.1 (0x00007ffd357fa000)
libfuse.so.2 => /lib/x86_64-linux-gnu/libfuse.so.2 (0x00007f57ba209000)
libhdfs.so.0.0.0 => not found
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f57b9fea000)
librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f57b9de2000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f57b99f1000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f57b97ed000)
/lib64/ld-linux-x86-64.so.2 (0x00007f57ba652000)

libfuse.so.2 と libhdfs.so.0.0.0 が依存していることがわかります。そのため、次のステップでそれらをコンテナーからコピーする必要があります。そうしないと、コンパイルされた fuse_dfs を実行できません。

10. 上記の 2 つのファイルの場所を見つけます。

sudo find / -name 'libfuse.so.2'
sudo find / -name 'libhdfs.so.0.0.0'

11. コンテナーを終了します。

exit

12. 2 つの依存ライブラリを処理します。libfuse の場合、fuse_dfs が依存するライブラリのバージョンは 2 であるため、システムに付属のパッケージ マネージャーを直接使用して libfuse2 をインストールできます。

sudo apt install libfuse2

13. fuse_dfs の本体と libhdfs のダイナミック リンク ライブラリについては、コンテナーからコピーする必要があります。手順 7 と 10 で記録したコンテナー ID とファイル アドレスを覚えていますか? それらをそれぞれの場所からコピーし、ファイルのアクセス許可とファイルの所有者を変更します。

# 创建一个文件夹,存放文件,免得太乱
mkdir fuse_dfs
cd fuse_dfs

# 把编译好的 fuse_dfs 从容器里拷出来
docker cp <容器ID>:<fuse_dfs 文件地址> ./fuse_dfs

# 把编译好的 libhdfs 从容器里拷出来
# 注意这里的 cp 命令有个 -L 的参数,这是为什么呢?参见下文~
docker cp -L <容器ID>:/home/<用户名>/hadoop/hadoop-hdfs-project/hadoop-hdfs-native-client/target/native/target/usr/local/lib/libhdfs.so.0.0.0 ./libhdfs.so.0.0.0

# 文件此时有可能不是可执行状态,需要加上可执行权限
chmod 755 ./libhdfs.so.0.0.0

ここで cp コマンドに-Lパラメーターシンボリック リンクを解決し、それが指す実際のファイルをコピーするためです。

ご存知のように、Linux の慣例では、大きなバージョン番号のみを持つソフト リンクを使用して、完全なファイル名を持つダイナミック リンク ライブラリをポイントします。libyaml-0.so.2たとえば、システム ディレクトリにはと の2 つのファイルがありlibyaml-0.so.2.0.6、 はlibyaml-0.so.2libyaml-0.so.2.0.6指す。したがって、-Lスイッチ、最後にコピーされたものがショートカットになります。

14. fuse_dfs を実行するためにいくつかの環境変数が必要です。面倒なので、それらを設定するスクリプトを作成するだけです。fuse_dfs_wrapper.sh次の内容で呼び出されるシェル スクリプトを記述します。

#!/bin/bash
# 此脚本用于代替 fuse_dfs 命令,执行本脚本即相当于运行 fuse_dfs 本体

# 这里填写你的 Hadoop 安装位置
export HADOOP_HOME=/usr/local/hadoop

# 这里填写你的 JDK 安装位置
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64

# 检测当前用户是不是 root,如果不是就退出并报错
if [ "$(id -u)" != "0" ]; then
    echo "此脚本必须使用 root 用户运行" 1>&2
    exit 1
fi

# 计算当前脚本所在的目录位置
CURRENT_SHELL_FILE_DIR=$(dirname $(readlink -f "$0"))

# 设置 LD_LIBRARY_PATH,加入脚本所在目录,
# 这样一来运行的时候,就能找到 libhdfs.so.0.0.0
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$CURRENT_SHELL_FILE_DIR

# 找到 Hadoop 安装目录中所有与 HDFS 相关的 Jar 包地址,并加入到 CLASSPATH 中
export CLASSPATH=.
while IFS= read -r -d '' file
do
  export CLASSPATH=$CLASSPATH:$file  
done < <(find ${HADOOP_HOME}/share/hadoop/{
    
    common,hdfs} -name "*.jar" -print0)

# 把运行本脚本时传入的参数转发给 fuse_dfs
./fuse_dfs $@

その後、上記のスクリプトを fuse_dfs コマンド自体の代わりに使用できます。

fuse_dfs の使用

1. マッピングを容易にするために、/root の下にフォルダーを作成します。

sudo mkdir /root/hdfs

2. 次に、次のコマンドを実行して、HDFS をファイル システムにマップします。

sudo ./fuse-dfs-wrapper.sh dfs://<NameNode 地址>:<端口号> /root/hdfs -oinitchecks

3. 閉じる場合は、fuse_dfs プロセスを終了し、/root/hdfs のマッピングを閉じます。

sudo killall fuse_dfs
sudo umount /root/hdfs

あとがき

どうですか?とてもシンプルですか?私はこのソリューションのパフォーマンス テストを行っていませんが、外国のブログがテストを行っており、結論として、このソリューションは基本的にネットワーク カードの帯域幅を伝送速度で満たすことができ、少なくとも代替ソリューション。試してみてください。間違いや追加したいことがあれば、コメント欄でお知らせください。

おすすめ

転載: blog.csdn.net/llbbzh/article/details/128394729