Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

rzmq

8,155 views

Published on

TokyoR #31 LT発表資料

rzmq

  1. 1. rzmq で並列分散コンピューティング(自称) ZeroMQエバンジェリスト 礒部正幸(@chiral)
  2. 2. 自己紹介• R歴 約2年、TokyoR参加歴 約1年半• 本業はソフト開発エンジニア• アドテクベンチャーを起業(まだひとりで奮闘中)– アドサーバ、DSP, 3PAS, DMPを作っています。最近のヒット作
  3. 3. ZeroMQ• 低レイテンシかつスケーラブルなトランスポートライブラリ– 「メッセージキュー付きのソケット」のようなもの• アクターモデル的な実装が可能になる• プロセス内(スレッド間)、プロセス間(同一ホスト、別ホスト)のいずれにも対応– 豊富な言語にバインディングが存在• 言語間のインテグレーションが容易• オープンソース(LGPL)• ピアの基本パターンを組み合わせることにより、豊富な分散処理形態に対応できる(スケーラブル)Pub SubSubSubPub-Sub Push-PullPush PullPullPullReq RepReq-Res
  4. 4. rzmqパッケージ• ZeroMQのRバインディング• 同一マシン上、別マシン間で、簡単にデータのやり取りが出来る• RとR、Rと別の言語、いずれでもデータをやり取りできるrzmqZeroMQrzmqZeroMQpyzmqZeroMQ
  5. 5. 【1】 同じマシン上でRとRをつなぐプロセス1(Rを起動) プロセス2(Rを起動)library(‘rzmq’)context = init.context()sock1 = init.socket(context, “ZMQ_PULL”)bind.socket(sock1, “ipc:///test”)receive.socket(sock1)library(‘rzmq’)context = init.context()sock1 = init.socket(context, “ZMQ_PUSH”)connect.socket(sock1, “ipc:///test”)send.socket(sock1,“hoge”)[1] "hoge"文字列の転送receive.socket(sock1)receive.socket(sock1)x <- 3.14y <- 1:5send.socket(socket, x)send.socket(socket, y)数値データの転送[1] 3.14[1] 1 2 3 4 5なんと関数の転送も可能f <- function(n) n*365send.send(socket, f)send.send(socket, f)receive.socket(sock1)f <- receive.socket(sock1)f(10)function(n) n*365[1] 3650(参考) 逆方向にデータを送りたいときは、もう一組のPUSH-PULLソケットを作成するちゃんと関数を使える
  6. 6. 【2】 別マシン間でRとRをつなぐホストAのプロセス(Rを起動) ホストBのプロセス(Rを起動)library(‘rzmq’)context = init.context()sock1 = init.socket(context, “ZMQ_PULL”)bind.socket(sock1, “tcp://*:1234”)receive.socket(sock1)library(‘rzmq’)context = init.context()sock1 = init.socket(context, “ZMQ_PUSH”)connect.socket(sock1, “tcp:///192.168.10.1:1234”)send.socket(sock1,“hoge”)[1] "hoge"(参考) 両マシン上のRに同じパッケージが入っていれば、パッケージ関数の呼び出しは可能ただし送れるのはピュアRのデータだけであり、パッケージの内部(C言語のメモリ)に持っているデータは送ることができない。以下、前頁と同様に数値データや関数を送受信できる違いはここだけ192.168.10.1 192.168.10.2ポート1234
  7. 7. 【3】 Rと他言語をつなぐlibrary(‘rzmq’)library(‘rjson’)context = init.context()sock1 = init.socket(context, “ZMQ_PULL”)sock2 = init.socket(context, “ZMQ_PUSH”)bind.socket(sock1, “ipc:///test1”)bind.socket(sock2, “ipc:///test2”)while(1) {json<-receive.string(sock1)dat <- fromJSON(json)res <- some_calculate(dat)send.string(sock2, toJSON(res))}RPythonimport zmqimport jsoncontext = zmq.Context()sock1 = context.socket(zmq.PUSH)sock1.connect(“ipc:///test1”)sock2 = context.socket(zmq.PULL)sock2.connect(“ipc:///test2”)sock1.send(json.dumps([1,2,[3]])res=json.loads(sock2.recv())JSONでやりとり(用途例)* WebサービスのバックエンドでRを動かして分析機能を実現* バッチ集計の一部でデータマイニングのところをRで実行* Rから、前処理の部分をPerlやPythonで行う* Rとscipyやscikit-learnを連携* zeromqのfluent-plugin を使って、Rからfluentdでログデータを転送(ちなみにJSONじゃなくてMsgPackで通信する方法があるか試したがうまくいかなかった)var zmq = require(‘zmq’), sock1 = zmq.socket(‘push’), sock2 = zmq.socket(‘pull’);sock1 = context.socket(zmq.PUSH);sock1.connect(“ipc:///test1”);sock2 = context.socket(zmq.PULL);sock2.connect(“ipc:///test2”);sock1.send(JSON.stringify([1,2,[3]]));sock2.on(‘message’, function(msg) {res = JSON.parse(msg);});Node.jsPerlRuby以下、なんでも
  8. 8. 【4】 AWSでスピードテストやってみたスタンドアロン(Rのプロセス1個)一様乱数でx*x+y*y < 1 な割合でπ/4を求める→ 4倍してπを得るよくあるやつ○ 実験の設定・乱数の数N = 100000000 (1億)・スタンドアロンのプログラムと、マスタスレーブ型の構成で速度を比較・8コア26ECUのAWS EC2 M3ダブルエクストララージインスタンスで検証・スレーブはN/10000(1万)単位のタスクを割り振るスレーブ(Rのプロセス)マスター(Rのプロセス)https://gist.github.com/chiral/5689735実験に使ったソースコード比較
  9. 9. 【4’】 AWSでスピードテストやってみた実行結果8CPUで6倍くらい速くなった!
  10. 10. 【5】 まとめZeroMQ(rzmq)を使えばマルチコアCPUをフルに活用できる!ZeroMQ(rzmq)を使えば複数台のPCでスケールアウトができる!さらに、ZeroMQ(rzmq)とJSONで他の言語とも連携ができる!前処理は“P系“言語で、データ分析はRで、役割分担!Webサービスのバックエンドで簡単にRを使える!数値や文字列だけでなく関数も送受信できる!
  11. 11. じゃあZeroMQ(rzmq)いつ使うの?おわりにヒント: 「今」

×