Multi-Raft: Apache Hadoop Ozoneの書き込みパフォーマンスを加速する

2020/06/24 に公開された「Multi-Raft — Boost up write performance for Apache Hadoop-Ozone」の翻訳です。

関連リンク

Apache Hadoop Ozone: Apache Hadoop 用のオブジェクトストアの紹介
Apache Hadoop Ozone: オブジェクトストアの概要
Apache Hadoop Ozone — オブジェクトストアのアーキテクチャー
Ozoneのベンチマーク: CDP用Clouderaの次世代ストレージ
Apache Hadoop Ozone セキュリティ — 認証

この記事は、Li Cheng, Software Engineer, Tencent Inc.による寄稿です

本番環境で Hadoop-Ozone を利用する

Apache Hadoop Ozone は、ビッグデータプラットフォームにおける新時代のオブジェクトストレージのソリューションであり、強い一貫性を担保しスケールします。Ozone は Apache Ratis (Incubating) で実装される Raft プロトコルを用いて分散システムにおける高可用性を実現しています。

Tencent での私のチームは数ヶ月前 (訳注: 2020年初頭と考えられます) に本番環境でのバックエンドのオブジェクトストレージとして Ozone を採用し始め、より多くのデータウェアハウスユーザーを受け入れてきました。そこで発見したのは、DataNode あたり単一の Ratis パイプラインを持つ Ozone ではディスク帯域を使い切ることができず、結果として書き込みレイテンシが安定しないということでした。

Ozone は Raft プロトコルを用いてデータ複製とグローバルな一貫性を実現しています。Apache Ratis は Raft プロトコルの実装であり、DataNode 間での一貫した書き込みを提供します。Ozone は DataNode からなる Raft のグループ (つまり複製係数、デフォルトで 3つ) を Ratis パイプラインとして隠蔽しています。Ozone 0.5.0 より前のリリースでは、Ozone は各 DataNode に唯一ひとつの Ratis パイプライン (Raft グループ) への参加を許可していました。

このポストでは、単一 Raft による Ratis パイプラインのパフォーマンスについての調査内容、ならびに最新の 0.5.0 (訳注: 元記事執筆時) に追加された multi-Raft による Ratis パイプラインがどのように書き込みパフォーマンスの向上に寄与したのかを説明したいと思います。

single-Raft での書き込みパフォーマンスの問題

私たちの Ozone クラスタはすべて HDD の物理マシンで構成されており、10Gps のネットワークと各ノード 12 本のディスクを備えています。上流のユーザーは Hive SQL のクエリを書き、クエリの結果は Ozone S3 ゲートウェイを介して Ozone クラスタにファイルとして保存します。生成されるファイルのサイズは多様で、数バイトから数ギガバイトに及びます。このファイルサイズの違いを見るため、レイテンシの分布をプロットしてみました。ノイズを削除するため、大きなファイル (GB) の書き込みは排除しました。

この図から、68% 以上の書き込みが 0.2 秒以内に完了していますが、気になるのは 20% 以上の書き込みが 2–3 秒もかかっていることです。詳しくみてみると、書き込みに 2–3 秒かかったファイルのサイズは数バイトからメガバイトと多様でした。

そこで、DataNode のディスク使用量を確認しました。

各 DataNode は 10 本の HDD を Ozone 用に設定していますが、4 本のみ使用されており、そのうち 3 本だけが完全にビジーになっていることがわかります。つまり、DataNode が効率的に使われていないことになります。このことから、書き込みが溜まり、結果として(レイテンシが)バラバラになっているのだと推測しました。つまり、DataNode の書き込みパフォーマンスを上げるためには Ozone クラスタにもっとディスクを使わせる必要があるということです。

Ozone の書き込みパス

Ozone には三つのメインのコンポーネントがあり、Ozone Manager (OM)、Storage Container Manager (SCM)、そして DataNode (DN) です。SCM はコンテナ、パイプライン、RocksDB にあるその他のメタデータを管理します。DataNode は SCM にレポートとハートビートを送ります。Ozone は莫大な数のコンテナ (クラスタのあちこちに存在します) にデータを保存し、各コンテナはデータブロックを DataNode に割り当てます。すべてのコンテナを管理するために、Ozone は論理グループとしてのパイプラインを作成し、冗長化を目的として複数の DataNode からコンテナを組み立てます。

そのため、パイプラインは Ozone の書き込みパス、つまりクライアントがリクエストを出してから DataNode のディスクに書き込まれるまでのすべて、を司ることになります。その舞台裏では、パイプラインは Raft プロトコルを用いてリーダーを一つもつ Raft のグループを作成します。Ozone は 3 複製モードもサポートしているので、各パイプラインには三つの DataNode が存在し、そのうちのひとつがリーダーに選出されます。パイプラインを通じてデータはリーダーの DataNode に書き込まれ、その後フォロワーに複製されます。このデザインは、Ozone が書き込みトラフィックをクラスタ全体に広範囲に分散させるのに役立っています。

結果として、Ozone の書き込みパフォーマンスは、DataNode のディスクへの書き込み負荷をパイプラインがいかにうまくバランシングするかにかかっています。パイプラインは、ディスクへの書き込み負荷を分散させるために RaftLog (Raft における WAL の実装) の恩恵を受けています。つまり、Ozone の書き込みパフォーマンスには二つの主要因があると考えられます。

  • 処理能力を上げるために、多くのパイプラインを用意してコンテナへのアクセスを促進すること
  • ディスクをどれだけ効率的に使用できるか

multi-Raft とは何か、どう役立つのか?

Ozone のパイプラインは Raft プロトコルを用いてリーダーからフォロワーの DataNode への複製を実現しています。パイプラインは、各 DataNode が一つのパイプラインに参加するところから始まります。例えば 10 台のノードがあるとき、Ozone クラスタは 1 台のマスターと 9 台の DataNode から構成され、3 複製のパイプラインが三つあることになります。もっと多くのパイプラインやコンテナが必要であれば、ノードを追加することになるでしょう。しかし、その数は複製係数のきっちり倍数とする必要があります。そうでなければ、余ったノード (複製数 3 であれば 2 台まで) が書き込みパイプラインに使用されないことになります。つまり、パイプラインが DataNode を重複して持てるようにするために、パイプラインと DataNode のマッピングを一対複数から複数対複数への発展させる必要があるということです。これによりパイプラインの数は大幅に増えることになります。

ここで multi-Raft の登場です。これによりすべての DataNode が複数のパイプラインへの参加できるようになるのです。multi-Raft が意味するところは、すべての DataNode が複数の Raft パイプラインを持ち、RaftLog をすべてのディスクに書き込むということです。すべてのディスクを RaftLog のディレクトリとして設定すると、multi-Raft のパイプラインはディスクをより効率よく使用することができます。これは、ディスクの負荷が複数のコンテナにより分散されるからです。multi-Raft により、すべての DataNode はパイプラインのリーダーになる一方で、他のパイプラインではフォロワーにもなり得ます。このことで、ネットワーク負荷もバランシングできることになります。

3 台の DataNode の multi-Raft クラスタに4 台目の DataNode (DN4) を追加すると、SCM は追加のパイプラインを 3 つ (=4–1) 作成することができ、すべての DataNode がそれらのパイプラインに参加することができます。single-Raft の場合は、DN4 はバックアップとしてしか使えません。それぞれの DataNode がいくつのパイプラインに参加できるかの負荷上限は設定されています。DataNode がその負荷上限に達すると、バックグラウンドのスレッドはパイプラインを作成しなくなります。

DataNode の数を N、負荷上限を M とすると、single-Raft は N/3 のパイプラインしか作成できないのに対し、multi-Raft は (M*N)/3 のパイプラインを作成できます。multi-Raft クラスタのコンテナ使用率は、最大 M 倍となります。

この負荷上限値により、パイプラインが不要に作成されることで溢れ返るようなことは発生しなくなります。

データパイプラインのためのラックアウェアネス

パイプラインの配置ポリシーにはラックアウェアネスも考慮されるので、パイプラインは異なるネットワークのラックから DataNode を選択します。このことは、コンテナのデータローカリティ向上に寄与し、クラスタが成長し多くのラックを跨がるようになると最終的には Ozone の IO スループット向上にも貢献します。

multi-Raft のパイプライン割り当ては、データローカリティとデータの耐久性のバランスをとるために同じラックから二台のノードを選択し、異なるラックから一台を選択します。また、multi-Raft ではすべてのノードが同じ数のパイプラインに参加するように、パイプライン割り当ての負荷をすべてのノードに対して調整します。

結論とベンチマーク

multi-Raft は以下の三つのゴールを達成しました。これらは最終的に Ozone の書き込みパフォーマンスを加速させるものです。

  1. マシンやディスクを追加することなく、コンテナやパイプラインの数をより効率的に増やすことができる
  2. ディスク IO やネットワークの負荷を調整することでより IO の帯域を高めることができる
  3. パイプラインの割り当てにおいてマシンを「無駄に」することなく DataNode を使い切れる

multi-Raft を有効化した社内のクラスタにてユーザーからの書き込み負荷をかけた場合に、そのうちの 98% が 0.2 秒で完了するようになりました。これは、single-Raft のクラスタに対して 30% 以上の向上です。以下に結果を示します。


比較のために他のベンチマークもとったので紹介します。

クラスタの構成:

9 台の物理マシンにそれぞれ 10 本の HDD を用意し、1 台がマスター、8 台が DataNode。

1.実行時間が長いジョブのレイテンシの比較

クライアントは Ozone S3 ゲートウェイに 100KB のファイルを書き込みます。

この図から、multi-Raft のクラスタの書き込みレイテンシは single-Raft に比べて 1/3 ほどになっていることがわかります。それだけでなく、single-Raft では完了できなかったような大規模スケールの書き込みも達成しました。

注: 上記のテスト環境で、single-Raft では 100KB のファイルを 60,000 個書き込むのに 17 時間かかりました。

2. ディスク使用量の測定

testDFSIO を用いて 1GB のファイルを 1000 個書き込みます。書き込み並列度は 90 です。

パイプラインがひとつの場合

パイプラインが 12 の場合

パイプラインが 15 の場合

single-Raft から見ていくと、パイプラインが 1 つの場合ディスク使用量は均等になっていません。multi-Raft を有効にすると、パイプラインが 12 の場合に改善が見られました (ozone.datanode.pipeline.limit は 4)。パイプラインが 15 になるとディスク負荷が過剰になります (ozone.datanode.pipeline.limit は 5)。マシンの追加はしなかったことに留意してください。

multi-Raft により、Ratis の RaftLog の書き込みにおいてすべてのディスクを使い切ることができるようになりました。

謝辞

multi-Raft の機能は Ozone の書き込みパフォーマンスを改善しました。我々は Apache Hadoop-Ozone のコミュニティに感謝をしたいと思います。 特に Cloudera の Xiaoyu Yao, Sid Wagle, Jitendra Pandey、Tencent の Sammi Chen, Jerry Shao, Junping Du にはこの改善にあたってのコントリビューションや指南をいただき感謝します。

さらなる改善予定について

Ozone における multi-Raft を改善する案について紹介します。
Ozone が Ratis に対してリーダー DataNode を推薦できるようにする。これによりリーダーを均等に分布させることができる
SCM が各 DataNode に適切な数のパイプラインを決定できるようにする。これは例えば DataNode の数、ディスク本数、Ratis クライアントのリトライポリシーやコネクションタイムなどといった設定により調整する
DataNode のディスクがグレードアップしたときに、multi-Raft が最適な決定を下せるようなアルゴリズムを見つける

ユーザーガイドと補足資料

multi-Raft を有効にするために必要なのは、ozone-site.xml に ozone.datanode.pipeline.limit を追加することだけです。また、デフォルトの 2 から必要に応じて設定値を変えてください。我々の推奨は、すべてのハードディスクを設定に追加すること、また Ratis クライアントのリトライカウントを減らすことです。これにより、単一の通信が長期にわたってスタックするのを防ぐことができます。今後、SCM が Ozone から別の統計情報を収集することでパイプラインの負荷の上限を決定できるようにするつもりです。これにより、ユーザーは設定値を気にすることなく multi-Raft による書き込みパフォーマンスの恩恵を得ることができるでしょう。

訳者謝辞

翻訳記事公開にあたり、Cloudera Japan の Bin Liu にレビューしていただきました。また、@kuenishi@kernel023 両名にもレビューいただきました。ありがとうございます。

 

ホワイトペーパー: 機械学習を成功に導く3つの方法

Cloudera Japan Marketing
この著者の他の記事

コメントする

あなたのメールアドレスは公開されません。また、コメントにリンクを貼ることはできません。