P2P実用ソフトウェアへの道

首藤 一幸

注: このページの文章は UNIX magazine 2006年 10月号 (2006年 9月発売) に掲載された以下の記事の元原稿です。
首藤一幸, "P2P実用ソフトウェアへの道", UNIX magazine 2006年 10月号, pp.44-47, (株)アスキー, 2006年 9月 16日

ここまでで、アプリケーション層マルチキャスト(ALM)の理論と実例を紹介しました。 ここまでの話が現実環境を無視しているわけでも、 以降の話に理論がないわけでもありませんが、 実際にインターネット上で稼働する仕組みを作り上げるためには、 乗り越えねばならない問題がいろいろあります。 以降、ALMを中心として、P2Pソフトウェアを実用のレベルまで持っていくために 配慮が欠かせない点を、順に説明していきます。

ネットワーク帯域幅

ツリーベースのALM手法の場合、 子の数が多ければ多いほど子へのデータ転送トラフィックが増えます。 このため、子の数は上り方向の帯域幅が許す範囲に調整する必要があります。 メッシュベースの手法であっても、 上り帯域幅が狭いノードから多量にデータを配布しようとすると無理が生じるため、 帯域幅に応じて転送量を調整することが求められます。

こういった調整を行うためには、まずは帯域幅を把握する必要があります。 簡単な方法としては、 利用者におよその値を入力または選択してもらうという手段もあります。 しかし御想像通り、利用者が入力・選択する値はあまりあてにはなりません。

帯域幅を知る方法の基本は、計測です。 ただし、計測のために流すトラフィック自体が帯域幅を圧迫する点に注意が必要です。 ALMシステム自体の動作の妨げにもなり得ます。 かと言ってあまり計測時間を短くすると、 必要な精度が得られないことになりかねません。 また、どのノードを相手として計測を行うのかも重要です。 ALMシステム運用側で計測相手となる(少数の)ノードを用意する方法もありますし、 一般利用者のノード間で計測させる方法も考えられます。 それぞれに長所短所があります。

連続的なトラフィックを流すことなく、 通信の遅延から帯域幅を推定する方法もあります。 つまり、pathcharというソフトに実装されたような方法です。 また、測定を行わずに、他所の帯域幅やネットワークのトポロジを元にして 推測することも考えられます。

NATやファイアウォール

最近では多くのコンピュータが NATやファイアウォールを経由してインターネットとの接続を持っています。 その場合、インターネット側からそのコンピュータに向けた通信は制限され、 難しくなります。 ALMに限らずオーバレイの方式研究では すべてのノードが相互に通信できることを前提とすることも多く、 その場合、NAT越しの相互通信は別の何らかの方法で達成されることを 期待しているわけです。

ファイアウォールや、NATを行うルータをまたいだ相互通信を達成するためには、 それらの設定を変更してしまうことが確実です。 しかし、設定変更にはある程度の専門知識が必要ですし、 単純に設定変更が許されない場合も多いです。 利用者によるルータの設定変更は、 利便性向上、利用者獲得のためには避けたいところです。

そこで、利用者の手を介さずに自動的にNAT・ファイアウォール越しの 双方向通信を達成するための手法がいろいろと考えられてきています。 通信の中継であればTURNというプロトコルがよく知られていますし、 中継なしの直接通信のためにはTCPでのconnection reversal、UDP hole punching、 UPnPを用いたルータの設定変更、などの方法が提案され、実装されてきています。 シグナリングプロトコルSIPを前提とするなら、 ICEという追加仕様がNAT越えを想定したものとなっています。

しかしこれらのNAT越え(NAT traversal, firewall penetration)手法は どれも万能ではなく、いくつかの性質の間にトレードオフがあります。 例えば、中継を行えばどちらもNATルータの裏側にあるような2ノード間の 通信も可能となりますが、中継を行うコンピュータのネットワークに負担がかかり、 また、そこでの故障や離脱が他のノードの通信に影響するということになります。

UDP hole punchingでは、一旦準備が整えば、 通信を行う2ノード以外を煩わせる必要はありません。 STUNサーバの機能をノード側が果たすことで 集中的なサーバを完全に排除することも可能です。 しかし、NATの性質によってはUDP hole punchingでは越えることが 非常に困難です(i.e. symmetric NAT)。 また、NATに開けた穴(アドレス変換表のポート番号対応エントリ)が 塞がってしまうまでの時間が ルータや設定によってまちまち(数十秒〜数時間)なので、 穴を開け直す間隔を一概に決めにくい点も、UDP hole punchingの難しい点です。

UPnPは、それでNATに穴が開いてしまえば悩みは少ない方法なのですが、 きちんと穴を開けるまでの過程に難しさがあります。 そもそもUPnP非対応のルータや設定で無効化されているルータがあり、 ルータが受け付けるメッセージ形式も様々で、 多くのルータに対応することに大変な労力がかかります。 ひどい場合にはルータがハングアップしてしまうこともあるため、 そういったソフトウェアをリリースしてしまわないためには、 慎重な試験が欠かせません。 UPnP対応ソフトウェアをリリースしている企業は、どこも、 数十台以上のルータを調達して、そのすべてについて試験、 といった作業をこなしているのではないでしょうか。

ノードの頻繁な離脱や参加

ALMを含めたオーバレイでは、方式研究の時点ですでに、 ノードの頻繁な離脱や参加(churn)に対する強さ(resilience)が 重要な指標のひとつとなっています。 そもそも方式にchurnへの耐性がなければ、 それを実装したソフトウェアがresilientになるはずがありません。

オーバレイ、ALMの方式にchurn耐性があればそれで充分かというと、 そうではありません。 例えば、受信データのバッファ容量は慎重に調整する必要があります。 映像・音声のライブ配信では、もともと、途切れのないスムースな再生のためには データ受信から再生までの間に多少の間(バッファ)を設けることが必要です。 この間は利用者にとっては再生の遅れとして見えるので、 なるべく減らしたいところです。 こういったもともと必要な間に加えて、 ツリーベースのALMであれば、ノード離脱時のツリー再構成に要する時間を見込んで バッファ容量を調整する必要があります。 データ駆動のALMでは、1つのノードから安定・連続して データがやってくるわけではなく、 いつ必要なデータを入手できるという保証もありません。 そのため、バッファ容量の調整はより難しい問題となります。 データ駆動のとあるALMソフトウェアでは、 配信元での送出から各ノードでの再生まで、数十秒から1分程度の間が設けてあります。 バッファ容量の動的な調整も、有効かもしれません。

状況の動的な変化

P2Pシステムでは様々な状況がシステムの動作中に変わっていきます。 ノードの稼働状況、ネットワーク帯域幅に加えて、ときには IPアドレスすら変わります。 例えば、DHCP等で割り当てられたIPアドレスが変わったり、 ノートPCがサスペンド中に別のネットワークに移設されたり、 といった状況すら日常です。

これはつまり、ある時点で認識した状況がずっと続くと想定すべきではない ということを意味します。 具体的には、IPアドレスの認識し直しや、 ネットワーク帯域幅の測定・推定し直しが必要となることがある、 ということです。

映像や音声のストリーミングプロトコル

映像・音声の再生ソフトウェアは それだけで開発にかなりの労力を要しますし、 PC上ではすでに日用品となっているので、 ALM用にも既存のものを利用するのが得策です。 日用品とはすなわち、Mac OS XやWindows系OS上で動作する Flash Player、RealPlayer、QuickTime Player、Windows Media Player などを指します。

映像・音声ストリームをALMで配信する場合、 ALMシステムが再生ソフトウェアに対して データストリームを供給することになります。 ここで問題となるのが、ストリーミングのプロトコルです。 データストリームを供給するためには、ALMシステムは 各再生ソフトウェアが対応しているストリーミングプロトコルにのっとって、 再生ソフトウェアと対話することが必要です。 そのプロトコルは、QuickTimeが採用しているRTSPを除いて、 再生ソフトに独自のものであり、しかも仕様は公開されていません。

プロトコルによっては、解析結果が(合法的に)入手可能であったり、 サーバ側の実装が入手可能(例:FlashサーバRed5)であったりします。 いずれにせよ、ALMシステムは何とかして再生ソフトに データストリームを供給する必要があります。

ISPをまたぐトラフィック

インターネットは、ISP(インターネット接続提供業者)が 自身で構築したネットワークを他のネットワークと接続させることで 形作られています。 業者間の接続点では、何らかの契約に基づいて、一方からもう一方へ 接続料や通信料の支払いが発生しています。 その額はときに従量制で、トラフィックが多いほど支払い額が増えます。

データを配布するという視点で、 従来のサーバ・クライアント(やCDN)型を基準としてP2Pシステムの影響を考えると、 それがISPをまたぐトラフィックの量を変化させることは確実です。 特にCDN(コンテンツ配信ネットワーク)を前提とすると、 CDNはISP間のトラフィックを減らす効果があるので、 P2Pシステムを使った方がISP間トラフィックは多くなることが予想されます。 ISPの境界をまたぐトラフィックが増えると、 ある業者は収入が増え、別の業者は支出が増えます。 収入が増える業者は何も言わないでしょうが、 支出が増える業者はたまらないわけです。

ただし、P2PシステムがISP間トラフィックを増やすと決まったわけではありません。 特にCDNを経由しないデータについては、 ISP間を受信者の数だけまたいでいたデータが P2PシステムによってISP内で再配布されるようになり、 ISP間トラフィックが減るという効果も期待できます。 さらには、P2PシステムがISPの境界を認識できたなら、 CDNと同等以上のISP間トラフィック減効果を得られるかもしれません。

いずれにせよ、P2Pシステムの開発者には、 インターネット運用側のこういった力学を意識して システムを設計することが求められます。

大規模試験の方法

P2Pシステムには、下は数十から上は数百万という非常に大きな規模で、 破綻せずに動作することが求められます。 では、ノードが増えていった場合にもきちんと動作することは、 どうやって確認したらよいでしょうか。

サーバ・クライアント型のシステムであれば、ボトルネックとなるのは サーバ側の処理能力やネットワーク帯域幅であり、 その負荷もたいていはサーバへの問い合わせ数や通信量に比例するので、 試験はシンプルです。 可能なところまでサーバに対するの問い合わせ頻度や通信量を上げていき、 それ以上については負荷の量を外挿して推測します。 サーバ側を増強することで性能向上を図れますし、 運用の努力で安定性を高めることもできます。

P2Pシステムでは、利用者側のコンピュータがサーバの役割も果たします。 利用者側ノードの安定性や性能はP2Pシステム提供側の手の及ぶところではなく、 運用の努力で向上できるものではありません。 また、ソフトウェアが普及すればするほど、後での更新も難しくなっていきます。 そのため、あらかじめ、頻繁な離脱&参加(churn)、 低性能・狭帯域幅ノードの参加、 ノード数の増加を想定してよくよく考えて設計する必要があります。 同時に、厳しい状況でも破綻せずに動作することを、 可能な限り事前に確認しておくことが望ましいです。

確認の手段は、システムのシミュレーション、および、 大規模環境のエミュレーションです。 シミュレーションでは、P2Pシステムの挙動を模したソフトウェアを作り、 1〜数台程度のコンピュータで多数のノードを模します。 エミュレーションでは、P2Pシステム側ではなくネットワーク環境の側を模します。 一般に、シミュレーションの方が模すことのできるノード数は多くできますが、 エミュレーションでは実際のソフトウェアを動作させることができ、 現実により近い動作を期待できます。 どちらの方法でも、最大で数千程度のノードを模擬できているというのが 世の中の状況です。

試験は、ノード数を多くできればそれでよいというものではありません。 例えばノードの頻繁な離脱&参加があった場合にも破綻しないことの確認も 行っておきたいところです。 そのためには、シミュレータやエミュレータに、 各ノードにそういった動作をさせるための仕掛けが必要となります。 与えたパラメータに従って離脱&参加、その他の動作を繰り返すような 特殊なノードを作るという手もありますし、 シナリオとして記述(生成)した動作を各ノードに行わせるという手もあります。

そうは言っても、試験というものはあらかじめ想定し得た項目についてだけ 行うことができるものなので、 実際と同じ状況でできるだけ多くの人に試してもらうことは欠かせません。

まとめ

本稿では、理論・方式研究では無視されがちだけれど 現実のインターネットでの動作には配慮が欠かせない点を述べました。 この種の知識は、まだ、様々な論文や書籍、発言の中に散らばり、 ときに埋もれているというのが現状です。 本稿が、分散システムを設計、開発するエンジニアの一助となれば幸いです。
Copyright (C) 2006 首藤 一幸