CDNとは ― 仕組みとエッジサーバ・キャッシュ
CDNとは、
CDNとは、利用者の近くのサーバからコンテンツを届ける仕組み
CDNは、Webサイトの画像や動画などの複製を各地のサーバに置き、利用者に近いサーバから届ける仕組みです。正式名は Content Delivery Network で、日本語ではコンテンツ配信ネットワークと訳します。
利用者はいつもどおり www.example.com を開くだけで、近くのサーバから応答を受け取ります。近くのサーバへの振り分けには、DNSやAnycastを使います。サイトが速く開き、元のサーバに届く要求も減ります。
CDNの仕組み:なぜ近くから配ると速いのか
Webページを開くまでには、PCとサーバの間で何度も往復が起きます。TCPを使うHTTPSなら、TCPの準備に1往復、TLS 1.3の準備に1往復かかります。そのあとで、ようやくHTTPの要求と応答が1往復します。HTTP/3なら、準備の往復は1回で済みます。
往復の回数は、相手が遠くても近くても変わりません。変わるのは1往復にかかる時間で、距離が遠いほど長くなります。仮に1往復が100ミリ秒なら3往復で300ミリ秒ですが、10ミリ秒なら30ミリ秒で済みます。
そこでCDNは、利用者の近くにサーバを置き、そこで往復を終わらせます。近くのサーバが応答を持っていれば、遠くのサーバまで行く必要がありません。往復の流れは、3ウェイハンドシェイクとHTTPとHTTPSの記事で説明しています。
エッジサーバとオリジンサーバの役割
サイトの元の内容を持つサーバを、オリジンサーバと呼びます。このサイトの例では、203.0.113.50 の Webサーバがオリジンサーバです。ページを作るのも、ファイルの最新版を持つのも、オリジンサーバです。
利用者の近くに置くサーバは、エッジサーバと呼びます。エッジサーバは、オリジンサーバから受け取った応答を保存しておき、次の要求にはそれを返します。この保存の仕組みがキャッシュです。
図の1回目では、エッジサーバに応答がありません。エッジサーバはオリジンサーバへ取りに行き、受け取った応答を保存してから返します。2回目は保存した応答をすぐ返すので、オリジンサーバとの往復がなくなります。
キャッシュに応答があることをキャッシュヒット、無いことをキャッシュミスと言います。エッジサーバは、オリジンサーバの手前で代わりに応答するので、リバースプロキシの一種です。CDNは、プロキシの記事のリバースプロキシを各地に並べたものと考えられます。端末が作ったデータを近くで処理するエッジコンピューティングも同じエッジの語を使いますが、CDNのエッジサーバとは役割が違います。
キャッシュの有効期限:Cache-ControlとTTL
エッジサーバは、保存した応答をいつまでも使うわけではありません。いつまで使ってよいかは、オリジンサーバが応答のヘッダで指定します。このヘッダが Cache-Control で、HTTPのキャッシュの規格 RFC 9111 で定められています。
HTTP/1.1 200 OK Content-Type: image/png Cache-Control: max-age=300 Age: 120 # max-age=300 は、300秒の間は新鮮として使ってよいという指定です。 # Age は、オリジンサーバで応答ができてから、または確認されてからの経過秒数です。 # 300から120を引いて、残りは180秒です。
保存した応答を使ってよい秒数を、CDNではTTLと呼ぶことがよくあります。DNSのTTLも答えをキャッシュしてよい秒数ですが、こちらはHTTPの応答についての値です。同じ www.example.com でも、名前の答えの期限と、画像そのものの期限は別々に決まります。
RFC 9111 は、CDNのように大勢で使うキャッシュを共有キャッシュと呼びます。これに対し、利用者のブラウザの中のキャッシュはプライベートキャッシュです。Cache-Control には、どちらに効くかを分けた指定もあります。
| 指定 | 意味 |
|---|---|
| max-age=秒数 | 受け取ってから、この秒数の間は新鮮として使ってよい |
| s-maxage=秒数 | CDNなどの共有キャッシュだけに効く秒数。max-age より優先される |
| no-cache | 保存してよいが、使う前に毎回オリジンサーバへ確認する |
| no-store | どこにも保存しない |
| private | 共有キャッシュは保存しない。利用者のブラウザは保存してよい |
次の図で、オリジンサーバが付ける指定を切り替えられます。0秒・120秒・400秒に別々の利用者が同じ画像を要求したとき、エッジサーバの動きがどう変わるかを示します。応答には、このあと説明する ETag が付いているものとします。
- 0秒取りに行くオリジンへの通信:あり(応答を丸ごと受け取る)保存して返す。ここから300秒は新鮮
- 120秒キャッシュから返すオリジンへの通信:なし保存した応答を返す。Age: 120 が付く
- 400秒確かめてから返すオリジンへの通信:あり(変わったかだけ聞く)期限切れなので確認する。変わっていなければ304が返り、保存した応答を返す
- 0秒取りに行くオリジンへの通信:あり(応答を丸ごと受け取る)保存して返す
- 120秒確かめてから返すオリジンへの通信:あり(変わったかだけ聞く)304が返れば、保存した応答を返す
- 400秒確かめてから返すオリジンへの通信:あり(変わったかだけ聞く)304が返れば、保存した応答を返す
- 0秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
- 120秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
- 400秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
- 0秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
- 120秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
- 400秒毎回そのまま中継オリジンへの通信:あり(応答を丸ごと受け取る)保存せずに返す
期限が切れた応答は、すぐに捨てられるとは限りません。エッジサーバは、前に受け取った応答から変わったかどうかだけを、オリジンサーバに確認できます。この問い合わせを条件付き要求と呼びます。変わっていなければ、オリジンサーバは本文なしの 304 Not Modified を返します。
変わったかどうかの判断には、ETag などの印を使います。ETag は、オリジンサーバが応答の版ごとに付ける識別子です。エッジサーバは、保存した応答の ETag を If-None-Match ヘッダに入れて問い合わせます。この仕組みは RFC 9111 の4.3節と、HTTPの意味を定めた RFC 9110 に書かれています。
有効期限の指定がない応答でも、キャッシュが自分で期限を見積もって保存することがあります。共有キャッシュに保存させたくない応答には private を、どこにも保存させたくない応答には no-store をはっきり付けます。また、CDNのキャッシュだけに向けた CDN-Cache-Control ヘッダも RFC 9213 で定められています。
どのエッジサーバに届くか:DNSとAnycastによる振り分け
エッジサーバは各地にあります。利用者を近いエッジサーバへ送る方法には、DNSを使う方法とAnycastを使う方法があります。どちらを使うか、組み合わせるかはCDNによって違います。
DNSで振り分ける
CDNを使うときは、www.example.com のDNSの設定を書き換えます。たとえば、CNAMEで example.cdn.example.net のようなCDN側の名前を指すようにします。CNAMEは、ある名前を別の名前に付け替える別名のレコードです。
付け替え先の名前の答えは、CDN側の権威DNSサーバが返します。このサーバは、問い合わせてきたキャッシュDNSサーバの場所を手がかりに、近いエッジサーバのアドレスを答えます。上の図では、東京からの問い合わせには 192.0.2.10、大阪からには 192.0.2.20 を答えています。
ただし、権威DNSサーバに見えるのは、利用者のPCではなくキャッシュDNSサーバのアドレスです。PCと遠いキャッシュDNSサーバを使っていると、振り分けがずれることがあります。これを補うため、利用者側のアドレスの一部を問い合わせに添える拡張が RFC 7871 にあります。
DNSの答えには、DNSの記事で説明したTTLが付いています。TTLの間は、キャッシュDNSサーバやPCが同じ答えを使い続けます。DNSで行き先を決める考え方は、ロードバランサの記事のDNSラウンドロビンやGSLBと同じです。
Anycastで振り分ける
Anycastは、複数の拠点が同じIPアドレスを使い、パケットを経路の上で近い拠点に届ける方法です。図では、東京と大阪のエッジサーバがどちらも 192.0.2.80 を持っています。各拠点は、このアドレスへの経路を周りのルータに知らせます。
ルータは、届いた経路の中から近いものを選んでパケットを送ります。そのため、利用者は同じアドレスに送っているのに、地域ごとに違う拠点へ届きます。ここで言う近さは地図の上の距離ではなく、ルーティングの記事で説明した経路の選び方で決まります。
経路が途中で変わると、通信の途中のパケットが別の拠点に届くことがあります。TCPの接続はふつう始めた拠点でしか続けられないので、その接続は切れてしまいます。Anycastの運用上の注意は、RFC 4786 にまとめられています。
世界規模でAnycastを使うときは、拠点の経路をBGPで交換します。
キャッシュの削除:パージ
オリジンサーバのファイルを差し替えても、エッジサーバは期限が切れるまで古い応答を返します。期限を待たずに、エッジサーバのキャッシュを消すことをパージと呼びます。パージは、CDNの管理画面や、CDNが用意するAPIから指示します。
パージのやり方はHTTPの規格では決まっておらず、CDNごとに違います。URLを1つずつ消す方法のほか、まとめて消す方法を用意しているCDNもあります。消した直後の要求は、どのエッジサーバでもキャッシュミスになり、オリジンサーバに集まります。
パージを使わずに済ませる方法もあります。キャッシュは、要求のURLを鍵にして応答を探します。そこで style.css を style.v2.css のように名前ごと変えると、キャッシュは別のファイルとして新しく取りに行きます。
動的コンテンツはどう扱うか
画像やCSSのように、誰に返しても同じ内容のファイルを静的コンテンツと呼びます。一方、ログイン後のマイページのように、要求のたびに作る内容は動的コンテンツです。動的コンテンツは人によって中身が違うので、そのまま共有キャッシュに保存してはいけません。
もしマイページを保存すると、次に来た別の人に前の人のページが返ってしまいます。これを防ぐため、オリジンサーバは利用者ごとの応答に private か no-store を付けます。こうした応答では、エッジサーバは保存せずにオリジンサーバへの中継だけをします。
中継だけでも、CDNを通す効果は残ります。TCPとTLSの準備の往復は、近くのエッジサーバとの間で終わります。エッジサーバとオリジンサーバの間の接続を使い回せば、遠い区間の準備を毎回やり直さずに済みます。
また、POSTのようにサーバの中身を変える要求は、ふつうキャッシュから返しません。RFC 9111 は、こうした要求が成功したとき、キャッシュがそのURLの保存内容を無効にすることも定めています。
HTTPSとTLS終端:証明書はどこに置くか
HTTPSのサイトでCDNを使うと、ブラウザのTLSの接続はエッジサーバで終わります。エッジサーバが暗号を解かないと、どのURLの要求かが分からず、キャッシュを探せないからです。このように途中の機器で暗号を解くことを、TLS終端と呼びます。
ブラウザは、相手が本物の www.example.com かを証明書で確かめます。そのため、エッジサーバは www.example.com の証明書を示してTLSの接続を受けます。CDNが証明書の発行と更新を代わりに引き受ける場合もあります。
エッジサーバからオリジンサーバまでは、別の接続になります。この区間もインターネットを通るので、TLSで暗号化しておかないと中身が読まれます。利用者からはHTTPSに見えても、オリジンサーバとの区間が平文のままでは安全とは言えません。
1台のエッジサーバが、多くのサイトの要求を同じアドレスで受けることもあります。どのサイトの証明書を出すかは、ブラウザがTLSの最初に送るサイト名で決めます。この仕組みをSNIと呼び、RFC 6066 で定められています。
TLS終端は、ロードバランサの記事でも出てきます。TLSの手順と証明書の役割は、HTTPとHTTPSの記事で説明しています。証明書の発行元をたどる仕組みは、電子証明書とPKIの記事にあります。
CDNのメリットと注意点
CDNを使うと、次のことが起きます。上の3つがメリット、下の3つが注意点です。
| 内容 | |
|---|---|
| 速くなる | 利用者の近くで応答するので、往復の時間が短くなる |
| オリジンサーバが楽になる | キャッシュから返した分は、オリジンサーバまで届かない |
| アクセスの集中に強くなる | 要求が多くのエッジサーバに分かれて届く |
| 古い内容が残ることがある | 有効期限が切れるか、パージするまで前の内容が返る |
| 個人の情報を配ってしまう危険 | 利用者ごとに違うページを共有キャッシュに保存すると、別の人に返る |
| オリジンから利用者が見えにくい | キャッシュから返した要求は、オリジンサーバのログに残らない |
オリジンサーバへ要求を送るのは、利用者ではなくエッジサーバです。そのため、オリジンサーバに届く要求の送信元アドレスは、エッジサーバのものになります。元の利用者のアドレスは、プロキシの記事で説明した X-Forwarded-For などのヘッダで伝えます。
配信を世界中のエッジサーバに分けるので、通信が1か所に集中しにくくなります。この考え方は、DoS攻撃・DDoS攻撃の記事で説明する対策の1つでもあります。
練習問題(全5問)
正解:利用者の
エッジサーバは、
正解:180秒
max-age=300 は、
正解:Cache-Control: private
private を
正解:複数の
Anycastでは、
正解:エッジサーバの
エッジサーバは、
選んでから「採点する」を押すと、解説つきで答え合わせができます。
関連記事
おすすめの本 PR
ネットワークを初めて学ぶ人向けの入門書です。
![『[改訂新版]3分間ネットワーク基礎講座』の表紙](https://m.media-amazon.com/images/P/4774143731.09.MZZZZZZZ.jpg)
