PIAXで作る P2Pネットワーク 伊藤 祐司 2015/10/17 Creators MeetUP #33
自己紹介伊藤 祐司
バックエンドの設計 開発
フレームワークの作成 バイナリ・テキスト変換 クローラー アルゴリズム 仮想マシン
下北沢OSSカフェでPROCESS WARPというシステムを作っています
http://www.processwarp.org/
GitHub llamerada-jp
facebook ito.yuuji
blog http://llamerad-jp.hatenablog.com/
分散アルゴリズム
繋げるだけでは利用が難しい
Socket, WebRTCも繋ぐだけ
探すアルゴリズムが必要
●●属性を持つPeerを探す
永続化、保存するアルゴリズムが必要
分散ハッシュテーブル(DHT), Key-Valueストア
PIAX
http://piax.org/
大阪大学とNICTで作ったP2Pフレームワーク@Java
Peer探索ができる
Key-Valueストアが使える
エージェント機構(今回は省略)
ver2.2.0まではMIT, var3.0からはAGPL(今回はver2.2.0)
サンプル
https://github.com/llamerada-jp/piax-sample
コマンドラインから対話形式でPIAXの機能を利用する実験用アプリケーション
スライドは該当機能のコードを切り貼りしているので注意!!
接続しよう既に接続しているPeerに接続要求を出す
処理能力に余裕があり、寿命が長いPeerの一覧を使ったり、サービスプロバイダが固定IPでseed役をやったり
// org.piax.trans.common.PeerLocator : // peerのIDを管理する抽象クラス // org.piax.trans.ts.tcp.TcpLocator : // ↑の具象クラス、TCP接続するときに使う PeerLocator local = new TcpLocator(<自分のIP&Port>); PeerLocator seed = new TcpLocator(<seedのIP&Port>);
// org.piax.ov.Peer : Peerそのもの // seedはcollectionで複数渡すことも可能 Peer peer = new Peer(local, seed); peer.online();
OverlayMgr mgr = peer.getOverlayMgr(); RPCWrapper rpc = mgr.getRPCWrapper(); PeerId peerId = new PeerId(<送信先>);
Object ret = rpc.remoteCall( peerId, Receiver.SERVICE_NAME, "recv", <送信メッセージ>);
単一PeerへのRPC
// 受信側のPeerId System.out.println(peer.getPeerId());
// 受信用クラス public class Receiver implements OldRPCService { static String SERVICE_NAME = <サービス名>;
@Override public String getServiceName() { return SERVICE_NAME; }
public Object recv(Object message) { // 受信してからの処理 return <応答メッセージ>; } }
// 受信用インスタンスを登録 OverlayMgr mgr = peer.getOverlayMgr(); RPCWrapper rpc = mgr.getRPCWrapper(); Receiver receiver = new Receiver(); rpc.register(receiver);
sender receiver
Key-Valueストアなどに入れて渡したり
マルチキャスト
PIAXのマルチキャストでは●●属性をもつPeerにメッセージを送る
属性の種類によってオーバーレイ(=検索アルゴリズム)を変える
へび / ハリネズミ
いぬ / ねこ / ウォンバット
ねこ / やどかり
ぞう / ハリネズミ
ねこ属性のPeerに送信
マルチキャスト
// 属性の型によって適切なオーバーレイ String ovClassName = mgr.getOverlayFromKeyType(<属性>); if (ovClassName == null) ovClassName = MSkipGraph.class.getName();
// マルチキャスト // Multi-key Skip Graphの場合、属性は範囲検索可能 ReturnSet<Object> rset = mgr.forwardQuery( ovClassName, new Range(<属性>, <属性>), <送信メッセージ>);
// マルチキャスト結果の取得 while (rset.hasNext()) { try { Object ret = rset.getNext( OvConfigValues. returnSetGetNextTimeout)); } catch (Exception e) { // エラー処理 } }
public class Callback implements OverlayCallback { @Override public Object execQuery(Object arg0, Object arg1) { // メッセージ受信時の処理 // arg0 : メッセージ受信のトリガとなった属性 // arg1 : 受信メッセージ return <応答メッセージ>; }
@Override public ReturnSet<Object> execQuery( Set<Comparable<?>> arg0, Object arg1) { // ↑と同様 return <応答メッセージ>; } // 他にも幾つかあるけど省略 }
// 受信用インスタンスを登録 Callback callback = new Callback(); mgr.registerCallback(callback);
// 属性を設定 String ovClassName = mgr.getOverlayFromKeyType(<属性>); if (ovClassName == null) ovClassName = MSkipGraph.class.getName(); mgr.addKey(ovClassName, <属性>);
sender receiver
アルゴリズムの特徴LL-Net
地理的探索(緯度経度での探索みたいなこと)が得意
LL-Netの概要
Multi-key Skip Graph
順序付け可能な属性の範囲検索が可能
PIAXでは随所にこのアルゴリズムが使われているようだ
単一ピアに複数キーを保持可能とする Skip Graph 拡張の提案
アルゴリズムの特徴PIAXには実装していないけど有名なもの
Chord
円状スキップリスト+ハッシュ、負荷分散が可能
Chord: A Scalable Peer-to-Peer Lookup Service for Internet Applications
ChordアルゴリズムによるDHT入門
Kademlia
Bit-torrentなどファイル共有系アプリケーションで利用されている場合が多い
Kademlia: A Peer-to-peer Information System Based on the XOR Metric
DHT Kademlia
Key-Valueストア
ちゃんと切断した場合、値は他のPeerに保存される
突然の切断や耐障害性は不明
DHT dht = mgr.getDHT(); dht.put(<Key>, <Value>);
DHT dht = mgr.getDHT(); Object value = dht.get(<Key>);
put get
いろいろ
PIAXはアルゴリズムの追加を意識した作りになっているようで、独自のOverlay、プロトコル追加も可能なようだ。
アルゴリズムの論文はあるけどAPIドキュメントが無いので、コードを結構読む必要あり。