Dec 25, 2012

Node-level aggregation の概要


本投稿は Hadoop Advent Calendar 25日目(#hadoopAC12jp)です.現在投稿中のパッチである MAPREDUCE-4502 の内容の日本語資料がないのに気づいたので,その説明をします.

現在取り組み中のパッチの内容


Node-level aggregation は,MapTask 毎に部分集約(Combine処理)を行うための機能です.従来の Combine 処理よりも広い範囲で適用できるため,より高速な処理が可能となります.

設計


MRAppMaster が各ノードを調停して,MapTask にNode-level aggregation を開始するように指示します.Combine 処理は重いので,処理によっては Combine 処理によるデータの圧縮効果よりもオーバヘッドの方が大きくなってしまう場合があります.そこで,現在の設計では,しきい値を超えたら Node-level aggregation を開始するようにしています.また,耐故障性も担保できるように設計しています.


改造箇所


1. Mapper
2. Reducer
2. MRAppMaster(JobTracker)
3. Mapper-MRAppMaster間の Umbilical Protocol

だいたい全部ですね^^;

ユーザからどう見えるか


設計上はフラグで本機能をON/OFF切り替えできるようになっています.最終的には,

conf.enableLocalAggregation();

としたら本機能が有効になるようにする予定です.

ベンチマーク


現在とっている最中なので,乞うご期待^^;

終わりに


現在 Hadoop の標準機能に入れようと取り組んでいる最中の Node-level Aggregation について書きました.

本機能を実装する上で,Hadooper の皆様の声をぜひ聞いておきたいというところが本音です.もし何か要望がありましたら,気軽に @oza_x86 までお気軽にご連絡ください.よろしくお願いします.

Nov 20, 2012

fluent-logger-scala の maven repository を公開しました

fluent-logger-scala の maven repository を,sonatype に公開 しました.
2012/11/20 現在,apache maven の Central Repository から利用できるようになっています
Scala コンパイラのバージョンは,2.8.1,2.8.2,2.9.0,2.9.1,2.9.2 をサポートしています.

使い方

build.sbt に以下を追加することで,maven 同様に利用可能となります.
 
resolvers += "Apache Maven Central Repository" at "http://repo.maven.apache.org/maven2/"
libraryDependencies += "org.fluentd" % "fluent-logger-scala_''scala_version''" % "0.2.0"


''scala_version'' の部分は,2.8.1,2.8.2,2.9.0,2.9.1,2.9.2のいずれかで置き換えてください. 2.9.2 を利用する場合は,
 
resolvers +=  "Apache Maven Central Repository" at "http://repo.maven.apache.org/maven2/"

libraryDependencies += "org.fluentd" % "fluent-logger-scala_2.9.2" % "0.2.0"

とすれば動作します.

今後について

これからですが,Scala のオブジェクトをそのまま FluentLogger#log() に突っ込めるようにしていく予定です.なお,オブジェクト変換には msgpack-scala.jar を利用予定です.

謝辞

今回のリリースに辺り,TreasureData の @muga_nishizawa さんが fluentd プロジェクトのために sonatype 周りの手続きをしてくださいました.
また,@xuwei-k さんにはリリースに先立ち bug fix のための pull req を, @kmizu さんには便利な publish 方法を教えて頂きました.
みなさま,ありがとうございます!

Nov 12, 2012

Renewed fluent-logger-scala!

fluent-logger-scala を,fluent-logger-java  を使う形に更新し,公開した.特徴は以下の通り.
  1. Scala のmutable/immutable Map を利用できるように拡張.
  2. fluent-logger-java の提供している API を全てサポート.
テストがまだいい加減で, fluentd が 24224 ポートで立ち上がっていることを前提としている.そのうち Mock を利用したテストを追加する予定.ただ,コアの部分をほぼ fluent-logger-java に依存するように書いたので,安定して使えるようになっていると思う.

最後に,fluent-logger-scala の利用例をテストコードから抜粋:

    val logger = FluentLoggerFactory.getLogger("debug")
    val data1 = new HashMap[String, Object]();
    data1.put("k1", "v1");
    data1.put("k2", "v2");
    FluentLoggerFactory.flushAll
    FluentLoggerFactory.closeAll


API が Scala っぽくないとか,もっとこうした方が良いとかあれば,是非ご意見ください.

Jan 13, 2012

Auto Commit Memory に関するメモ

Fusion IO が,Auto Commit Memory という新技術のプレスリリースをした.プレスリリースによると,数十億 IOPS という驚異的な性能が出るということだが,PCI Express の Bus を介して毎回 commit しているとすると,明らかに物理性能を超えており,ホントにデータの永続化が保証されているか気になったのでメモしておく.根拠は全て書いているが,ところどころに私の予想が入っているため,正しさは保証できないので注意されたし.

まず,数十億 IOPS を達成するには,PCI Express の bus を介していたら間に合わない.しかし,特殊なハードウェアを使っているわけではなく,プレスリリースには HP ProLiant DL 370 + ioDrive2 Duos を使っていると記述されている.

(プレスリリースから引用 http://www.fusionio.com/press-releases/fusion-io-breaks-one-billion-iops-barrier) 
This demonstration used eight HP ProLiant DL370 servers, each equipped with eight ioDrive2 Duos, to break the one billion IOP barrier when transferring 64 byte data packets.

現状の x86 間に合うとすれば,「データがインメモリに書かれただけである」という場合くらいだろう.すると,1つの仮説が浮かび上がる.

Auto Commit Memory はOSのメモリ管理とフラッシュディスクと電源の合わせ技

まず,Auto Commit Memory の中で使われているであろう技術は,SSDAlloc という名前で既に論文化されている[1].使われているかもしれない,という根拠は,著者のページに Fusion IO と産学提携している 都度が書いてあるためだ(もちろん,違う技術が使われている可能性もありますが :P ).

SSDAlloc を用いることにより,OS から見てメモリとFlashディスクを透過的に扱うことができる.メモリとフラッシュディスクを透過的に扱うと,1つ大きな問題にぶち当たる.sync() ができないため,データの永続性を保証できない.そこで,ACM では電源のバッテリーを工夫することで,データの払い出しを保証していると予想される.これは,プレスリリースの以下の文言からも見て取れる.

(プレスリリースから引用 http://www.fusionio.com/press-releases/fusion-io-breaks-one-billion-iops-barrier)
Data integrity is assured by the ioMemory architecture’s ability to flush all in-flight data, even if the power is abruptly cut, without the need for super capacitors or batteries. 

スリリースの以下の文言からも見て取れる.つまり,技術の中身はOSのメモリ管理とフラッシュディスクと電源の合わせ技,というわけだ.

ソフトウェアに与える影響
Auto Commit Memory により,フラッシュディスクはメモリと透過的に扱うことができる.逆に,sync は ACM にとっては最適化の邪魔になる.すると,sync を発行する DB は軒並みレガシー化する.

逆に,Volt-DB や Oracle Coherence ・Gemfire といった インメモリDB・データグリッドは,ACM を用いることにより全て永続化が保証される.完全に DB の代替になることが可能になる.

まとめ
Auto Commit Memory は,メモリとFlush Driveを透過的に繋ぐ技術であると予想される.あくまでも「Auto Commit Memory」であり,sync してる訳ではないことに注意が必要.すると sync は最適化の邪魔となる.逆に,sync を発行しないインメモリDB・データグリッド技術が世間を圧巻するだろう.このデバイスは,費用対効果さえ高ければ計算機のモデルを変える可能性が非常に高い.今後の動向に注目していきたい.

[1] SSDAlloc: hybrid SSD/RAM memory management made easy. 著者の HP を見るとわかるが,Fusion IO と産学提携しているようだ


Dec 21, 2011

Cloud Foundry の Services について

この記事は Cloud Foundry JP Advent Calendar 21日目の記事として投稿です.えっ,投稿時間が過ぎているって?GMT ではまだ 23 時ですよ :)

概要
Cloud Foundry では,MySQL や RabbitMQ などの,デーモンとして起動するソフトウェアを "Service" として定義している.本稿では,Service の構成と概要について説明する,

何故 Service が必要なのか
アプリを立ち上げる毎に,PCのリソース確認して, MySQL を立ち上げる場所を決めて,テーブル作って,アクセス権限して,っていうルーチンワークを作成するのは面倒ですよね.その場所を自動化するのが Servicesである.

Service の実態について
1つのServiceは,2つのパーツから構成されている.
  1. Service Proxy
  2. Service Node
Service Proxy は,Cloud Controller からのリクエストを受け付けて,Service Node とのひも付けを行う.Service Node は,Service Proxy からのリクエストを受け付けて,実際にService インスタンスの割り当てを行う.全体像を把握するために,vmc client,CloudController,Service Proxy,Service Node,Message Bus (NATS)の関係を以下に示す.



vmc コマンドと挙動をのマッピングを示すと,
  1. vmc create-service : Service Proxy 経由で,自分用の Service を Service Node から割り当てる.
  2. vmc bind-service : Service と app をひもづける.
  3. vmc delete-service : Service を削除する.
といった具合になる.なお,create と bind の順序を別コマンドにすることで,複数アプリから 1つの Service (たとえば,DB)に対してアクセスする,といったことが可能になる.もし,RabbitMQ を複数アプリから共有すればアプリ間の連携が可能になるだろし,MySQL を複数アプリから共有すればユーザ情報を共有する,といったことが可能になるだろう.

まとめ

Services について,必要な理由とその仕組みについて大まかに説明した.Cloud Foundry ではデプロイだけでなく,アプリ間の連携もできるように設計されている.そのため,Cloud Foundry ユーザは煩わしいデプロイや管理の手間を最小化し,アプリを作成するのに集中できる環境を手に入れることができるだろう.

Dec 6, 2011

RabbitMQ の高可用構成について

本稿は CloudFoundry Advent Calendar の 6日目の記事として投稿させて頂いています.

本当はどの辺りをいじったら CloudFoundry から RabbitMQ を cluster setup できるのか調査…したかったのだが,そこまで終わらなかったので,VMware つながり && 昨日の y_wakai さんによる RabbitMQ の記事つながりで, RabbitMQ のクラスタセットアップについてまとめておく.

RabbitMQ は 2.6.x から複数台による Active-Active Standby 構成をとることができる.以前は DRBD による Active-Stanby 構成しかとれなかったので,2.6 以降で,より柔軟性が上がっている.

前準備
最新の RabbitMQ をインストールするには,http://www.rabbitmq.com/install-debian.html が参考になる.インストールが終了し,RabbitMQ がマシン h1, h2, h3 で動作していると仮定する.
まず,高可用構成をとるには,RabbitMQ のインスタンス識別子である cookie を同一にしておく必要がある.Debian の場合,cookie ファイルは /var/lib/rabbitmq/.erlang.cookie にある.もし編集していない場合は,

h1 $ echo "cookie" > /var/lib/rabbitmq/.erlang.cookie
h2 $ echo "cookie" > /var/lib/rabbitmq/.erlang.cookie
h3 $ echo "cookie" > /var/lib/rabbitmq/.erlang.cookie

などとして,クラスタに参加させたいノードの cookie を併せておく.

前知識
高可用構成のセットアップに入る前に,いくつかクラスタセットアップに必要なクラスタのノードの種類について説明する.クラスタのノードの種類には RAM ノードと Disk ノードの2種類がある.その名前の通り,RAM ノードのキューの状態はメモリの中にのみ保存され永続化は行われない.一方,Disk ノードのキューの状態は外部記憶に永続化される.ただし,複数台 Disk モードで動作させたとしても,複製はディスクに書くことを保証しないので注意.DRBD の Bモードで動作させている状態だと思えば良い.高可用構成のクラスタ内には,最低でも1台の Disk ノードが必要なので注意.

高可用構成のセットアップ
高可用構成のセットアップを行うには. rabbitmqctl コマンドを用いる.

h2 $ rabbitmqctl stop_app          # Erlang は起動させたまま RabbitMQ プロセスを停止
h2 $ rabbitmqctl reset             # RabbitMQ の保持している状態,および DB を初期化
h2 $ rabbitmqctl cluster rabbit@h1 # rabbitmq@h1 をディスクノード,rabbitmq@h2 をRAMノードにしてセットアップ
h2 $ rabbitmqctl start_app          # RabbitMQ プロセスを再開

これで,h1 をDiskノード, h2 を RAMノードにしてセットアップが完了した.
ポイントとしては, rabbitmqctl cluster で選択したノードが Disk ノードになることだ.
クラスタの状態を調べるには rabbitmq cluster_status を使う.
h1 $ rabbitmqctl cluster_status # クラスタ設定を調べる
[{nodes,[{disc,[rabbit@h1]},{ram,[rabbit@h2]}]},
 {running_nodes,[rabbit@h1,rabbit@h2]}]

h2 $ rabbitmqctl cluster_status
[{nodes,[{disc,[rabbit@h1]},{ram,[rabbit@h2]}]}, {running_nodes,[rabbit@h1,
rabbit@h2
]}]


disc,となっているのが Disk ノード,ram となっているのが RAM ノードである.
3台構成でも同様に行ける.

h3 $ rabbitmqctl stop_app          # Erlang は起動させたまま RabbitMQ プロセスを停止
h3 $ rabbitmqctl reset             # RabbitMQ の保持している状態,および DB を初期化
h3 $ rabbitmqctl cluster rabbit@h1 # rabbitmq@h1 をディスクノード,rabbitmq@h2 をRAMノードにしてセットアップ
h3 $ abbitmqctl start_app          # RabbitMQ プロセスを再開

h1 $ rabbitmqctl cluster_status 
h2 $ rabbitmqctl cluster_status
h3 $ rabbitmqctl cluster_status
h1 と h2 など,複数ノードを disc ノードにしたい場合は,
rabbitmqctl cluster rabbit@h1 rabbit@h2
とすれば良い.

ついでに,昨日の記事にもあった Bunny のライブラリについての補足もしておく.
Bunny のドキュメント中には,リモートの RabbitMQ の接続を行う方法が記述されていない.その方法を知るには,コードを読んで追いかける必要がある.以前調査を行ったので,以下に,リモートの RabbitMQ に接続して enqueue, deque するサンプルを示す.ポイントは,Bunny.new する箇所で :host でホストネームを渡してあげる部分.
#!/usr/bin/env ruby
require "bunny"

if ARGV.size < 3
  puts "Arguments Error! "
  exit(1)
end

hostname = ARGV.shift.to_s
num = ARGV.shift.to_i
msgsize = ARGV.shift.to_i

b = Bunny.new(:host => hostname, :persistent=>false, :immediate=>true)
val = "a" * msgsize
# start a communication session with the amqp server
b.start
b.tx_select
# declare a queue
q = b.queue("test1")
# declare default direct exchange which is bound to all queues
e = b.exchange("")


def push(b, e, num, val)
  num.times do |num|
    # publish a message to the exchange which then gets routed to the queue
    e.publish(val, :key => 'test1')
    b.tx_commit
  end
end

def pop(q)
  while msg = q.pop(:ack => true)[:payload]
    if msg == :queue_empty
      break
    else
      q.ack
    end
  end
end

push(b, e, num, val)
pop(q)
というわけで,次回こそは RabbitMQ と vcap のについて追いかけて説明したい.


Nov 12, 2011

OSS を運営する上でのルールについて

最近 Accord という ZooKeeper like な OSS をリリースした.その中で,「OSS として守るべきルール」を学んだのでまとめておく.以下の内容は他の人に使われることを目標とした Linux 的な開発に話が偏っているかもしれないので,注意されたし.

学んだことは,以下の3つ.
  1. 基本,議論は ML ですべき.
  2. コミッタであろうとなかろうと,変更はすべて ML に投げる.
  3. ターゲットとしている層の自然言語でドキュメントを記述する.
1, 2 について.

本当の OSS なら,開発がオープンであることをアピールする必要がある.ソースが github に上がっていても,開発プロセス,議論が不透明な場合はコミュニティから不満が出るだろう.Eucalyptus が良い例だ.

また,コミッタのあなたにとって都合が良い変更でも,他のデベロッパにとって都合の悪い変更もあるかもしれない.都合が悪い変更を見たデベロッパは思うだろう...「言ってくれれば良かったのに」,と.あなたがコミッタであっても,議論,変更を隠したままコミットしたら,それは職権乱用であり,信頼を失ってしまうだろう.

"気にくわないなら fork してコードを改変すれば良い.それが OSS" というスタンスの人も居るかもしれないが,fork されたコードのメンテナンスは fork した本人で行う必要がある.もし似たようなプロジェクトがあれば,皆はfork するよりも,よりオープンな競合プロジェクトに移る方を選ぶだろう.

もっとも,競合のプロジェクトが存在せず,独占状態であるのであれば話は別だ.でも,それならプロプライエタリソフトウェアとして商売した方が成功する可能性は高いように思う.

3. について.

当然だが,英語圏の人に使ってもらいたいのに ML やドキュメントが日本語のみだったら使ってもらえない.まずは,狙っている層で ML/ドキュメントを整備すべきだ.


まだまだ自分も配慮しきれていない点も多いので,気をつけたい.その他に気づいた点があったら,追記していく予定.