HDFS, HBaseへのデータ投入時間について

1,201 views
Skip to first unread message

taro_x

unread,
Aug 17, 2011, 3:56:35 AM8/17/11
to Hadoopユーザー会
落合と申します。

HDFSへの書き込み時間と、
HBaseへの書き込み時間についての質問です。

当方の環境で試したところ、
HBaseへのデータ投入にかかる時間が、
HDFSへの書き込み時間に比べて遅いように見えるため、
どの程度の結果が妥当なのか、ご意見を伺いたいです。

■構成
 ZooKeeper用サーバ(ZooKeeper) 1台
 Masterサーバ(NameNode, JobTracker, HBaseMaster) 1台
 Slaveサーバ(DataNode, TaskTracker, HRegionServer) 6台

■HDFSへの書き込み
 100MB 16秒
 1GB 30秒
 10GB 190秒

■HBaseへのデータ投入
 100MB 29秒
 1GB 200秒
 10GB 3100秒

HBaseへのデータ投入時間が、
特にデータ量が多くなるにしたがって、
HDFSに比べて大幅に増えているように見えます。

このような傾向は妥当なのでしょうか?
それとも、設定のチューニングが足りないと考えられますでしょうか?

なお、
HBaseへは、
カラム数7, 1レコードのサイズ1KBのものを投入しています。

100MB:10万レコード
1GB :100万レコード
10GB :1千万レコード

です。

また、レプリケーション数はデフォルトの3としています。

以上、よろしくお願いいたします。

Tatsuya Kawano

unread,
Aug 17, 2011, 5:55:00 AM8/17/11
to hado...@googlegroups.com, Hadoopユーザー会
落合さん、
こんにちは。

HBaseのアーキテクチャですと、writeのスピードはデータ量に関わらず、一定になるはずです。しかし、HBaseでは、writeが一時停止するタイミングがあります。それは、リージョンの分割です。HBaseでは、あるリージョンのデータ量が多くなってくると、それを2つに分割するのですが、その間、該当リージョンへのwrite/readが一時停止します。一時停止するのは、数秒から数十秒程度です。

データ投入を行うプログラムは、シングルスレッドですか?もし、そうですと、リージョン分割時の一時停止がパフォーマンスに大きく影響するはずです。

あと、気になったのは、クラスターのサイズに比べて、書き込むデータ量が少なすぎることです。おそらく、100MBですと、リージョン分割は一度も起きないと思います。1GBですと、数回の分割。10GBですと、数十回の分割が起きると思います。ですから、リージョン分割時の一時停止が測定結果に大きく影響しているのだと思います。

HBaseのwebコンソールを開いて、ノード毎に割り当てられたリージョンの数を確認してください。たぶん、上で書いたような状態だと思います。リージョン分割時の一時停止が、テスト結果に影響しなくなるようにするには、おそらく、次の2点が必要です。

1. テスト前に、テーブルに十分なデータを書き込んでおいてください。1ノードあたり、20~30個くらいのリージョンが割り当てられた状態にするとよいと思います。おそらく、数百GB書くことになるでしょう。

2. テストでは、いまの100倍くらいのデータ(10GB、100GB、1TB)を、数十スレッドでパラレルに書き込んでください。

この2点を実行すれば、データ量に比例したスピードが得られると思います。

たつや

--
Tatsuya Kawano
Tokyo, Japan

JuhaniC

unread,
Aug 18, 2011, 1:35:51 AM8/18/11
to Hadoopユーザー会
落合さん
こんにちは

シングルスレッドで書き込んでるとリージョン分割意外にも、 もう一つ書き込みに影響する物は行名です。
連番の行名が全部同じリージョンサーバーに送られるため、もし全てのデータを連番の行名で入れてるなら、 複数のサーバーのパラレリズムは使われない
で、リージョンスプリットが一つのサーバーで起きてから他のサーバーで何も行われていない。 そのため、テストを再度行う場合、複数のスレッドだけでな
く、行名をランダムにして見るのはいかがでしょうか(ランダムじゃなくても、何かの方法でスプレッドがあるように)?

Juhani

On Aug 17, 6:55 pm, Tatsuya Kawano <tatsuya6...@gmail.com> wrote:
> 落合さん、
> こんにちは。
>

> HBaseのアーキテクチャですと、writeのスピードはデータ量に関わらず、一定になるはずです。しかし、HBaseでは、writeが一時停止するタイミ ングがあります。それは、リージョンの分割です。HBaseでは、あるリージョンのデータ量が多くなってくると、それを2つに分割するのですが、その間、該当リ ージョンへのwrite/readが一時停止します。一時停止するのは、数秒から数十秒程度です。


>
> データ投入を行うプログラムは、シングルスレッドですか?もし、そうですと、リージョン分割時の一時停止がパフォーマンスに大きく影響するはずです。
>

> あと、気になったのは、クラスターのサイズに比べて、書き込むデータ量が少なすぎることです。おそらく、100MBですと、リージョン分割は一度も起きないと思 います。1GBですと、数回の分割。10GBですと、数十回の分割が起きると思います。ですから、リージョン分割時の一時停止が測定結果に大きく影響しているの だと思います。
>
> HBaseのwebコンソールを開いて、ノード毎に割り当てられたリージョンの数を確認してください。たぶん、上で書いたような状態だと思います。リージョン分 割時の一時停止が、テスト結果に影響しなくなるようにするには、おそらく、次の2点が必要です。


>
> 1. テスト前に、テーブルに十分なデータを書き込んでおいてください。1ノードあたり、20~30個くらいのリージョンが割り当てられた状態にするとよいと思います 。おそらく、数百GB書くことになるでしょう。
>
> 2. テストでは、いまの100倍くらいのデータ(10GB、100GB、1TB)を、数十スレッドでパラレルに書き込んでください。
>
> この2点を実行すれば、データ量に比例したスピードが得られると思います。
>
> たつや
>
> --
> Tatsuya Kawano
> Tokyo, Japan
>

taro_x

unread,
Aug 18, 2011, 9:55:11 AM8/18/11
to Hadoopユーザー会
たつやさん、こんにちは。
ご回答いただきありがとうございます。

リージョン分割の数が重要とわかりました。
そうすると、
商用などでデータが0件からスタートする場合は、
先にダミーデータを入れる(MapReduce処理する場合はダミーデータを無視する)
べきでしょうか?

もしくは一度データを書き込んだ後、
deleteをするとリージョンは分かれたまま残るのでしょうか?


なお、
検証の際、データは空っぽの状態から入れていました。
また、シングルスレッドで投入していました。

データを事前に投入して、より多くのデータを書き込む試験も実施してみます。
各ノードのリージョン数は注意して見ていなかったので、
もう一度確認します。

落合 雄介

On 8月17日, 午後6:55, Tatsuya Kawano <tatsuya6...@gmail.com> wrote:
> 落合さん、
> こんにちは。
>
> HBaseのアーキテクチャですと、writeのスピードはデータ量に関わらず、一定になるはずです。しかし、HBaseでは、writeが一時停止するタイミングがあります。それは、リージョンの分割です。HBaseでは、あるリージョンのデータ量が多くなってくると、それを2つに分割するのですが、その間、該当リージョンへのwrite/readが一時停止します。一時停止するのは、数秒から数十秒程度です。
>
> データ投入を行うプログラムは、シングルスレッドですか?もし、そうですと、リージョン分割時の一時停止がパフォーマンスに大きく影響するはずです。
>
> あと、気になったのは、クラスターのサイズに比べて、書き込むデータ量が少なすぎることです。おそらく、100MBですと、リージョン分割は一度も起きないと思います。1GBですと、数回の分割。10GBですと、数十回の分割が起きると思います。ですから、リージョン分割時の一時停止が測定結果に大きく影響しているのだと思います。
>
> HBaseのwebコンソールを開いて、ノード毎に割り当てられたリージョンの数を確認してください。たぶん、上で書いたような状態だと思います。リージョン分割時の一時停止が、テスト結果に影響しなくなるようにするには、おそらく、次の2点が必要です。
>
> 1. テスト前に、テーブルに十分なデータを書き込んでおいてください。1ノードあたり、20~30個くらいのリージョンが割り当てられた状態にするとよいと思います。おそらく、数百GB書くことになるでしょう。
>
> 2. テストでは、いまの100倍くらいのデータ(10GB、100GB、1TB)を、数十スレッドでパラレルに書き込んでください。
>
> この2点を実行すれば、データ量に比例したスピードが得られると思います。
>
> たつや
>
> --
> Tatsuya Kawano
> Tokyo, Japan
>

taro_x

unread,
Aug 18, 2011, 10:08:15 AM8/18/11
to Hadoopユーザー会
Juhani さん、こんにちは。

行名については、
MapReduce処理への影響を確認しようと思い、
<時刻>_<itemID>
としたデータを入れた場合と、
<itemID>_<時刻>
としたデータを入れた場合で、
ある時刻とある時刻の間のデータに対する計算処理時間を比較してみようと考えていました。
(前者の処理が速い想定)

行名をランダムにすると、
書き込みは速くなったとしても、
後のMapReduce処理に影響は出ないでしょうか?
元から全データを走査するつもりなら、行名がランダムでも同じこととは思うのですが、
そうすると行キーの範囲指定によるデータ選択ができなくなるのではないかと思っています。

落合雄介

JuhaniC

unread,
Aug 19, 2011, 2:37:21 AM8/19/11
to Hadoopユーザー会
落合さん、こんにちは

MapReduce処理と行の分散された書き込みは確かに難しいです。

やろうと思っている物は一日のバッチ処理でしょうか?
ここらへんが個人的にHBaseを使っていて結構難しい所と感じています。ネーミングによって違う所への良くない影響があります。

似た問題で解決策として、そう言う時には一つの有効な方法は行名をday_id_timestampにするのが結構いいと思います。 そうすれば一日の
データがちょっと出来てから、スプリットされ、ばらばら書き込まれ、書き込み処理が有効にパラレリズムを使えます。 MRのスキャンを作る時にレンジを
日で分ける事が出来るとスムーズに一日分のデータの分析ができます。 走査の範囲が日レベルでなければ他の有効な行名を考える必要があるかもしれませ
ん。 エントリーを連番で入れる限りはHBaseの書き込みのパフォーマンスは前に説明した理由で多分期待しているような結果を出せないと思います。

Juhani Connolly

YiFeng Jiang

unread,
Aug 19, 2011, 10:16:45 AM8/19/11
to hado...@googlegroups.com
落合さん
こんにちは。

row keyの値は予測できるのならば、データを大量に入れる前、予測したrow keyの範囲をもとに、regionを事前に作るのはいいやり方です。うちの事例は、regionを事前に分割する場合は、しないときの10数倍の書き込み性能でした。
region分割のやりかたは色々あります、例えばorg.apache.hadoop.hbase.util.RegionSplitterを使うのがひとつ。shellから起動できますので利用も簡単。 -Dsplit.algorithm=your_classで分割のアルゴリズムを指定できます。詳細はSplitAlgorithm.javaのコメントを見てもらえば分かるかと思います。

他にも書き込み性能に大きく影響するいくつかのtuning pointがあります。
*サーバー負荷、読み込み性能とのバランスは要注意

・JVM tuning
 GCの発生頻度、一回のGC時間などを見てtuning。

・hbase.hregion.max.filesize
 regionの最大サーズ。初期値は256MBが、データ量に応じて512MBか1GB以上にすると、region分割の回数が減り、書き込みが早くなる。

・hbase.hstore.blockingStoreFiles
 書き込みをブロックするstorefileの数のしきい値。初期値は7。意味は、1storeに7以上のstorefileがあると、該当hregionの書き込みブロックが発生する。コンパクションの時間とのトレード・オフ。

・hbase.hregion.memstore.block.multiplier
 書き込みをブロックするメモリ使用量のしきい値。初期値は2。意味は、memstoreは 64MB(hbase.hregion.flush.size) X 2 = 128MB に達したら、書き込みをブロックする。メモリ余裕があれば、8位がいいかも。

・hbase.regionserver.global.memstore.upperLimit と hbase.regionserver.global.memstore.lowerLimit
 すべてのmemstoreのメモリ使用量を制限するオプション。block cacheと合わせてmax heapの70%位が妥当かと思う。

hmasterのlogに、「spliting」、「blocking」でgrepしたら、いっぱいヒットするなら、以上のオプションを調整するとよく効きます。

書き込みと読み込みの性能がトレード・オフすることが多いので、書き込みの性能目標を決め、少しずつチューニングするのはいいかと思います。

----
蒋 逸峰

2011年8月18日22:55 taro_x <taro...@gmail.com>:

taro_x

unread,
Aug 19, 2011, 1:34:42 PM8/19/11
to Hadoopユーザー会
Juhani さん、こんにちは。

検証する予定だったのは、一日のバッチ処理です。
ただ、実際の利用の想定はもっと幅広く、
1時間ごとや1週間ごとも考えていました。

期間を指定すれば、後はデータ量の問題だと思っていたのですが、
day_id_timestamp
という行キーを使う事などを踏まえると、実際の利用想定を決めないといけませんね。

まずは、行キーを day_id_timestamp 変えた検証も行ってみたいと思います。

ありがとうございました。


落合雄介

taro_x

unread,
Aug 19, 2011, 1:44:11 PM8/19/11
to Hadoopユーザー会
蒋 逸峰さん、こんにちは。

なるほど、チューニングの項目として注目していなかったものもあるので、
ぜひ試してみます。

また、
書き込み性能をまずは一通り計測しようと考えていましたが、

> 書き込みと読み込みの性能がトレード・オフすることが多いので、書き込みの性能目標を決め、少しずつチューニングするのはいいかと思います。

ということであれば、両方行ってバランスを見た方が良さそうですね。

ありがとうございました。

落合雄介

> 2011年8月18日22:55 taro_x <taro50...@gmail.com>:

Reply all
Reply to author
Forward
0 new messages