ヤフー株式会社は、2023年10月1日にLINEヤフー株式会社になりました。LINEヤフー株式会社の新しいブログはこちらです。LINEヤフー Tech Blog

テクノロジー

Hadoopのバージョン混用は可能? HDP 2.6.4 とコミュニティ版 Hadoop 3.2.1 におけるHDFSの互換性調査結果 

Yahoo! JAPAN Advent Calendar 2019の6日目の記事です。一覧はこちら(外部リンク)

トップ画像

(English translation is available here)

ヤフーで Hadoop の運用・開発をしている李 燮鳴です。私たちのチームでは Hadoop 3.2.1 に含まれる Router Based Federation (RBF) で Hadoop のスケーラビリティ問題の解決を試みています。この記事では RBF を導入する背景と Hadoop 3.2.1 と既存の実行系の互換性を紹介します。

背景および目的

Hadoopクラスタ@ヤフー

ヤフーでは、自社が提供している多種多様なサービスのログを分析してサービスの改善に役立てるため、Hadoop クラスタを複数運用しています。ソフトウェアスタックでは、HDFS をストレージシステムとして利用し、MapReduce, Tez, Hive, Pig, Spark などの実行系をリソースマネージャ (YARN) 経由で提供しています。またリソースマネージャを経由しない実行系として Presto も提供しています。

社内 Hadoop クラスタ構成の一例

図1. 社内 Hadoop クラスタ構成の一例

ヤフーでは、1000ノードを超える Hadoop クラスタが複数存在します。最大規模のクラスタは1500台以上の DataNode から成り立っています。以前の記事でも紹介したように、HDFS では1つのクラスタで扱えるデータ規模には限界があり、それ以上のデータを格納するためには複数のHDFSクラスタを用意して各クラスタに分割する必要があります。

しかしながら、クラスタを分割してしまうとクライアントから見たときに横断的にデータを活用できなくなり利便性が損なわれるため、複数のクラスタをまとめ、クライアントに1つのネームスペースとして提供する手法が必要とされます。Hadoop において、クラスタをまとめる手法として ViewFS と Router Based Federation (以下RBF) が提供されています。

ViewFS vs. Router Based Federation (RBF)

ViewFS では、クライアント側でマウントテーブルを保存しているのに対して、RBF は StateStore にマウントテーブルを保存しています。

図2は ViewFS のアクセスフローを示したもので、アクセスを行う際クライアントは自分のマウントテーブルを照会し、リクエスト先のディレクトリパスに対応した NameNode(NN) にアクセスします (図2中のⒶ)。そして該当 DataNode(DN) にデータの参照・作成を行います(Ⓑ)。

社内 Hadoop クラスタ構成の一例

図2. 社内 Hadoop クラスタ構成の一例

図3は RBF のアクセスを示したもので、クライアント(Client)からリクエストを受け取る(①)と、StateStore のマウントテーブルを参照し(②)、リクエスト先のディレクトリパスに対応したクラスタの NameNode(NN) にルーティングします(③)。クライアントのリクエストは適切な DataNode(DN) にリダイレクトされ、データの参照・作成を行います(④)。

Router Based Federation (RBF) のアクセスフロー

図3. Router Based Federation (RBF) のアクセスフロー

RBF に比べ、ViewFS は追加コンポーネントを必要としないため、簡単な構成となっています。しかし、ViewFS はクライアントにマウントテーブルを持つため、マウントテーブルを変更するたびにクライアントの設定ファイルを更新する必要があります。 私たちが運用するクラスタには1000以上の月間アクティブアカウントが存在し、彼らにマウントテーブルを更新させるのはコストが大きいと考えられます。

一方、RBFでは、StateStore に保存されたマウントテーブルが変更された瞬間、全てのクライアントから最新のマウントテーブルが参照されるようになります。 そのため、私たちのチームでは、RBFを採用しようとしています。

コミュニティ版 HDFS と HDP版 Hadoop の混用

Hortonworks Data Platform (HDP)CDH は Cloudera 社が提供している Hadoop のディストリビューションです。

私たちのチームでは、近年 HDP を利用して Hadoop を構築しており、現在 HDP 2.6.4 を使用しています。2019年12月時点の最新バージョンである HDP 3.1.4 や CDH 6.3.2 に含まれる HDFS も RBF を公式サポートしていないため、コミュニティ版 HDFS を導入することにしました。

一方、YARN, MapReduce, Hive や Spark のような実行系はバージョンが上がることによる既存クエリに対する影響が大きいため、現段階では HDFS のみをコミュニティ版に変更し、それ以外のコンポーネントは HDP 2.6.4 のものを流用することにしました。本番環境には HDFS 3.3 をデプロイする予定ですが、HDFS 3.3 は現時点ではリリースされていないため、この記事では、最新リリースである HDFS 3.2.1 を利用して分析を行います。

HDP 2.6.4 実行系とコミュニティ版 HDFS の互換性確認

Hadoop は Protocol Buffers を利用して通信のインターフェースを定義しているため、hdfs-client に互換性のない変更がないことを確認すれば、HDP版 Hadoop とコミュニティ版 HDFS の入力フォーマットが変わっていないことが確認できます。

比較対象バージョン:

比較する Protocol Buffers の定義ファイルの整理

Apache Hadoop 3.2.1 では、hdfs-client の Protocol Buffers の定義ファイルは下記のパスに配置されています:

hadoop-hdfs-project/hadoop-hdfs-client/src/main/proto

ClientDatanodeProtocol.proto
ClientNamenodeProtocol.proto
ReconfigurationProtocol.proto
acl.proto
datatransfer.proto
encryption.proto
erasurecoding.proto
hdfs.proto
inotify.proto
xattr.proto

一方、HDP 2.6.4 では、これらのファイルが下記のパスに配置されています:

hadoop-hdfs-project/hadoop-hdfs/src/main/proto

ClientDatanodeProtocol.proto
ClientNamenodeProtocol.proto
ReconfigurationProtocol.proto
proto/acl.proto
proto/datatransfer.proto
proto/encryption.proto
proto/hdfs.proto
proto/inotify.proto
proto/xattr.proto

互換性の確認

互換性の確認では、変更された Protocol buffers の Message について関連する JIRA や Commit を確認し、影響がないかを確認します。

メッセージの field に変更がある場合は下記の基準で判断します:

  • you must not change the tag numbers of any existing fields.
  • you must not add or delete any required fields.
  • you may delete optional or repeated fields.
  • you may add new optional or repeated fields but you must use fresh tag numbers (i.e. tag numbers that were never used in this protocol buffer, not even by deleted fields).

https://developers.google.com/protocol-buffers/docs/javatutorial#extending-a-protocol-buffer

ここでは例としてacl.protoの差分を詳細に説明:

--- hadoop-hdfs-project/hadoop-hdfs/src/main/proto/acl.proto    2019-10-09 19:26:58.000000000 +0900
+++ /Users/sri/Downloads/hadoop-3.2.1-src/hadoop-hdfs-project/hadoop-hdfs-client/src/main/proto/acl.proto    2019-09-10 23:35:49.000000000 +0900
@@ -21,7 +21,12 @@
 option java_generate_equals_and_hash = true;
 package hadoop.hdfs;

-import "hdfs.proto";
+/**
+ * File or Directory permision - same spec as posix
+ */
+message FsPermissionProto {
+  required uint32 perm = 1;       // Actually a short - only 16bits used
+}

 message AclEntryProto {
   enum AclEntryScopeProto {
@@ -61,11 +66,6 @@
   optional FsPermissionProto permission = 5;
 }

-message AclEditLogProto {
-  required string src            = 1;
-  repeated AclEntryProto entries = 2;
-}
-
 message ModifyAclEntriesRequestProto {
   required string src            = 1;
   repeated AclEntryProto aclSpec = 2;

import hdfs.protoの削除について:

  • FsPermissionProto が明示的に追加されたため、hdfs.protoを削除しても問題ありません
  1. 関連JIRA: https://jira.apache.org/jira/browse/HDFS-6984
  2. 関連Commit: https://github.com/apache/hadoop/commit/12e44e7bdaf53d3720a89d32f0cc2717241bd6b2#diff-c904c24f461666f80be15d52c2c0d0ca

message AclEditLogProtoの削除について:

  • AclEditLogProtoeditlog.proto に移動されているが、移動したあともMessageの定義が変わっていないため、問題はありません (Related Commitを参照)
  1. 関連JIRA: https://jira.apache.org/jira/browse/HDFS-8726
  2. 関連Commit: https://github.com/apache/hadoop/commit/fc6182d5ed92ac70de1f4633edd5265b7be1a8dc#diff-c904c24f461666f80be15d52c2c0d0ca

互換性確認の結果

下記の例外を除いて、HDP 2.6.4 の実行系とコミュニティ版の Hadoop 3.2.1 の HDFS を混用しても、不具合はないと考えられます。

例外:

検証環境では HDP 2.6.4 の実行系とコミュニティ版の HDFS 3.2.1 が実際に数カ月間稼働し、古いバージョンのクライアントがいる状況でも HDFS の Protocol Buffers を用いた RPC 通信について互換性に関する問題は発生していません。

まとめ

  • 互換性チェックは Hadoop だと Protocol Buffers の定義ファイル (*.proto) を読む必要があります。

    • 今回検証では HDFS のみを異なるバージョンに置き換えたため、hdfs-client のみをチェックしました。
    • YARN のバージョンを上げて古いクライアントが混在する場合は yarn-client も確認が必要となります。
  • バージョンがそろっているのが望ましいが、何らかの事情でそろわない (かつコミュニティがサポートしていると明言していない、コミュニティの言っていることが不安な) 場合は互換性をチェックした方が好ましいです。

  • 互換性がない部分があっても、実際のユースケースで使用していなければ無視できます。

  • このやりかたは、RPC 通信に Protocol Buffers を使っているミドルウェアなら同じように使用できます。


Compatibility Analysis of Running HDP 2.6.4 Execution Frameworks on HDFS of Apache Hadoop 3.2.1

Background and Motivation

Hadoop Clusters in Yahoo! JAPAN

Yahoo! JAPAN adopted Hadoop as the infrastructure for analyzing logs produced by various services. We employed HDFS as the storage and YARN for managing the resources and orchestrating jobs. On top of that, typical Hadoop execution frameworks (MapReduce, Tez, Hive, Pig, Spark), as well as Presto, are offered for the data scientists inside our company.

A typical configuration of Hadoop Cluster in Yahoo! JAPAN

Fig 1. A typical configuration of Hadoop Cluster in Yahoo! JAPAN

We are operating multiple Hadoop clusters at 1000-nodes scale. The largest one among those consists of more than 1500 DataNodes (slaves/workers). As you may know, there is a limitation on the amount of data that can be handled by a single Hadoop cluster, exceeding which, the data has to be divided and stored in multiple clusters.

However, running jobs and queries which access data separated on multiple clusters is quite inconvenient. Hence, a method of federating multiple clusters and providing them as a single namespace is preferred in such cases. ViewFS and Router Based Federation (RBF) are the two methods offered by Hadoop for achieving that purpose.

ViewFS vs Router Based Federation (RBF)

When federating multiple clusters with a single virtual namespace, the mount table is required to store the mapping from the original path in each cluster to the new virtual namespace.

In ViewFS, the mount table is stored as a file on the client-side. Whereas in RBF, a dedicated component (StateStore) is employed to hold the mapping information.

The flow of accessing data in ViewFS is shown in Fig 2. The client will refer the mount table stored on its local, and then access corresponding NameNode(NN) (Ⓐ in Fig 2) to acquire the block location. Finally, the client will communicate with DataNode(DN) (Ⓑ in Fig 2) for block access.

Accessing Data in ViewFS

Fig 2. Accessing Data in ViewFS

The flow of accessing data in RBF is shown in Fig 3. With RBF, when Router receives a request from the client (① in Fig 3), it will access the StateStore for mount table and figure out the right NameNode to be accessed (② in Fig 3), and then the request will be redirected to the corresponding NameNode(NN) (③ in Fig 3) to acquire the block location, and finally, the client will communicate the DataNode(DN) for block access (④ in Fig 3).

Accessing Data in Router Based Federation

Fig 3. Accessing Data in Router Based Federation (RBF)

When compared with RBF, ViewFS is a much simpler solution since it does not require a dedicated component. However, the maintenance cost is considerably higher because whenever the mapping is updated, the mount tables stored on the clients have to be updated accordingly. Considering that there are 1000+ monthly active accounts in our environment, we have chosen RBF as the federation solution.

Running Execution Frameworks of HDP on Top of Apache Hadoop

Hortonworks Data Platform (HDP) and CDH are Hadoop distributions offered by Cloudera.

We have adopted HDP for constructing Hadoop over the past few years and we are running HDP 2.6.4 right now. Since the latest (as of Dec 2019) HDP 3.1.4 and CDH 6.1.4 do not officially support RBF, we decided to replace the HDFS that comes with HDP 2.6.4 to the HDFS from the Apache community. We plan to deploy Apache Hadoop 3.3 into our production cluster. However, Apache Hadoop 3.2.1 will be used in this article since 3.3 is not yet released.

Updating YARN or other execution frameworks, such as MapReduce, Hive, or Spark, may have a greater impact on existing jobs and queries, therefore, we decided to replace only the HDFS, and stick to the HDP's version for other components.

Compatibility Analysis of Execution Frameworks in HDP 2.6.4 and HDFS of Apache Hadoop 3.2.1

Hadoop is utilizing Protocol Buffers for defining the RPC interface, the compatibility of the HDFS interfaces between HDP 2.6.4 and Apache 3.2.1 can be examined by analyzing the compatibility of Protocol Buffers definition files (*.proto) from hdfs-client of two versions.

The versions used in this article:

The Protocol Buffers Definition Files to be Compared

For Apache Hadoop 3.2.1, the Protocol Buffers definition files of hdfs-client are located in the following path:

hadoop-hdfs-project/hadoop-hdfs-client/src/main/proto

ClientDatanodeProtocol.proto
ClientNamenodeProtocol.proto
ReconfigurationProtocol.proto
acl.proto
datatransfer.proto
encryption.proto
erasurecoding.proto
hdfs.proto
inotify.proto
xattr.proto

For HDP 2.6.4, those counterparts are located in the following path:

hadoop-hdfs-project/hadoop-hdfs/src/main/proto

ClientDatanodeProtocol.proto
ClientNamenodeProtocol.proto
ReconfigurationProtocol.proto
proto/acl.proto
proto/datatransfer.proto
proto/encryption.proto
proto/hdfs.proto
proto/inotify.proto
proto/xattr.proto

Compatibility Analysis

The methodology of compatibility analysis is quite straight forward. We take the diff of Protocol Buffers definition files from two versions and check if the modified part is compatible. When messages are deleted or added, we check for the corresponding JIRAs or commits; when fields in a message are deleted, we judge that with the following rules:

  • you must not change the tag numbers of any existing fields.
  • you must not add or delete any required fields.
  • you may delete optional or repeated fields.
  • you may add new optional or repeated fields but you must use fresh tag numbers (i.e. tag numbers that were never used in this protocol buffer, not even by deleted fields).

https://developers.google.com/protocol-buffers/docs/javatutorial#extending-a-protocol-buffer

Here, the diff analysis of acl.proto is used as an example:

--- hadoop-hdfs-project/hadoop-hdfs/src/main/proto/acl.proto    2019-10-09 19:26:58.000000000 +0900
+++ /Users/sri/Downloads/hadoop-3.2.1-src/hadoop-hdfs-project/hadoop-hdfs-client/src/main/proto/acl.proto    2019-09-10 23:35:49.000000000 +0900
@@ -21,7 +21,12 @@
 option java_generate_equals_and_hash = true;
 package hadoop.hdfs;

-import "hdfs.proto";
+/**
+ * File or Directory permision - same spec as posix
+ */
+message FsPermissionProto {
+  required uint32 perm = 1;       // Actually a short - only 16bits used
+}

 message AclEntryProto {
   enum AclEntryScopeProto {
@@ -61,11 +66,6 @@
   optional FsPermissionProto permission = 5;
 }

-message AclEditLogProto {
-  required string src            = 1;
-  repeated AclEntryProto entries = 2;
-}
-
 message ModifyAclEntriesRequestProto {
   required string src            = 1;
   repeated AclEntryProto aclSpec = 2;

Deletion ofimport hdfs.proto:

  • FsPermissionProto was added explicitly, so it is safe to not import hdfs.proto
  1. Related JIRA: https://jira.apache.org/jira/browse/HDFS-6984
  2. Related Commit: https://github.com/apache/hadoop/commit/12e44e7bdaf53d3720a89d32f0cc2717241bd6b2#diff-c904c24f461666f80be15d52c2c0d0ca

Deletion ofmessage AclEditLogProto:

  • The deletion is safe because AclEditLogProto was moved to editlog.proto, and the definition of that stays unchanged. (Refer to the related commit)
  1. Related JIRA: https://jira.apache.org/jira/browse/HDFS-8726
  2. Related Commit: https://github.com/apache/hadoop/commit/fc6182d5ed92ac70de1f4633edd5265b7be1a8dc#diff-c904c24f461666f80be15d52c2c0d0ca

The Result of Compatibility Analysis

Running execution frameworks from HDP 2.6.4 on top of Apache Hadoop HDFS 3.2.1 is considered compatible except for the following exceptions:

We have run a test cluster with real workloads of MapReduce, Hive, and Spark with a mixed version of execution frameworks and HDFS for three months, and no compatibility issues were observed with regard to RPC defined by Protocol Buffers.

Takeaways

  • The compatibility analysis of Hadoop can be achieved by checking the compatibility of Protocol Buffers definition files (*.proto)
    • We only checked Protocol Buffers definition files from hdfs-client as we only replaced HDFS this time.
    • When replacing YARN to a different version, you should also check the compatibility of yarn-client.
  • It is always preferable to use components from the same version. You should always do a compatibility check when that is not possible.
  • You can safely ignore the incompatibility as long as you do not use the functionality related to that.
  • This methodology applies to not only Hadoop but also all the softwares which uses Protocol Buffers to define their RPC interfaces.

こちらの記事のご感想を聞かせください。

  • 学びがある
  • わかりやすい
  • 新しい視点

ご感想ありがとうございました


李 燮鳴 (Li Xieming)

Hadoop Data Engineer

Hadoop DevOps

このページの先頭へ