技術としてみたキャッシュと中継

ダウンロード機能を作る前のまとめ的メモとしてまじめに駄文を書いたので載っけとく。
内容的には、Winnyのファイル配信に関する基本的な考え・概要の個人的解釈。
基本的に短所は書いてないので過剰解釈に注意。

この文章は、全体的にあまり調べずに想像で書いているので、間違い指摘などいくらでも受け付けます。

@ 法と倫理とテクノロジー

Winnyの特徴である「キャッシュ」と「中継」という仕組みは、倫理的だったり法的だったりする問題を抱えているため、この話題が扱われるときは、常にそういう方向に話が進んでいく傾向があります。そこで、本当は無視したらいけないのでしょうけど、この文章ではそれを無視して技術的観点からキャッシュと中継について書くこととします。

Winnyは分散型のファイル配信システム

まず、Winnyは、P2Pファイル共有ソフトなんて微妙な言い方をよくされていますが、分散型のファイル配信システムではないかいう意見から。どう違うのかと訊かれると、ぱっとはニュアンスかなとしかいえませんが、あくまで配るため技術を中心に考えられたのではないかと思えました。

@ ミラーサーバーの考え

ウェブでは、配信サーバのミラーを作ることで、負荷分散を図ることがあります。これには、ドメイン名に複数個のIPアドレスを割り当てておいて、DNSでの問合せが発生するたびにあらかじめ用意された複数のミラーサーバのIPアドレスの中からランダムに選択したものを返すことで、1つのサーバにアクセスが集中しないようにする方法や、sourceforgeのダウンロードセンターのように、いくつか利用するサーバの選択肢を用意しておいて、ユーザに選択してもらう方法など様々なものがありますが、技術の根本は、1つで配るよりも2つで配るほうが並列化と負荷分散ができて効率がいいという単純な考えに基づくものです。
Winnyのファイル配信も、このミラーサーバーの考えに基づくもので、Winnyではミラーサーバを動的に増やすことで、ネットワーク内に分散配信システムを構築できるようになっています。

@ キャッシュを使ったミラーの生成

Winnyでは、ミラーの生成にキャッシュという技術を用います。キャッシュという考え自体は、かなり古い時代からあるもので、DNSキャッシュやウェブのプロキシサーバ等、UNIXのネットワークで遊んでいた人間にはおなじみの考え方でしょう。
これは、物理的に遠いサーバにある資源を直接利用する代わりに、近所にある同じコンテンツを保持するサーバを利用したほうが、トラフィックを抑えられ、かつ特定のサーバへのアクセス集中を避けられるという考え方で、一般的にはコンテンツのアクセスに『中継サーバ』を挟む方法をとります。まず、前提として全てのクライアントは中継サーバへ問合せを行うようにします。中継サーバでは、要求されたコンテンツを保持していなければ、それを遠くのサーバに問合せ、問合せ結果を要求元へ返します。このとき、『問合せ結果』は『キャッシュ』され、次回から同じコンテツへの問合せ結果として、このキャッシュを返すようになるため、遠くのサーバへアクセスする必要がなくなります。
上記は、一般的なキャッシュの話ですが、Winnyのキャッシュは少し性格が違っていて、厳密には、このキャッシュ技術のある一点に着目した作りになっています。
例を出します。


(中継サーバ)

↑ Aをくれ

(クライアント)

クライアントがコンテンツAを要求します。このとき、中継サーバはまだAをもっていないと定義すると、この時点では『中継サーバはAのミラーサーバではない』ということになります。

(遠きサーバ)
↑ Aをくれ
(中継サーバ)

↑ Aをくれ

(クライアント)

中継サーバは、Aを持っていないので遠くのサーバへ問い合わせます。

(遠きサーバ)
↓ Aあげるよ
(中継サーバ) {!!Aをキャッシュ!!}

↓ Aあげるよ

(クライアント)

問合せは、遠くのサーバに届き、応答はクライアントまで転送されました。このとき、中継サーバはAをキャッシュしました。この時点で『中継サーバはAのミラーサーバになった』ことに気づいたでしょうか。Winnyのキャッシュは、まさにこの特徴を持っています。
WinnyはピュアP2Pシステムなので、サーバとクライアントが1つになったサーバントと呼ばれるノードでネットワークが構成されています。そのため、あるノードがAをダウンロードした場合、そのノードはそのままAを配信するミラーとなります。この単純な仕組みは、需要と供給を含めて考えた場合の負荷分散手法としても、きれいに問題を解決できていることがわかります。というのもの『需要の多い人気のファイル』というのは、自然と持っている人も多くなるわけですから、人気のファイルほどより多くのミラーが作られ、アクセスの分散化によって効率的に配信を行えるようになります。逆に人気のないファイルは、もっている人が少ないためミラーも少なくなります。しかし、需要の少ないファイルなので、それが十分な量のミラーであるといえるでしょう。

上記の話は、『だんだんと人気の出た場合』を考えるとそこそこ効率的であると思えますが、突然人気が出た場合はどうでしょうか。突然人気の出た場合は、需要ばかりが多く、供給できるミラーがまだ少ない可能性があるため、できるだけ速く沢山のミラーを生成する必要があります。この問題をカバーするのが次で紹介する『中継』という仕組みです。
@ 中継によりミラーの生成を加速させる

Winnyの『中継』と呼ばれる仕組みは、Winnyの大きな特徴でもある匿名性の中心的役割もはたしているため、匿名性の話題ばかりされる傾向がありますが、この仕組みはミラーの生成を爆発的に加速させる効果があります。
例を出します。まず、中継がない場合を考えます。


(A)

Aを持っているノードは世の中に1つしかいません。


(A) ←←( )


( )

ここで、Aは突然人気が出たので、2つのノードからダウンロードされます。

(A) (A)

(A)


ダウンロードの完了したノードがAのミラーになったため、Aは3つのミラーを持つことになりました。次から3つで配信を行うことができます。

次に、中継を行った場合を考えます。


(A) ←←( ) ←← ( )


( )


( )

Aを保持するノードからみると、中継がない場合と同様に2つのノードからダウンロードされます。つまり配る側は相手が中継かどうかという意識はありません。

(A) (A) (A)

(A)

(A)


ダウンロードの完了したノードとその中継を行ったノードがAのミラーになったため、Aは5つのミラーを持つことになりました。中継を行うノードは、中継したAを同時にキャッシュするため、このような結果となります。次から5つで配信を行うことができます。
例から分かるように、1つの中継を挟むことで、ファイル保有ノードがアップロードする負荷はそのままでミラーを2倍の量増やすことができます。つまり、2倍の『速度』でミラーを増やすことができるため、需要が供給よりも多いインフレ状態のときに活発的に中継を発生させることで、ネットワーク全体で協調して、できるだけ速く需要と供給のバランスを保てるように努めることができます。
ただし、実装上では、人気度や回線速度(ノードの性能)から、中継を発生させる確率を求めて、その確率によって中継が発生する仕組みになっているようです。

@ おまけ - Shareの拡散アップロード -

おまけとして、Winnyと似た仲間のShareというソフトがもつ『拡散アップロード』という機能についてのメモ。

まず最初にWinnyの問題。
Winnyでは、中継を除いては、完全なファイルを持っているノードだけがミラーとして働きます。これはつまり、大きなファイルほど沢山のミラーを作るのにより多くの時間を要するということになります。

Shareは、拡散アップロードという能動的にファイルを配る仕組みを持っています。これは、ファイルを1MB単位に分割して周辺ノードへ強制的にアップロードするという機能で、これにより早い段階から沢山の断片化されたミラーを作ることができます。これはファイル配信の初期段階で行うと優れた機能になると思いまが、配る側の判断で拡散するため、人気に関係なく拡散すると無駄に帯域を使う可能性があります。
また、今現在のバージョンでは、この拡散アップロード機能と断片化されたミラーのいくつかがなくなってしまうP2P特有の問題が原因で、いつまでたっても完全ファイルが完成しなくなる『歯抜け』と呼ばれる病的な問題を抱えています。