Dart で Torrentクライアントを作ろう ( 2 ) おおまかな仕組み

DartでTorrentクライアントを作ろう!! 第2回です。

全15回で実際にTorrentクライアントを作成します。P2Pアプリをサラッと作れるような基礎体力をあなたに!!

## おおまかな仕組み
本章では、Torrentクライアントを利用してデータをダウンロードする時のおおまかな処理の流れを解説します。

最初に宣言した通り、本書はTorrentクライアントを実装する仮定を通して、P2Pの仕組みを解説する予定です。なので、直にでも、Torrentの実装に入ろうか考えたのですが、ワンクッションおき、本章を用意しました。

非常に残念ながら、まだコードは書きません。これから扱うP2Pデータ配信システムであるTorrentについて、認識を合わせたいと思います。攻略する対象について紹介します。

また、本文を通して、「Torrentがとてもシンプルな仕組みで動作している」ことを理解して頂いて、こいつは、倒せそうだと思って頂ければ幸いです。

### 配信している端末を探す
P2Pアプリがまず最初に行う事は、P2Pのネットワークに参加することです。
Torrentでは、データをダウンロードしたい端末が、お互いにP2Pネットワークを組みます。そのためには、データをダウンロードしたい端末同士が出会う仕組みが必要です。

これを実現するには、広大なネットワークからデータを配信している端末を探しだす必要があります。

##### 配信している端末を探すのは大変
インターネット上には数えられないほどの端末が存在しています。そして、どの端末がどのテーターを持っているか知るすべはありません。

例えば、インターネットは、IPv4アドレスで管理されています。IPv4の数だけインターネット上に端末が存在できます。IPv4は24bitの数字で表現されていますから、2の24乗=42億以上の端末を扱う事ができます。

さらに、現時点では、このアドレスは足りなくなりつつあり。IPv6というよりたくさん端末を扱う事ができる方法が利用されるようになりました。つまり、42億で収まらない端末が既にネットワーク上に存在しているのです。

この42億以上の端末から任意のデータを配信している端末を探すのは困難です。例えば、ひとつの端末へ確認するのに、10ミリ秒必要だとしましょう。すべての端末へ確認するとしたら、420億秒必要になります。これは、一年以上かかる事を意味します。

##### 直接、端末のアドレスを交換する
とはいっても、そんな広大なネットワークすべてを相手にする訳ではありません。最終的には、そんな広大なネットワークを相手にする事になるかもしれませんが、まずは、身近な所から解決していきましょう。

ひとつの解決方法は、データを配信している人が、配信している端末のアドレスを、データをダウンロードしたい端末の持ち主に、直接、教える事です。

メールを使っても良いし、口頭で話し手も良いし、どこかの掲示板にアドレスを書き込んむでも良いでしょう。

データを配信したい人は、掲示板に自分の配信したいデータと、自分の端末へアクセスするためのアドレスをおいておけば良いのです。とても原始的ですが、P2Pでデータの配信が可能です。

##### 端末一覧を管理するサーバーを用意する
しかし、掲示板やメールでいちいちユーザーどうしが情報交換するのは、面倒です。

Torrentでは、変わりに、データを配信したい端末を管理するサーバーを用意することにしました。これはTrackerと呼ばれています。
データを配信したい人は、掲示板に配信したいデータを書くのでなく、Trackerサーバーを立ち上げます。データをダウンロードしたい人は、Trackerサーバーにデータを配信している端末を教えてもらいます。

これで、煩わしさがなくなりました。もう、ユーザー同士が直接情報を交換する必要はありません。

###### 配信者が支払うコストを軽減
また、配信する側も、配信している端末を管理するだけならば、オンメモリーで数百、数千の端末を扱う事が可能です。
毎回、リクエストごとに、50端末分のIPアドレスとポート番号を返すだけの仕組みのサーバーとした場合、1リクエスト、「6byte×50=300byte」のデータ配信で済みます。
例えば、Wimaxの回線で1Mbpsですから、1秒間に100端末くらいアクセスがあって軽々対応できます。

端末の管理も、10000の端末を管理しても、たかだか、60kbyteのメモリーしか消費しません。

###### 改善の余地あり
しかし、これでも、Trackerサーバーを誰かが運用する必要があります。誰もがアクセスできる場所ですサーバーを立ち上げる必要があるのです。
サーバーをレンタルして、Trackeアプリをインストールして、起動して、維持して、とかなり大変です。

実際の運用では、データを配信する人がTrackeサーバーを持つ事はほとんどなく、インターネット上で公開されているTrackerサーバーを利用しすることなるでしょう。

そうなると、配信する端末を管理するサーバーへの同時接続数があがり、パフォーマンスに影響が出てきます。また、Trackerサーバーにアクセスができなくなると言ったトラブルも発生する事でしょう。

##### P2Pネットワーク上でアドレスを交換する(kademlia)
Torrentでは、Trackerを利用しない方法もサポートしています。データ配信をしている端末一覧の管理もP2Pネットワーク上で行ってしまえば良いです。そうすれば、Trackerが一時的に動作しなくなっても、データの配信を継続できます。


###### 六次の隔たりを利用する
では、どのようにして、P2Pネットワーク上で端末一覧を管理するのでしょうか？どのように、データを配信したい端末を探すのでしょうか？
その仕組みは簡単です。周知のTorrentクライアントへ、そのデータを配信していそうな端末を紹介してもらうことで実現します。これを繰り返す事で、データを配信している端末へたどりつくことができます。

例えば、自分は欲しいデータを配信している端末の事は知らなくても、友人は欲しいデータを配信している端末を知っているかも知れません。
友人は知らなくても、友人の友人は知っているかもしれません。現実世界では、「六次の隔たり」と言われており、6人もたどれば、世界中の誰とでもつながっているそうです。
Torrent ネットワークも同様の仕組みを利用することで、データを配信している端末を探し当てます。

###### 距離を定義する
「六次の隔たり」は6回聞くだけで欲しいデータを持っている端末を探し出すというものです。これを実現するには、「誰に聞くと良いのか？」を知らなくてはなりません。
聞く人を間違えると、6人で到達する事はないでしょう。聞くだけではだめなのです。

誰に聞けば良いのかを知る尺度が必要です。尺度としてTorrentでは距離を定義します。欲しいデータと距離が近い端末に聞ようにする事で、まったく関係の無い人に聞くリスクを軽減するのです。

既に世の中には、全てのデジタルデータに特別な値を割りふる仕組みがあります。SHA-1 ハッシュ関数です。動画ファイルもテキストデータもユーザー情報、Torrentクライアントアプリにも値を有り振ることができます。
値を割り振る事ができたならば、距離を求める事もできそうですね。

###### 自分に近い距離の事はより詳しい
距離が定義できましたが、聞いた人が自分よりもそのデータについて詳しくないとダメです。
そこで、「自分と距離が近い人の情報はたくさん知っている。遠い距離の人もすこしは知っている」といった状態を維持するようにします。

これで、聞く相手は自分よりもより多くの情報を知っている可能性があがりましたね。無事「六次の隔たり」で実現できそうです。


### ネットワークに加わりデータをダウンロードする
欲しいデータをもっている端末が見つかると、Torrent クライアントはデータのダウンロード処理を開始します。前章で説明した通り、Torrentクライアントは、データのダウンロードすると同時に、ダウンロードしたデータを他の端末へ配信します。
単純に配信するサーバーが増える訳ですから、配信できるデータ量は増えます。しかし、注意深くその仕組みを考えなと、非効率になる恐れもあります。例えば、「極度にデータの配信効率の悪い端末からデータをダウンロードし続ける。」、「一部の端末に負荷が集中してしまう。」といった問題が発生します。

Torrentは、これらの問題について考慮した設計がされています。多数の端末から、 効率的にデータを配信する仕組みを提供しています。

##### ブロック単位で、複数からダウンロード
Torrent クライアントはデーターを任意のブロックに分割して管理しています。データをダウンロードするのも、配信するのも、このブロック単位で配信します。
このブロック単位のデータを複数の端末から、戦略的にデータを配信してもらいます。これによって、効率的にデータを配信する事に成功しています。

###### 転送速度が安定する
負荷が集中した場合、データの配信する量は減ります。このような場合、負荷が高い状態の端末からデータを配信してもらうべきではあれません。データの配信を一度止めて、別の端末からデータを配信してもらう事を検討すべきです。
Torrentでは、常にデータを配信する速度は計測されており、その瞬間最も安定してデータを配信できると思われる端末へデータの配信します。

###### 上がり速度、下がり速度の差を平均かできる
我々が利用している回線はダウンロードする速度の方が、アップロードする速度よりも圧倒的に早い場合がおいです。2013年のWimaxはダウンロード速度が10Mbps、アップロード速度は2Mbpsとなっており。5倍くら差があります。
ひとつの端末からダウンロードするだけだと、相手がアップロードす速度分しかデータを配信してもらえません。つまり、Wimax上だと2Mbpsです。しかし、複数の端末からデータをダウンロードすれば、10Mbpsを一杯を利用する事ができます。
###### フリーライドを許さない
また、データを配信してくれた端末へ、優先的にデータを配信します。これによって、Torrentネットワークに貢献していない端末は、データのダウンロードに時間がかかるようになります。
これによって、より早くデータをダウンロードでするために、データの配信に協力するようになります。