460 likes | 582 Views
揮発性資源上での並列分散計算を 支援するオブジェクト指向ライブラリ. 東京大学 弘中健 澤井省吾 田浦健次朗. 背景. Fire Wall. leave. 利用できる計算資源の拡大 Grid5000(France) DAS-3(Neth.) InTrigger(Japan) 出来るだけ多くの資源を使った計算 資源はヘテロな環境にある 複数のクラスタ・ NAT/Firewall 使える資源は一定ではない バッチ・キュー 使える時間の制約 計算途中の参加・脱退 ⇒ 資源は「揮発的」である. join. 需要. 依存性の少ない重い処理を並列化
E N D
揮発性資源上での並列分散計算を支援するオブジェクト指向ライブラリ揮発性資源上での並列分散計算を支援するオブジェクト指向ライブラリ 東京大学 弘中健 澤井省吾 田浦健次朗
背景 Fire Wall leave • 利用できる計算資源の拡大 • Grid5000(France) • DAS-3(Neth.) • InTrigger(Japan) • 出来るだけ多くの資源を使った計算 • 資源はヘテロな環境にある • 複数のクラスタ・NAT/Firewall • 使える資源は一定ではない • バッチ・キュー • 使える時間の制約 • 計算途中の参加・脱退 ⇒資源は「揮発的」である join
需要 • 依存性の少ない重い処理を並列化 • 非常に多い情報量の処理 • 多分野に渡った需要 • 自然言語処理 • 遺伝子情報解析 • 大量の入力ファイルを分割し、並列処理 • 逐次:1年間 → 並列:1日・数時間 • 簡単に広域分散計算資源を繋ぎ合せ、並列化したい
広域分散資源を繋ぎ合わせる 透過的な P2Pな通信 • 上層(user level)の見え方 • 任意の資源間で通信 • 透過的な方法 • 簡潔に記述 • サポートする下層の環境 • 揮発的資源 • 参加・脱退 • Firewall/NAT leave join Fire Wall
Requirements • 透過的通信 • 全対全接続を仮定しない • システムに容易にプロセスを追加できる • システムから途中に脱退を許す • 故障した場合、検知する術を与える
本研究の貢献 • dds:Pythonの分散オブジェクト指向ライブラリ • RMIでプロセス間の通信を透過的に • NAT/Firewallにも適用可能 • 動的な資源の投入が可能 • ポータブル・記述も簡潔 • ライブラリを用いた適応的並列処理フレームワーク • 揮発性資源に耐える • 動的に資源の投入・削除が可能
今後の発表の流れ • 関連研究 • dds : Pythonライブラリの紹介 • ddsを用いた並列化フレームワーク • フレームワークを用いた実験 • まとめ
関連研究 • ProActive [Huet et al. ‘04] • Javaに分散オブジェクトを追加 • 計算参加ノードは固定 • 複雑なXML設定ファイルを手書きする必要 • ネットワーク構成の詳細な知識が必要 • Ibis + Zorilla [Drost et al. ‘05] • ノード(Peer)間でoverlay networkを構築 • 資源の追加・削除にも対応している • P2Pシステム上でJava分散オブジェクトのRMIを実装 • 手軽に繋ぎ合せたい:スクリプト言語を採用 • 自然言語処理、ウェブアプリケーションで使う人にとってjavaはoverkill
関連研究 • Map-Reduce(Hadoop) [Dean et al. ‘04] • ユーザはmap, reduceの関数を定義するだけでクラスタで処理を自動並列化 • フレームワークの機能に制約される • 接続のport決めうち • クラスタ環境に限定 • master workerホスト名を列挙した設定ファイルの記述 • Martlet [Goodman ‘06] • 並列関数型言語 • 大量の分散データに対する処理を並列化 • 開発中でまだ実装は明らかでない
dds:分散オブジェクト指向ライブラリ foo.doJob() • Python言語のライブラリ • 分散オブジェクト間のRMIの実装 • プロセスを跨るオブジェクトへの アクセスを透過的に扱う • 遠隔のプロセスで容易に計算が可能 • 導入しやすい • 設定ファイルなし • importするだけ • 広域分散環境への対応の記述を 出来るだけスマートに 計算 RMI foo import dds # libraryをインポート dds.start() # ddsを起動 …# 一連の処理 dds.shutdown() #ddsを終了
Hello World proc1.py proc2.py import dds class Foo: def hello(self): return “Hello World!” foo = Foo() dds.start() #wrap 分散オブジェクト化 foo = dds.RemoteRef(foo) #任意文字列で外部公開 foo.register(“Bar”) while True: time.sleep(10) dds.shutdown() import dds dds.start() #接続する dds.mk_connection((ip,port)) #分散オブジェクト参照取得 foo = dds.RemoteRef(“Bar”) # RMI! print foo.hello() dds.shutdown() $ python proc2.py Hello World!
foo.doJob.promise() foo.doJob.promise() foo.doJob.promise() 計算 RMI RMI RMI 計算 計算 非同期RMI • 並列計算 • 一つのRMIにblock出来ない • 連続して発行できる必要 #非同期 RMI 実行 future1 =foo1.doJob.promise(args) future2 =foo2.doJob.promise(args) #他の計算… … #返り値を取得。 Wait value1 =future1.get_result() value2 =future2.get_result() Blockせずに 続けて発効 まとめて取得
RMI 広域分散環境への対応 • プロセス間でTCP Overlay Network • プロセスは選んだ幾つかのPeerと接続を試みる • FireWall内の相手の場合は失敗する • グラフの連結性は仮定する • overlay上でRMI msgをroutingする • 全対全の接続は必要無い • スケーラビリティ • NAT/firewall環境へ対応 FireWall
動的プロセスの参加 • 計算進行中にプロセスを加わる • 動的に資源を投入するには必須 • どれかのプロセスにTCP接続 • 問題 • どれかのプロセスのendpointを 知る必要がある • listen()している(IP, Port)ペア • endpointをユーザーが明記することは大変 • プロセスが存在するホストを特定する必要がある • そもそもportはbind()してみないと分からない • dynamic bind ? endpointは 何?
接続 Endpoint Server(1) • 接続可能なendpointを格納したディレクトリサーバ • 接続を受け付けるノードは登録 • 参加したいノードは問い合わせ、接続 • ユーザーが覚えるものは サーバのURLのみ HTTP Server EP取得 EP登録 conn_list = dds.get_endpoints(url) dds.register_endpoint(url)
‘/hoge’ ? ⇒proc 0,2,3 Endpoint Server(2) proc 0 ‘/hoge’ proc 3 ‘/hoge/piyo’ • endpointは階層的に管理 • 登録・取得時にpathを指定する • 取得時に、pathで指定した階層 以下のendpointのみ取得 • 繋ぎたいプロセスの集合が定義出来る proc 1 ‘/’ proc 2 ‘/hoge/piyo’ / proc 1 /hoge proc 0 /hoge/piyo proc 2, 3
広域環境対応にEndpoint Serverを使う proc 4 ‘/firewall/1’ proc 5 ‘/firewall/1’ • ネットワーク環境ごとにendpointの登録を仕分けすることが出来る • global IP → ‘/global’ • Firewall → ‘/firewall’ • 参加プロセスのendpoint 取得 • global IPプロセス • global IPのendpointのみ求める • Firewall背後プロセス • global IP, 自分のLAN内のendpoint ⇒接続が成功する確率を高くすることが出来る • 容易に広域環境でoverlay network構築可能 proc 0 ‘/global’ proc 3 ‘/firewall/0’ proc 1 ‘/global’ proc 2 ‘/firewall/0’
未実装な点 • プロセスの脱退 • アプリケーションレベルで実装 • overlay上のRMIのfault tolerance • 中継プロセスがRMI msgを持ったまま故障 • 故障の検知がまだ出来ない • 「揮発的」資源のために 今後必要
ddsのまとめ • 広域分散資源を繋ぎ合わせるライブラリ • (同期・非同期)RMIでプロセス間の通信を容易に • NAT/Firewallがある環境でも繋ぎ合わせが容易 • overlay network構築、routing • 容易にプロセスを追加することが可能 • Endpoint Server
今後の発表の流れ • 関連研究 • dds : Pythonライブラリの紹介 • ddsを用いた並列化フレームワーク • フレームワークを用いた実験 • まとめ
ddsを用いた並列化フレームワーク • ファイルを入力に取り、ファイルを出力とするような大量なジョブを並列に実行 • 資源は自由に参加・脱退可能 • 用途 • 大量の文章の自然言語解析 • 文章ファイルを配布し、並列に計算資源で処理 • 文章に字句解析、構文解析、意味解析と順番に処理 • Job Staging lexical syntax semantics
Job Staging • 現在のjobが次のjobを生成する • jobが木構造に展開する • workerがjob実行時に新しい子jobをmasterに 投入出来る必要がある JOB SPAWN TREE STAGE 1 STAGE 2 STAGE 3
Submit Output File Copy File Request フレームワークの処理の流れ • workerのlife-cycle • 計算に参加 • 計算の実行 • 1.ジョブを受け取る • 2.入力ファイルの取得 • 3.出力ファイルのコピーをマスターに格納 • 4.子ジョブの投入 • 計算から脱退 • heartbeatで検知 Job Queue
ファイル転送の詳細 • 基本的には、Workerが直接file sourceから取得 • 別のworker, master, HTTP Server • workerが他のworkerから取得出来ないことがある • sourceが既に脱退してしまった • sourceがNAT/firewall背後にいる • 出力ファイルはMaster にも置かれるので そこから入手 Firewall Non-Operational
SUBMIT JOB DO JOB STEAL ddsでの実装 • RMIでプロセス間の通信を透過的に記述 • 他のMWフレームワークとの違い • master→workerだけでなく、 worker→masterのRMI • workerもmasterに子ジョブを投入出来る • worker ⇔ workerでもRMIが可能 • random work stealingなどの協調動作 には必要
今後の発表の流れ • 関連研究 • dds : Pythonライブラリの紹介 • ddsを用いた並列化フレームワーク • フレームワークを用いた実験 • まとめ
実験(1) • HPSGパーサ:Enju [Miyao et al. ‘02] • Head-Driven Phrase Structure Grammar • 自然言語処理:英文の意味的・構文的解析 • 入力 • MEDLINE:医学系論文DBのアブストラクト • 背景 • 解析し、総合的な医学系意味的サーチエンジンを作りたい • 膨大な量のアブストラクト • 意味的解析は大きな計算量を要する
実験(2) • 実験の手法 • MEDLINEのアブストラクト10個を1 Jobで処理 • 12,000 jobs • 平均実行時間:168[sec] • 平均ファイルサイズ:61[KB] • 2 stageで処理 • 1. EnjuJob • Enjuパーサでアブストラクトを解析 • 2. StoreJob • 解析結果を自分のノードの持って来るジョブ • あくまで、ファイル転送のオーバーヘッドを強調するためのもの Do Nothing Parse! StoreJob EnjuJob
実験環境 • Master Object/初期ファイル source • hongoクラスタの1 node
スケーラビリティの実験 • 異なるコア数で実行し、speedupを測定 • 90 cores • hongo • 363 cores • suzuk, okubo, chiba, hongo • 513 cores(FW, private IP環境も含める) • suzuk, imade, kototoi, okubo, chiba, hongo
ノード間のファイル転送 Master Nodeに集中 11918 ⇒ 15100 ファイルの転送元
資源が揮発的な環境での実験 • 実行時にノードの追加・強制終了を繰り返す • 資源が揮発的 • 正常に全てのジョブが終了するか
実験結果について • ファイル転送の部分でオーバーヘッドがある • 他のワークフローフレームワークでは • レプリケーション • 裏で転送 • ddsを用いて作ることの利点として • クラスタを跨る資源をon demandで使える • 拡張性が効く • お手軽感
まとめ • 分散オブジェクト指向ライブラリ • スクリプト言語で広域分散資源を容易に繋ぎあわせることが出来る • NAT/firewall • 動的資源の追加 • ライブラリを用いたフレームワークの実装 • ファイルを入出力するJobを並列に実行 • 揮発性資源(参加・脱退)に対応
今後の課題 • ライブラリレベルでノードの故障・脱退に対応 • FTなRMI • invokerにexceptionを発行 • 事前なobjectの避難 • object migrationを用いる • 安全な脱退プロトコルを用いる[関谷ら’06] Leaving…
プロセスの脱退はアプリケーションレベルで実装プロセスの脱退はアプリケーションレベルで実装 • heartbeatをRMIで実装 • overlay上のRMIのfault tolerance • 中継プロセスがRMI msgを持ったまま故障 • 故障の検知がまだ出来ない • 現状では「揮発的」資源 には対応しきれない
ユーザーの手間 • 提供されたJobクラスを継承したクラスを実装 myjob.py import job class MyJob(job.Job): def __init__(self, filepath, host): job.Job.__init__(self) self.add_input(‘tcp’, filepath, host) def run(self): fp = open(self.input_files[0]) #一連の処理 (RMIなどもOK) self.add_output(‘tcp’, outfilepath, self.localhost) self.master.add_jobs(new_jobs) 継承 入力ファイルの指定 TCPソケット接続で入手 実行される頃にはfileはnodeに転送されている 出力ファイルの指定 子Jobも投入出来る
従来の手法 • ファイル転送・ジョブの簡単なスケジューリング • 「フレームワーク」に縛られない部分 • あくまでも、ddsのライブラリ上のフレームワーク • ジョブ間でRMIなどの協調も可能
今後の課題 • 資源の脱退を踏まえて • FTなRMI • ddsライブラリレベルでcleanな脱退のサポート
全体として • RMIの恩恵 • master – worker間のinteractionはbatch queueの単純なstagingで出来るか!? • worker-worker間でのファイルのやり取り • javaなどであるjob submission frameworkとの差分は?workflowとの差分は? • それだけに限られてしまう。
フレームワークの概要 • ddsを用いたアプリケーション • 膨大な量の情報の処理を並列化するフレームワーク • 複数のJobに分割して記述 • 一つのJobが子供Jobを作り出してもOK • 用途 • 大量の文章の自然言語解析 • 文章ファイルを配布し、並列に計算資源で処理 • 文章に字句解析、構文解析、意味解析と順番に処理 lexical syntax semantics
フレームワークの下層部 • フレームワークがカバーする部分 • 必要なファイルは自動的に転送 • 途中の資源の参加・脱退も考慮する • ユーザーは目的の処理だけを記述する • アプリケーションに集中出来る
Submit Output File File Request 処理の流れ • Master-Worker Model • Workerは自由に参加脱退出来る • Masterはheartbeatでmonitoring • 脱退したworker jobは再実行 • ファイル転送 • 処理に必要なファイルはworkerがsourceにアクセスする • TCP, wget (HTTP) • 出力ファイルはMasterに集める • Job submission • workerから子供jobの投入も出来る Job Queue