カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

Hadoop SlaveサーバとJBODとRAID

夏はビールがことごとくうまいなと感じる@masudaKです。 少し前にHadoop専用サーバの環境構築をする機会に恵まれたのですが、ディスク構成をどうするかでわりと目新しいことばかりだったので、備忘録も兼ねて文字に起こしておきます。

前提として、HadoopのMasterではJobTrackerとNameNodeが動いて、SlaveではTaskTrackerとDataNodeが動いてるとします。DataNodeが動くSlaveはクラスタ構成になっていて、HDFSによってデータが分散・冗長化されているとします。

今回の記事ではジョブのデータを読み書きし、IOに対するケアが必要なSlaveのディスク構成を対象とします。Masterはメタデータなど大事なデータは保存してますが、読み・書きの量は少ないのと、単にRAID1で組んでおけば、ディスクに対するケアはそこまで必要ないので、この記事では取り上げません。

まずRAIDのお話

もし、明日HadoopのSlave用のサーバを3台構築して欲しいと言われたら、どういうディスクの組み方をすればいいのか。その問に答えようというのがこの記事の目的です。データの保全性とかIOパフォーマンスとかとか。そういう視点でどうディスクを組むかという話です。

HDFS上にあるデータは解析データなのですごく大事なわけですが、冗長性・保全性という意味ではHDFSがクラスタで守ってくれますので、単一サーバで厳重に守る必要はありません。じゃ、どうするのかという話をしなければならないわけです。ここで重要なのが「RAID」と「JBOD」という概念です。

まず、それらの概念について新卒とか向け&自分の記憶を整理するために、ざっくり概要を説明します。 RAIDとはなんのか。かの有名なWikipediaでは以下のように書かれています。

RAID(Redundant Arrays of Inexpensive Disks、または Redundant Arrays of Independent Disks、レイド)とは、複数台のハードディスクを組み合わせることで仮想的な1台のハードディスクとして運用し冗長性を向上させる技術。ディスクアレイの代表的な実装形態で、主に信頼性・可用性の向上を目的として用いられるものである。

RAIDという概念は、David A Patterson, Garth Gibson, and Randy H Katzが書いた"A Case for Redundant Arrays of Inexpensive Disks (RAID) "というタイトルの論文(ACMのアニュアルレポート?)で1988年に初めて定義されたようです。

この論文ではCPUやメモリのパフォーマンス向上に比べると、ディスクのパフォーマンスはそこそこで、Single Large Expensive Disks(@masudak注: 当時は、今でいうFIOみたく高価なストレージが普及しようとしていたのかもしれない)が成長し続けてるものの、パーソナルコンピューター向けに新たな提案が必要だとして、コスパがいい概念としてRAIDをあげている。この論文ではRAID1からRAID5までの概念を提示しており、個人的にはパフォーマンスよりはデータの冗長性に重きが置かれている気はするけど、まぁ20年以上前にこういう概念が出たわけですな。この論文で定義されてるレベルは以下の5つです。

  • RAID1: ディスク2本に同じデータを書いて冗長化。
  • RAID2: ストライプ単位が1bitで、ハミングコードでデータの整合性チェック。この計算コストがめちゃ高いし、そこまで厳密なチェックが必要なものは早々ない。
  • RAID3: パリティによる整合性チェックを導入。bit・byte単位でアクセス。
  • RAID4: RAID3同様相変わらずパリティドライブを使う。アクセスはブロック単位になるので、パフォーマンスがRAID3よりあがる。SPOFはRAID3と変わらず。
  • RAID5: ブロック単位でアクセスしつつ、パリティブロックを使い、パリティ専用ドライブは使わない。

データの整合性をどのレベルで担保するのかを、複数のディスクを使って概念提案してるわけですね。 以上のように提案はされてますが、業務で使うであろう以下の3つも念のため追加しておきます。

  • RAID0: ストライプ単位で、ディスクそれぞれにわけて書き込む。
  • RAID6: パリティの種類を2種類にして、冗長性を増す。
  • RAID10: ストライプ単位でわけて書き込みパフォーマンスをあげつつ、同じデータを書き込んで冗長化。

ざっくりですいませんが、間違い・補足等あればご指摘お願いします。(力尽きた…

次にJBOD

ここで、RAIDに対抗する概念としてJBOD (Just a Bunch Of Disks) を説明します。

JBODというのは単純に言えば、ディスクを並べて、トータルの容量を増やそうというシンプルな構成のことを指します。RAID0同様、冗長性はなく、一つのディスクがおなくなりになれば、データは壊れしまいます。また、RAIDのように一番小さなディスクの影響を受けることはなく、各ディスクのサイズの総量がトータルのサイズとなります。

歴史的には、JBODはWindows Home Serverで導入された概念のようです(調べるのに心折れたのでぐぐってください

こっちは別にレベルとかはなく、ある一つの概念ですな。 面倒なんですが、このJBODですが、RAIDコントローラーによっては、RAIDの設定画面で選べたりします。RAID0にするか、RAID1にするか、JBODにするかみたいな。聞いた話では、このような設定を選んだディスクは、一つのVirtual Diskとなり、サイズは全てのディスクの総量となるようです。サイズは全て足し、Volumeは一つという感じですね。 逆に、RAIDコントローラーでこのような設定が選べない場合は、少し考える必要があります。それは後述しますので、ここでは飛ばします。 また、RAID0のように、ストライピングではないので、効率のよい読み書きができるわけではありません。なので、パフォーマンスはかなり怪しいかもですな。

HDFSとディスク構成

んで、なぜJBODという概念を出したのか。 Hadoopに関わると分かるのですが、JBODという概念がちょくちょく出てきます。ぐぐると、RAIDは組まないほうがいいとか、JBODのほうが高速というのが見つけられるかと思います。正直、概念が錯綜してたのでしょう。Dellが以下のような資料を公開しています。

Dell | Clouderaソリューション リファレンスアーキテクチャでは以下のように書かれています。

JBOD とシングルディスク RAID 0 構成の違い Hadoop コミュニティは、JBOD (Just a Bunch of Disks、単なるディスクの集まり) と呼ばれる「非 RAID 対応」ドライブ構成を積極的に推進しています。しかし、JBOD という表現は、デルリファレンスアーキテクチャの利用者に混乱や誤解を招きかねません。Hadoop コミュニティの方針についてはデルも全面的に賛成ですが、JBOD にはいくつかの構成方法が存在することから、もう少し絞り込んだ説明が必要だと感じています。

一般に Hadoop データノードに最適なディスク構成は、RAID ではなく JBOD だと考えられています。その理由は、HDFS 自身にデータをレプリケーションする能力があり、RAID レベル 1~6 で提供される冗長性が不要になるからです。また、HDFS は、複数のドライブにわたる効率的なラウンドロビン方式の並列 I/O をサポートしているので、RAID 0 のストライピング方式による並列処理も不要となります。

ただし、ドライブコントローラの中には、RAID モードしかサポートしないものがあり、この場合、JBOD に単純なホストバスアダプタ (HBA) モードを使用することができません。そこで、この種のコントローラでは、複数の RAID 0 「アレイ」を構成し、HDFS がこれらをシングルドライブとして所有できるようにします。このように構成したコントローラなら、標準の HBA を JBOD モードで使用した時と同様、効果的に動作できますし、この RAID 0 は、JBOD に匹敵する性能を発揮します。RAID コントローラを搭載するこ

ここでは、JBODという表現が誤解を招きかねいとし、JBODが最適なディスク構成とし、RAID1-6は必要ないという。また、JBODモードをサポートしないコントローラもあるため、RAID0アレイを作り、シングルドライブとして使うようにしようと書いてある。 なので、コントローラーがサポートしている場合は、Virtual Diskが一つになり、サポートしてない場合は、RAID0のVirtual Diskがディスクの数分できあがるようになる。

ここで、Hadoopのスレーブの話

じゃ、HDFSは上記で説明したようなディスクをつなげていくJBODにすればいいのか。それとも、RAIDのなかから適切なレベルを選ぶのか。 まず、前提として、ディスクサイズに早々ずれた構成なんて組まないです。2TB + 3TB + 2TB + 2TBみたいな構成で組むようなことは面倒でしょう。 なので、各ディスクのサイズは同じだとする。なので、ディスクの総量がVirtual DiskのサイズになるというJBODはあまり恩恵受けられないわけですな。

あとは、コントローラがサポートしているかいないか。サポートしていて、かつ一つのVirtul Diskにできるようであれば、JBODで組んでいいかもしれない。サポートしていなければRAID0で複数ドライブ組めばいいのかもしれない。

また、Hadoopでは、dfs.data.dir(CDH3)またはdfs.datanode.data.dir(CDH4)というパラメータを適切に設定することで、Virtual Diskごとに処理させることができます。ディスクが独立して扱われるわけですな。

今のところの結論

まぁ、ズラズラと述べましたが、JBODの利点は僕には現時点でメリットが見られなかったのが現状です。ここでいうJBODというのは、単にディスクをつなげたJBODと呼ばれるものです。Virtual Diskを一つ組めるようなJBODを一部のコントローラーがサポートしているのは事実でしょうが、それに依存した設定はあまり好きではないですし、正直ベンチとかを取れる環境すらもってないので、この設定は選んでいません。

結局、ディスクのサイズをずらして構築することは基本しないのですし、RAID0のVirtual DiskをRAID0で複数設ければ、OSから見たディスクは分割されてますので、あとはHadoopの設定で、ディスクごとに処理させることができます。

コントローラーの性能に左右はされますが、シンプルですし、RAID0を複数個作ればいいんじゃないかなというのが今の結論です。 あくまで、今の結論ではありますが、ひとまず整理したかったので、書いてみました。

こうしたほうがよりいいとか何かあれば、ご指摘お願いします。