ISUCON本の内容をまとめてみた 高速化に必要なその他技術編

# はじめに
この記事は[isucon本](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%8C%E6%95%99%E3%81%88%E3%82%8BWeb%E3%83%91%E3%83%95%E3%82%A9%E3%83%BC%E3%83%9E%E3%83%B3%E3%82%B9%E3%83%81%E3%83%A5%E3%83%BC%E3%83%8B%E3%83%B3%E3%82%B0-%E3%80%9CISUCON%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6%E9%AB%98%E9%80%9F%E5%8C%96%E3%81%AE%E5%AE%9F%E8%B7%B5-%E8%97%A4%E5%8E%9F-%E4%BF%8A%E4%B8%80%E9%83%8E-ebook/dp/B0B1Z9ZMY6/ref=sr_1_1?crid=3VFKVU9V3LQ4D&dib=eyJ2IjoiMSJ9.Fqg1BYtrQnEUkAI-Nz64Vlht-4b2gmnfCNzmBcYOOLrGjHj071QN20LucGBJIEps.ihawrCdi4UxmgZ_Xbpwz0kJimoBykcQ7nS9WIqRl40U&dib_tag=se&keywords=isucon&qid=1732981401&sprefix=isucon%2Caps%2C178&sr=8-1)の8章の内容をまとめたものになります。

この書籍では高速化について主に以下の観点でまとめられています

- 負荷試験
- モニタリング
- DB
- キャッシュ
- リバースプロキシ
- OS

この記事ではそれ以外に該当する高速化のテクニックについて紹介します。一部上記の内容に該当するものもありますが、書籍に準拠してこの記事に記載しています。

# 外部コマンド実行ではなく、ライブラリを利用する
外部コマンドを実行すると、アプリケーションとは別のプロセスを起動する必要があります。別のプロセスを起動するコストがかかり、起動したプロセスがメモリを消費するため、メモリの消費量も増えてしまうのでなるべくライブラリなどの代替手段を用意しましょう。

# 開発用の設定で冗長なログを出力しない
冗長なログも動作を遅くする原因になってしまいます。例えば一回のリクエストのログ記述に5KB必要なログと10KB必要なログがあるとします。通常はそこまで気にならないかもしれません。しかし開発用環境で負荷試験をする際にはリクエストが増大すればするほど必要なメモリ量の差も倍増し、正確なモニタリングが難しくなるので気をつけましょう。

# CDN上にHTTPレスポンスをキャッシュする
**CDN(Content Delivery Network)** とはCDN業者によって張り巡らされた高速なネットワークのことです。
世界中に一斉にコンテンツを配信したい際に、ユーザーの最寄りのサーバーからそれぞれコンテンツを配信することによって世界中のユーザーに高速にコンテンツを届けることができます。

そんなCDNには以下のような機能があります。
> - 柔軟なキャッシュ設定
>    - エッジサーバーでキャッシュをすれば高速にレスポンスをクライアントに返せる
> - アクセスログなどのログ保存
> - HTTPのリクエスト・レスポンスの書き換え
> - DDoS対策　
>    - 大量のリクエストやトラフィックをWebサービスに送ることでWebサービスを提供できなくする攻撃を防ぐ 
> - Web Application Firewall
> - 攻撃と思われる悪意のあるリクエストを遮断したり、ログを取得する機能
> ~書籍より引用~

様々な機能がありますが、ここではキャッシュについて説明します。httpの**Cache-Controlヘッダーを用いることでProxyやCDNなど経路上のキャッシュに関する設定をすることができます。** CDNではクライアントから近いCDNのエッジサーバーからレスポンスを直接返すことができます。アプリケーションサーバーのリクエストを減らすことによって負荷を減らすことも可能です。
```mermaid
graph TD
    Client1[クライアント1] --> EdgeServer1[近くのエッジサーバー1]
    Client2[クライアント2] --> EdgeServer2[近くのエッジサーバー2]
    Client3[クライアント3] --> EdgeServer3[近くのエッジサーバー3]

    EdgeServer1 -->|キャッシュヒット| Client1
    EdgeServer2 -->|キャッシュヒット| Client2
    EdgeServer3 -->|キャッシュヒット| Client3

    EdgeServer1 -->|キャッシュミス| AppServer[アプリケーションサーバー]
    EdgeServer2 -->|キャッシュミス| AppServer
    EdgeServer3 -->|キャッシュミス| AppServer

    AppServer --> EdgeServer1
    AppServer --> EdgeServer2
    AppServer --> EdgeServer3

    EdgeServer1 -->|キャッシュされたレスポンス| Client1
    EdgeServer2 -->|キャッシュされたレスポンス| Client2
    EdgeServer3 -->|キャッシュされたレスポンス| Client3
```
**一方でCDNの挙動に対して詳しくなければ事故を起こしやすいです。** キャッシュはそもそも実装を間違えて事故を起こす可能性が高いのですが、CDNそのものの挙動も難しいので事故を起こす可能性はより一層高くなってしまうので注意が必要です。


# HTTPクライアントについて
以下のことを確認して導入することがよいと書籍で紹介されています。
## 同一ホストへのコネクションを使い回す
コネクションの確立にもコストがかかります。コネクションを確立するにはローカルのポートを消費する必要があります。また、TCP、TLSハンドシェイクも必要なのでそれにもコストがかかります。そのため、できる限り同一ホストへの通信はコネクションを使い回すのが理想です。

## 適切なタイムアウトを設定する
通信は成功する保証はなく、タイムアウトしていしまうことも勿論あります。その間リソースを消費し続けるので適切なタイムアウトを設定することが重要です。

## 同一ホストに大量のリクエストを送る場合、対象ホストへのコネクション数の制限を確認する
ライブラリやネットワークのシステムによっては外、対象ホストへのコネクション数が制限されていることがあります。同一ホストに大量のリクエストを送る場合、ドキュメントを確認して、制限がどうなっているか確認する必要があります。

# まとめ
以上がisucon本8章まとめです。チューニングに必須な項目を要約したので是非ご活用ください！
その他の章の記事はこちらから
[ISUCON本の内容をまとめてみた DB編](https://qiita.com/Atkiyama/items/e9429910a17fa749e243)
[ISUCON本の内容をまとめてみた リバースプロキシ nginx編](https://qiita.com/Atkiyama/items/2dcfa7a3147368da6cec)
[ISUCON本の内容をまとめてみた キャッシュ編](https://qiita.com/Atkiyama/items/91a1c2924f15f29264cc)
[ISUCON本の内容をまとめてみた 高速化に必要なその他技術編](https://qiita.com/Atkiyama/items/8de9f6e5db5c6a4384c4)
[ISUCON本の内容をまとめてみた OS Linux編](https://qiita.com/Atkiyama/items/32bdc11ea631fe1c1820)