50ノードによる接続実験

今日は二日酔いで、コーディングする気にならなかったので、意味ないかと思いながらもテキトウなテストした。そのテキトウなレポート。

@ 起源
Windows GUIの実装は、前のソケットインタフェースだったUIタスクを、UIタスクの基底クラス(UITask)とソケットインターフェースクラス(SocketUITask)に分けて、SocketUITaskは使わずに、UITaskを継承したWindowsGUITaskを作るという方法をとった。(単純にcore.exeとの通信部分を書くのが面倒だったので・・)
なので、前はPerlで書かれたウェブサーバが実質UIだったのがいらなくなったので、その分必要なリソースが減った。
よって、ローカルで50ノード程度なら余裕で動かせるようになったはずなので、試してみた。

@ ついでに前回の問題と言い訳と対応
前回問題になったのは、ノードリストの優先度変更がバグっていて同じノードばかりに接続がいっていたという話。
バグ自体は単なるコーディング上の問題だけど、これの真相はノードの知能に関係する結構重要な問題なので、軽く説明。
ポエニーノードは、ノード情報テーブルというもの持っていて、これに知っているノードを保持している。起動時に初期ノードをこのテーブルに読み込んで、次々に接続していく仕組み。一度接続を行ったノードは、接続認証時に回線速度やクラスタリングキーワードを交換しているので、その情報がアドレス情報に付加されて、ノード情報テーブル内の優先順位が変更されソートされる。上流リンクはこのテーブルの優先順位の高いものから接続していくというのが、まず基本的な仕組み。ノードは基本的に他ノードに指示はされず、得た情報から自分で考えてもっとも適したノードへ接続を行うようになっている。この「得た情報」というの今回の問題の発端。
ノード情報を渡す側ノードから見ると、ノード情報を渡すタイミングというのは、下流リンク接続してきたノードが自分には合わない(回線速度が速すぎる)と判断したときか、下流接続が限界数に達していたときで、その接続してきたノードが接続するのにふさわしいノード情報を自分のリストから選出して渡し、切断する。ノード情報を渡される側としては、初期ノード(回線情報などないノード情報)にとりあえず接続を試みたところ、ノード情報を渡されて、切断されたしまったという状況で、渡されたノード情報の優先度を変更してソートして、次からもっとも適しているノードに接続を行うようなる。この繰り返しで、だんだんと自分に適したノード情報のリストを作りながら、ネットワークを作っていく。
しかし、これをポエニーで実装して、Winnyネットワーク内でテストしていたところ、Winnyではあまりうまく機能していないと思えた。現象的には、回線速度15KB/Sのノードで、初期ノードへ次々に接続していったところ、次々にノード情報を渡されては、切断されるのだけど、この渡されるノード情報がふさわしくないノードが多くて、起動後数分はたらいまわしにされているというもの。(数分後にはそこそこいい感じになる)
特に1000KB/Sのノード群は、それ以上速い回線がいないため、1000KB/S同士でネットワークを作っている傾向があるようで、ほぼ1000KB/Sのノード情報ばかりを渡してくる。これは、ノード情報の限界が600個で、その中で自分に適した優先順位ソートし、増えすぎた分は優先順位の低い情報(自分に合わないノード)を消してくものだから、1000KB/Sノードが15KB/Sノードに適したノード情報を持っていない可能性はネットワークが大きくなるほど高くなる。
で、考えたのが自分用ノードリストと検索用のノードリストを2つ持つという他ノードのための親切設計。
だけど、この2つにきっちりわけたのが失敗で、どっちに入れるかという判断アルゴリズムが必要になるのだけど、それがノードの保持状態によって変化しているのと、状態によって、検索用から自分用に移したり、自分用から検索用に移したりしているものだから、自分用にあったり、検索用にあったり、どっちかにないから新しく作られたりしていて、新規に作ったノード情報は優先度128から始まるから、本当は優先順位が下がっているはずのにまたもとにもどったりと、いろいろなところで壮大にバグっていた。
で、もうごちゃごちゃして自分でもよく分からんことになっていたので、今のところの対応としてはテーブルは1つにして、単純に保持数を増やし、優先度の決定方法で、テーブルを仮想的に上下に分割して自分に適さないノードは下のほうに入れ、自分に適した上のノードが、それらより下に行くのはそうとうノード情報が少なくなったときなるように調節した。根本的には解決していないのだけど、とりあえず様子見対応。

@ 今回行った内容

今回は、ある意味でノートPCの耐久テスト。
実はまだWindows GUIの設定画面ができていないのと、設定ファイルの保存を行っていないので、前回のように回線速度の変更ができない。
なので、とりあえずはノード50がきちんと動くかどうかを見るだけにしようと思った。

行った手順は次のようなもの。

  • ノード1-50番を起動する(2秒おきに1つづつ起動する)
  • このとき各ノードは1-5番ノードの初期ノードを持って起動する
  • 50個チェック!!(接続できているか確かめる)
  • 2番ノードのアップフォルダにポエムを30個ほど入れる
  • 50個で検索してみるチェック!!(検索できるか確かめる)
  • テキトウに下流リンク接続の多いノードから消していく(ノード離脱テスト)

@@ 結果

@ ノード1-50番を起動する(2秒おきに起動する)

起動できた。まだ余裕ありそう。
各ノードは10MB程度のメモリ使用量なので、100ノードでもいけるかもしれないと思った。

@ 50個チェック!!(接続できているか確かめる)
全て接続できていた。
ただし、全て同じ設定なのに接続するノードには偏りが感じられた。
下流リンク接続が1つでもあるノードは、最大数(5個)繋がれているノードが多くて、ほんどは下流リンクが1つもない状態。
これは、他ノード情報を渡すときに単純にヒットしたノード情報の先頭から渡しているからだと思えた。
ノード情報の検索結果をシャッフルして渡すように修正しとこう。

@ 2番ノードのアップフォルダにポエムを30個ほど入れる
@ 50個で検索してみるチェック!!(検索できるか確かめる)
めんどうなので、テキトウに10個ほどサンプリングして検索した。
全てのポエムを検索できた。
検索結果のレスポンスから、検索する前すでに拡散クエリによってネットワーク上にキーが拡散していると思えた。
検索のテストをまともにやるなら、各ノードにかなり多めのキーを持たせたないとダメだと思った。

@ - テキトウに下流リンク接続の多いノードから消していく(ノード離脱テスト)
ノードが離脱するたびに、そこに繋がっていたノードは接続を作り直していて、全体で見るとうまく動いていた。
ただ、全体が7ノードになった時点で、1ノードだけ接続するノード情報なくなって、ギブアップしたノードがいた。
このノードは、その1つ前から検索リンクを1つしか作れていないので気になっていたのだけど、どうやら、下流リンク接続されているノードに対しては、上流リンク接続を行ってはならないという知識があるので(グラフにループができるのでこうしてる)、それに従ったところ、保持しているノード情報が全部下流リンク接続で、どれにも繋ぎにいけない状況で、繋ぎにいけないから別のノード情報を得ることもできないという、どうしようもない状況になっているもよう。
んーどうしよ。ノード情報が全部下流接続ノードだったら、気にせずに繋ぎにいって、繋がれたノード側で、上流リンク接続しているノードからの接続はノード情報を送ったあとに切断するとしとこうか。ん、考えとく。

その後は、最後の2ノードになるまできちんと再構築できていた。

おしまい。

次は、設定つけ、ダウンロード機能をつけた後に100ノードでテストする。
このときアップするファイルは多めにする。