えっ？CDNのキャッシュHIT率を高めるためにTTLを伸ばしているの？？マジで？

# 結論
CDNでのキャッシュヒット率が低いときにTTL（キャッシュ生存期間）を伸ばすのは無意味なのでやめるべき。
これはCDNだけでなく、通常のキャッシュコントロールでも同じです。

# CDNとは
この章は知ってる人は読み飛ばしてください。

大量のコンテンツ配信を実施する際に、コンテンツ配信元のサーバの能力以上にユーザーへのサービスを提供するための仕組み。
Akamaiとか、CloudFrontとか、いろんな業者がサービスとして実施しています。

配信元のサーバを増強するよりよほど安上がりなことが多いので、大量コンテンツ配信が必要なサービスでは導入は必須と考えていいです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38018/9da4d453-569a-50fb-e679-a26d6836321e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38018/ae60d93f-acc1-e49b-5200-cbb18fdbed12.png)


CDNは大量のユーザーアクセスの中から、同一のコンテンツを返答して良いと設定されたコンテンツに関して、一定期間（TTL）の間コンテンツをキャッシュして、そのキャッシュから同じものを返答します。
コンテンツ配信元サーバ（オリジンサーバ）には、リクエスト自体が届かないことになります。

## CDNの具体的効果

例えば、台風の避難先を公開する自治体のページを考えます。
このページ、真冬のアクセスはほぼゼロですし、台風が近づいていないときのアクセス数もほぼゼロのサイトとなります。
ただし、超大型台風が近づいているとき、避難勧告が発令された瞬間に、1秒間で1000人のユーザーがこのページを閲覧する。などということは普通に有りえます。
通常はブラウザは画像なども含めて、複数のコンテンツを同時に取得しますので、サーバに届くリクエスト数としてはその10倍の1万req/secとなったと仮定しましょう。

CDNがないときはオリジンサーバは1万req/secの応答能力がないといけません。もし、その能力がないと、市民は避難勧告が出ても避難先を調べる事ができません。
ここで、CDNが1分間のTTLでのコンテンツのキャッシュをしていたパターンを想定します。
CDNは通常複数のエッジサーバから構成されるため、それぞれのエッジサーバがオリジンサーバに対してバラバラにリクエストを出す可能性はあるのですが、そちらを一旦無視すると、オリジンサーバに届くリクエストは1分間に10リクエストしか届かないことになりますので、オリジンサーバはかなり貧弱な構成であっても正常に避難先情報を返答し続けることができます。

この場合のキャッシュのヒット率は、本来60万リクエストを受け付けていた筈が10リクエストで済んでいるのでほぼ100%になります。
これを例えば1時間のTTLに変更したところでもともと十分にヒット率が高いためにほぼ無意味となります。
TTLが長いと、オリジナルのコンテンツの更新の反映に時間がかかる（CDN側でクリアすることもできますが、、、。）ため、弊害が大きくなります。

つまり、**キャッシュヒット率が十分に高いときにさらにTTLを伸ばすのは無意味**です。

| TTL | 1時間のリクエスト数の期待値 |
|:-:|:-:|
| なし | 10,000 * 60 * 60 = 3,600万回 |
| 1分間 | 10 * 60 = 600 回 |
| 10分間 | 10 * 6 = 60 回 |
| 1時間 | 10 回 |

CDN設定無し → 1分間のTTLではリクエスト回数が激減するが、10分や1時時間に延長してもほとんど意味がない。

# CDNとキャッシュヒット率
こちらのコンテンツに非常にわかりやすく解説されています。
[CDN選定時にキャッシュヒット率が重要な理由](https://pr.cdnetworks.co.jp/why-the-cache-hit-rate-is-important-when-selecting-a-cdn-vender/)

要約すると、キャッシュヒット率、95%と99%の違い、僅かな違いに見えるけど、オリジンサーバに対するリクエスト数を見るのは、ミスヒット率を見ないといけないので、ミスヒット率のほうは5%と、1%になるので、オリジンサーバへのリクエスト数は5倍違うよ。という話。
キャッシュヒット率、超重要。

# キャッシュヒット率が低くてオリジンサーバにリクエストが多く届いてしまう場合
問題は、CDNを導入してもキャッシュヒット率が低くて、オリジンサーバにまだ数多くのリクエストが届いてしまい、オリジンサーバの負荷が過大になるケースです。このときによく取られる手段が、

 **TTLを長くすることでキャッシュのヒット率を上げる。**

という手段です。

これは正しいでしょうか？というエントリ。

例えば、1分間のTTLを設定していたコンテンツのキャッシュヒット率が10%程度と低かった場合に、TTLを10倍の10分間に伸ばしたらキャッシュヒット率は100%になるのか。直感的にはキャッシュヒット率をサイコロやガチャの確率のように考えてしまい、100%にはなるはずないが、それに近い程度まで上がるのではないかと考えてしまいますがどうなのでしょうか。
結論的には、キャッシュヒット率は、
1-(1-0.1)^10 = 1-0.3486784401 ≒ 65%
までは上がります。

TTLを60分にまで伸ばした場合には、これはほぼ100%となります。

### キャッシュヒット率の変化
ここまでで得られた、キャッシュヒット率の変化は以下の通りです。

| TTL | キャッシュヒット率 |
|:-:|:-:|
| 1分間 | 10% |
| 10分間 | 約65% |
| 60分間 | 約100% |

これを受けて早急な判断をしてはいけません。

次に、60分間にオリジンサーバに対して発行される実際のリクエスト数で比較します。
ここで、キャッシュのヒット率が10%であったということは何を示すのかと言うと、1分間の間に該当コンテンツをリクエストされる確率はたったの10%だったということです。つまり、1分間あたりのリクエスト数の期待値は0.1回、60分間で6回しかないということです。

### 1時間におけるリクエスト数の変化

| TTL | 1時間のリクエスト数の期待値 |
|:-:|:-:|
| 1分間 | 0.1 * 60 = 6 回 |
| 10分間 | 0.35 * 10 = 3.5 回 |
| 60分間 | 1回 |

なんと、リクエスト回数の期待値は全くと行っていいほど変化していません。
もともとキャッシュヒット率が低いということは、そのコンテンツへのアクセス数が非常に少ないということですので、TTLを伸ばしてもほとんど意味がないということがわかります。

つまり、よく選択される、キャッシュのヒット率が低い場合に、
 **TTLを長くすることでキャッシュのヒット率を上げる。**
ということはコンテンツの更新に追従できなくなるというユーザーへのデメリットばかりが大きくて、メリットは殆どない選択であると言わざるを得ないです。

# では、どうすればいいの？
こちらのブログに良くまとまっていましたので、是非ご一読を

[CDN で高いHIT率にするチューニングとは](https://blog.redbox.ne.jp/cdn-high-hitrate-cookie-query.html)

この中でも、TTLを伸ばせとは書いてないですね。