インターネットオブジェクトは、FTP, HTTP, or gopherといったインターネットサービスのリクエスト対する、ファイルやドキュメントでの応答です。 クライアントは、キャッシングプロキシにインターネットオブジェクトをリクエストして、プロキシにすでにオブジェクトがある場合にはこれをクライアントに返し、ない場合にはURLで指定されたソースサーバか親・兄弟のキャッシュサーバからオブジェクトを入手し、これをクライアントへ返します。
ICPプロトコルはSquidキャッシュ間で使われるプロトコルです。ICPは2つのインターネットプロトコル標準で定義されています。1つはRFC 2186 でプロトコル自体について説明されており、もう1つはRFC 2187 で階層化されたWebキャッシュのためのICPアプリについて述べられています。
ICPは、兄弟キャッシュサーバへオブジェクトを置くために、主に キャッシュ階層内で使われます。 Squidキャッシュがドキュメントをリクエストされたとき、それがキャッシュになければ ICP クエリを兄弟キャッシュへ送ります。
そして兄弟キャッシュではドキュメントがあれば "HIT" を、無ければ "MISS" をICPへの応答として返します。
キャッシュは応答内容によって兄弟キャッシュをつかうか直接解決するかを決定します。
ICPは1つのTCPコネクションを使って複数オブジェクトの多重化転送をサポートします。 ICPは現在、UDPの上でも実装されています。 現在のバージョンのSquidはマルチキャストのでICPもサポートされています。
dnsserver は Squid が内蔵(実行時にforkされる)しているプロセスで、IPアドレスからドメイン名を検索するものです。 通常の
gethostbyname(3) 関数では、DNS検索検が完了するまで、呼び出したプロセスをブロックしてしまうので、この機能は必要です。 SquidにはブロックされないDNS検索が必要です。
そこで外部プロセスとしてSquidの主プロセスから起動されるようにしました。 dnsserver はDNS検索結果をキャッシュしません。 (要は、通常のDNS検索よりも高速に機能し、呼び出しプロセスをブロックしないDNS検索機能という事です)
ftpget はSquid1.0と1.1のバージョンに存在します。
クライアントがFTPサーバからファイルを検索するのに使ったFTPです。 FTPの処理が複雑になるため、Squidのコードとは別にして実装されました。
FTP の PUT は Squid2.0 以上から機能するようになりました。Squid1.1を使っているならバージョンアップしてください。
インターネットゲートウェイに尤も近いキャッシュが、もっとも遠いところのキャッシュへの親を務めるように論理的な親・子および兄弟という組み合わせで組織化されたものが階層キャッシュです。
子のキャッシュは、自身にクライアントのリクエストに応えるオブジェクトがない場合にソースサーバへ直接アクセスするのではなく、まずゲートウェイに近い親のキャッシュにオブジェクトの入手を依頼します。
親は依頼されたリクエストのオブジェクトを持っている場合にはそれを返し、ない場合にはソースサーバへアクセスしオブジェクトを入手・キャッシングしてこれを子のキャッシュへ返します。 これによって同一オブジェクトへのリクエストが抑制されて、インターネットへの帯域を有効に使うことが可能になります。
親子関係以外に、Squidは兄弟のキャッシュ関係もサポートします。 兄弟関係は並列なキャッシュ関係で、オブジェクトが兄弟間に無いかを確認して存在する場合にそれを融通します。 リクエストされたオブジェクトを持っていない場合にはそれをソースサーバへ取りにいかず"MISS"として返します。
ファイヤーウォールが存在する場合にはアルゴリズムは幾分、複雑です。
いくつかのキャッシングの問題、オートマッチマチックなロードバランサ、親キャッシュ、ルーティング、マルチキャスト、より良いURLのキャッシングについて取り組んでいます。
その他については、「TODO」リストをみてください。
将来の開発目標についてはSquid developers corner を見てください。
インターネットのトラフィックに興味があればNetwork Analysis activities を参照すると良いでしょう。
NLANRのルートキャッシュはNSFのスーパーコンピュータセンター(SCC)にあります。 そしてNSFは高速バックボーンサービス(vBNS)につながっています。
階層キャッシュのメリット(バンド幅の削減、アクセス時間の短縮)は価値があります。 NLANRキャッシュシステムを使うことでキャッシュにあるオブジェクトにヒットするかもしれません。 反面、上位のキャッシュにオブジェクトがない場合、さらに上位のキャッシュからオブジェクトを取ってくることになるかもしれません。結果として直接ソースサーバにアクセスするよりもアクセスが遅くなることがあります。
Firewalls FAQ ページを参照してください。
表示例:
LRU Expiration Age(LRU満期日)は、アクセスが無かったオブジェクトを削除して新しいオブジェクトの為にキャッシュを開ける日付の動的な値です。別な見方をすれば、現在のあなたのトラフィックにおいてキャッシュが空っぽの状態からフルの状態になるまでのおおよその日数です。
あなたのキャッシュが忙しければ、この値は下がっていくことでしょう。 理想的には、最低3日以上の値となるようにすべきでしょう。 もしこの値が3日をきるようであればキャッシュのサイズが十分な程大きくありません。 より多くのキャッシュスペースを増やすことでキャッシュのヒット率をあげる事ができる事でしょう。
Note: reference_age パラメータで LRU expiration age の上限を決めることができます。
AとBの2つの隣接キャッシュペアがあった時、仮にBのキャッシュのインターネットへの接続が不安定だったとします。
このようなとき、隣接のキャッシュにその事を伝えたいと考えられます。
Squidはトラフィックを追跡しており、リクエストが短期間の ERR_DNS_FAIL や ERR_CONNECT_FAIL や ERR_READ_ERROR
で失敗したなら、失敗から成功の比率を1.0以上にします。
このときSquidはICP_MISS ではなく ICP_MISS_NOFETCH を返します。 また、ICP_HIT が増えたならこれを戻します。
HUP シグナルをSquidに送ることで設定ファイルをリロードさせることができます。これを簡単に行う方法として、コマンドプロンプトから以下を実行します。
unlinkd は使用していないキャッシュファイルのリンクを外す(unlink)ための外部プロセスです。
もし私たちが注意深くなければ以下のような問題が起こるかもしれません。
問題は、Squid が新しいオブジェクトの為に割り当てたキャッシュファイルを unlinkd が削除しないことをどのように保証するかです。 私たちが取ったアプローチは、Squid の中で使っていない(しかし削除されていない)スワップファイル番号のスタックを持つようにしました。 スタックは128個のエントリのエリアをハードコードで持っています。 unlinkd に unlink のリクエストを与えるとき、使用しないファイル番号をスタックに記録します。 これによってunlink 中のファイル番号を常に把握して、unlinkd によってまだ削除されていないファイル番号を知ることができます。
unlink リクエストの処理ができるのは、unlinkd プロセスの storePutUnusedFileno 関数の中だけになっています。
Squidにとって不愉快なこととして、Gopher や FTP のディレクトリの HTMLページでの表示があります。
人々の奇妙な理由によって、表示の際にリスト表示にリンク先の種別(イメージ、テキストファイル、etc)を表した小さなアイコンを示す事を望みます。
1.0 と 1.1 までは、私たちは gopher-internal-image と同じようブラウザ内部アイコンを使いました。 しかし、これらは移植性に優れていませんでした。
これらをつかうと、内部アイコンを持っていないブラウザでは問題が発生します。
これらが使えるブラウザは多分、Netscape と Mosaic だけです。
Squid2からは、Squidの中にアイコンを持つようにしました。 これらのアイコンは必要に応じてロードされるようになっています。 現在では、Squidでは、Gopher
や FTPの為のアイコンを自身で持つようになっています。 他のオブジェクトで表示するアイコンについては、Uniform Resource Locators, を参照してください。
いいえ、Squid は HTTP でのリクエストだけを受けいれます。
クールな wget ならSquid経由でFTP URLでのダウンロードができる事でしょう。
Cachemgr で以下のように見えた値をスピードアップする方法はありますか?:
この値はファイルへのIOに要した時間ではありません。単にトータルのランニング時間をselect
callsで割った値です。
これはすべてのオープンされたファイルディスクリプタを調べるの.714秒要したことを意味します。
しかし、これはIOが行われいないウエイト時間も含んでいます。
私の持っている比較的ひまなキャッシュもよく似た値を返します。
また、私の持っているもっと忙しいにキャッシュはもっと低い値を表示させます。
このように、この値についてあまり気にする必要はありません。
リクエストにおけるクッキーヘッダーの存在は、HTTPの応答がキャッシュできるかどうかには影響しない。 同様に応答における Set-Cookie ヘッダーの存在もキャッシュできるかどうかに影響しません。
Set-Cookie の応答ヘッダーを除いて他のオブジェクトはRFC 2109 によってキャッシュされるとこが容認されています。
Squid-1.1ではHTTPヘッダーをフィルターすることができなかったため、Set-Cookie ヘッダーを含めどんな応答もキャッシュしませんでした。
オブジェクトの鮮度を調べるとき以下の評価を行います。
OBJ_DATE の時間は、ソースサーバからキャッシュにオブジェクトが登録された日です。
OBJ_LASTMOD はソースサーバにおけるオブジェクトの最終変更日です。
OBJ_AGE は最後の検索からどれだけ経過したかです。
OBJ_AGE = NOW - OBJ_DATE
LM_AGE はオブジェクトが検索されたときに、すでにどれくらい古いかです。
LM_AGE = OBJ_DATE - OBJ_LASTMOD
LM_FACTOR は OBJ_AGE と LM_AGE: の比率です
LM_FACTOR = OBJ_AGE / LM_AGE
CLIENT_MAX_AGE はクライアントが、HTTP/1.1のキャッシュコントロールヘッダーで受け取った(オプションの)最大のオブジェクト年齢(生存時間?)です。
EXPIRES は(オプション)のサーバヘッダーから入手する消滅時間です。
これらの値は refresh_pattern ルールと比較されます。リフレッシュのパラメータは、
quid-1.1 と Squid-1.NOVMのアルゴリズム
if (CLIENT_MAX_AGE) if (OBJ_AGE > CLIENT_MAX_AGE) return STALE if (OBJ_AGE <= CONF_MIN) return FRESH if (EXPIRES) { if (EXPIRES <= NOW) return STALE else return FRESH } if (OBJ_AGE > CONF_MAX) return STALE if (LM_FACTOR < CONF_PERCENT) return FRESH return STALE
Kolics Bertold はこの処理のすばらしいフローチャート・ダイアグラムを作成しました。
Squid-2のアルゴリズム
if (EXPIRES) { if (EXPIRES <= NOW) return STALE else return FRESH } if (CLIENT_MAX_AGE) if (OBJ_AGE > CLIENT_MAX_AGE) return STALE if (OBJ_AGE > CONF_MAX) return STALE if (OBJ_DATE > OBJ_LASTMOD) { if (LM_FACTOR < CONF_PERCENT) return FRESH else return STALE } if (OBJ_AGE <= CONF_MIN) return FRESH return STALE
キャッシュマネージャの I/O Page には様々なサーバサイドプロトコルでの deferred reads がリストされます。
サーバ側の読み込みにおいて、クライアントでの書き込みを追い越す事がたまにあります。 特に、サーバが高速のLANにつながっており、クライアントがモデムでつながってような場合、Squid-1.1では256K(リクエストあたり)まで読み込んで、読み込みを遅延(延期)するでしょう。
私はキャッシュのイーサネットアダプタにモニタをつけてトラフィックを監視しました。すると、行きと帰りのトラフィックの量が殆ど変わりません。 もっと違いが出ると思うのですが..
色々な理由が考えられので責任ある回答はできません。しかし、あなたが監視しているトラフィックは、Squidのキャッシュだけではなく他のすべてを見ている可能性があります。
オブジェクトをキャッシュするかどうかを決定するためにSquidは多くの考慮を行います。 現在のアルゴリズム(Squid-2での)では以下のような考慮をします。
しかしこれらの応答を隣接のキャッシュから受けた場合には、Squidはこれらのオブジェクトはキャッシュしません。 こうすることで、兄弟キャッシュ間でオブジェクトがバウンス(いったり来たりする状態)を避けます。
keep-alive ratio は Squid-2 のキャッシュマネージャの server_list に登場します。
これは、持続性のある接続をできない隣接のキャッシュをキャッシュを発見するためのメカニズムです。 私たちは随時、proxy-connection: keep-alive 要求ヘッダーを隣接キャッシュに送り、そのたびに隣接キャッシュからの proxy-connection: keep-alive 応答ヘッダーををカウントします。keep-alive ratio はこれらのカウントの比率です。
SquidではURL(least recently used : 利用頻度の少ない?)アルゴリズムによって古いオブジェクトをキャッシュから置き換えます。これは、もっとも長い時間アクセスされなかったオブジェクトを最初に取り去るという事を意味します。 オブジェクトにアクセスがあると時間はつねに更新されます。
オブジェクトの削除は必ずしも即時には行われません。 規則正しく予定されたスケジュールによって削除は行われます。 通常このイベントは毎秒実行されます。
Squidでは、キャッシュディスクの使用量を最低ラインと最高ラインの間を保つようにしています。 通常、最低ラインは90%で最高ラインは95%となっています。 キャッシュサイズの使用状況が最低ラインに近いときは、キャッシュの置き換えはあまり頻繁に行いません。 (僅かな削除だけです) 最高ラインに近い時にはキャッシュの削除は頻繁に行われます。
LRUの閾値は、現在のキャッシュサイズと最高・最低ラインによって動的に計算されます。 キャッシュが最低ラインに近い場合にはLRUに閾値は広くなります。
keys参照は、Squidのインデックス・キャッシュ・オブジェクトに使うデータベースキーを参照します。すべてのオブジェクトは(すでにディスクにあるか、ダウンロード中かに係わらず)、キャッシュキーを持っています。 Squid-1.0と1.1では基本的にキーはURLでした。 Squid-2.0からはMD5のチェックサムを使います。
Squidのキャッシュは、キャッシュキーとしてプライベートキーとパブリックキーという概念を使います。 オブジェクトは最初はプライベートを使って後に、公開キーを使うかもしれません。 プライベートオブジェクトは1つのクライアントに関係があり、パブリックオブジェクトは同時に複数のクライアントに送られるかもしれません。
つまりパブリックオブジェクトはどんなクライアントによっても置く事ができます。 プライベートキーはシングルクライアントにだけ置く事ができます。
私たちはPlankton. の為のデータを集めるためにこれを使います。
これはキャッシュソフトウェアの古い機能です。 キャッシュサーバは、ICPの”SECHO”メッセージをソースサーバのECHOポートに送ります。 これに反応して、他のICPへの返事より早くSECHOの返事が戻ってきたなら、この場合には隣接キャッシュよりソースサーバの方が近いということを意味します。 そのような場合には、Squidは直接ソースサーバにリクエストを送ります。
セキュリティを強化している多くの管理者は、UDPのポート7をフィルタをかけています。これは、CERT(Computer Emergency Response
Team)による( CA-96.01:
UDP Port Denial-of-Service Attack) での、UDPのECHOパケットを使ったDoS(サービス拒否攻撃)に関する勧告メモによります。 このため、多くのサーバで、UDP ECHOを使ったパケットが使えなくなりました。
Squid-2からは、source_ping 機能は無効になりました。 もしあなたのSquidがポート7へのパケットを見つけたなら相手のSquidはとても古いバージョンだと思われます。
これはSquidがIPアドレスを調べる為にDNSへ1つのIP検索要求をだしたところ、返答がDNSでないアドレスを持ったところから来たことを意味します。 デフォルトでSquidはDNSのアドレスをマッチングし、違うアドレスからの応答を無視します。
このような事が発生する理由としては:
警告のアドレスがあなたの知っているDNSサーバからのものであるなら、1.か2.の理由によります。 以下の設定によってあなたはこの警告を出さないようにして、応答を受け入れるようにする事ができます。
Squidは、オブジェクトを蓄える為のファイルを作りたいときに、cache_dir のどのディレクトリにオブジェクトを格納するかを storeDirSelectSwapDir() ファンクションを使って調べます。 もしあなたがN個のキャッシュディレクトリをもっているなら、このファンクションは空きスペースのあるディレクトリの75%(3N/4)のを明らかにして、さらにこの中で尤もスペースのあるものからディレクトリを使っていくようにします。
一旦、キャッシュするディレクトリが選ばれたなら、次のステップで利用できる swap ファイル番号を見つけます。 これは file_map_allocate() 関数によってファイルマップを調べることで得られます。 swap ファイル番号はシーケンシャルに割り当てられていきます。 例えば最後に割り当てられた番号が1000であったなら次は1001が割り当てられます。
Byte hit ratio はRequest hit ratioと異なるビットで計算されます。 Squidはサーバから読み込んだバイト数とクライアントから書き込んだバイト数によって計算を行います。 byte hit ratio は以下のように計算されます。
もしサーバのバイト数が大きいなら、これは negative な値になります。
サーババイト数がクライアントバイト数より大きくなる理由は以下のような内容かも知れません:
第一にあなたはプライベートキーと公開にキーの違いについて知る必要があります。
SquidはICPリクエストを送るとき、それはICPの reqnum フィールドを使ってここにプライベートキーのデータを保持します。つまりSquidのICPの返答を取得するとき、それは未決定のオブジェクトの為のプライベートキーを作るためにreqnum 値を使います。
あるICPのインプリメンテーションでは、常に reqnum フィールドにゼロをセットして返事をしてきます。 SquidはこれらのICPに返答を使ってプライベートキャッシュキーを作れないため、このような隣接キャッシュでプライベートキーを使うことができません。 このような
reqnumにゼロをセットして返答する隣接キャッシュを見つけたなら、Squidはプライベートキーの使用を無効にします。
プライベートを使えない場合、プライバシーに関する重要な意味が存在します。 2人のユーザが実際にはある唯一のユーザに宛てた応答を受け取るかも知れません。 このデータには機密の情報を含んでいるかもしれません。 もしSquidにプライベートキーを使って欲しいなら、あなたは
”ゼロのreqnum” を返す隣接キャッシュを無効にしなくてはなりません。
TCPにおける接続では"half-closed'' という状態が可能です。 これは shutdown(2) システムコールで生成されます。
Squidにおいては、クライアント側で読み込みをオープンにしたまま書き込み中において接続をクローズした場合に発生します。
これは大変トリッキーで、Squidにってはhalf-closedとfull-closedの違いが判断できません。
もしSquidがクライアントと接続して、read() で戻り値が0となり、クライアントが応答しない事を知ったならSquidはファイルディスクリプタにhalf-closedをマークします。 これはクライアントはリクエストと接続がアボートしてしていると信じられます。 しかし僅かながら、クライアントには shutdown() コールを使い静かに応答の読み込みを行っている可能性があります。
half-closedを無効にしたいならsquid.confの中で、
を設定してください。この時にはsquidはhalf-closedにマークを付けずに直ちにその接続を閉じる事でしょう。
参考: