# 1 日 90 億リクエストの cdnjs、まるごと Cloudflare 自社基盤に引っ越したよ！

やっほー、しぃちゃんだよ！今日は Cloudflare が自分たちのインフラを本気で使い倒した、ちょっとドヤ顔したくなるお話を持ってきたよ。

## なにが発表されたの？

Cloudflare Blog で、オープンソースの JS/CSS 配信 CDN「cdnjs」を Cloudflare 自社の Developer Platform に完全移行したことが発表されたよ。cdnjs は全 Web サイトの約 12 % で使われていて、JavaScript 系 CDN の中でのシェアは約 48.3 % なんだって。平均 108,000 リクエスト/秒、1 日あたりだと 90 億リクエストにもなる規模で、キャッシュヒット率は 98.6 %、330 以上のデータセンターに配信されているの。

## 今までどうだったの？

移行前の cdnjs は、Google Cloud Platform と Cloudflare にまたがった構成で動いていて、Cloud Functions・GCS イベント・Pub/Sub・git-sync 用の VM・Workers KV があちこちに散らばってたの。困りごとはこんな感じ。

- 観測性のギャップ: 各ステージに共通の相関 ID がなくて、処理は終わったのに GitHub への同期だけ失敗、みたいな部分的な障害が数週間も気づかれないことがあった
- ストレージの二重管理: ファイルが Workers KV と GitHub リポジトリの両方に「正」として存在していて、きれいに突き合わせる仕組みがなかった
- イベント連携の密結合: 各ステージがストレージイベントをメッセージ代わりに連結していて、デッドレターキューも滞留の可視化も再実行もできなかった
- アルファベット別のシャーディング: npm チェックを 26 個の Cloud Functions(アルファベット 1 文字ごと)で分担していて、それぞれ個別にデプロイ・ログ管理が必要だった
- 持続不可能なリポジトリ: git リポジトリが 1.1 TB まで膨らんで GitHub のアーカイブ生成上限を超え、フォークやクローンすら現実的じゃなくなっていた

## これで何が変わるの？

これらを全部 Cloudflare の Developer Platform に一本化したよ。

- R2 を正のファイルストレージにして、実質サイズ上限なし。ソースマップやバンドル、フォントパックみたいに今まで KV に入らなかった大きいファイルも置けるようになったの。S3 互換 API でカタログを外部にも公開してるよ
- KV は「読み取り多め・書き込み少なめ」という得意分野に合わせて、パッケージ情報・バージョン一覧・SRI ハッシュだけを持つメタデータ専用に
- 独立していた内部キャッシュ層を Workers Cache に置き換え
- 公開パイプラインを Workflows がオーケストレーション
- CPU 負荷の高い圧縮処理は Containers が担当
- Durable Objects が子ワークフローの完了数をカウント
- Queues が少なくとも 1 回配信を保証しながら移行作業をパッケージ名ごとに分配
- DigitalOcean Spaces を災害復旧用のミラー・フォールバックとして併用

技術レイヤーが 6 つも減って、観測性の穴も塞がったってわけなの。

## 深く潜ってみよう

パイプラインは 4 つの Workflow で構成されているよ。

- `PackageUpdatesWorkflow`: npm と GitHub を 10 分おきにチェック
- `DownloadPackageWorkflow`: tarball を R2 に取得
- `ProcessingWorkflow`: ファイルごとに展開・minify・圧縮
- `PublishingWorkflow`: 結果を書き込んで Algolia の検索インデックスも更新

移行そのものにも一苦労あったみたい。最初はファイルをまるごと再生成しようとしたんだけど、minify・圧縮ツールはバージョンをまたぐと完全に決定的じゃなくて、内容は正しいのに SRI ハッシュだけ変わっちゃうことが判明。そこで方針転換して、KV にある既存の内容をそのまま R2 にコピーする作戦に切り替えたの。数百万ファイルをアカウントをまたいで移行するのに、Queues 経由で複数の Worker 呼び出しに分割してサブリクエスト枯渇を避けたんだって。

この移行を通じて、Cloudflare は Workers・Workflows のプラットフォーム上限そのものも引き上げたよ。

- Worker 1 回の呼び出しあたりのサブリクエスト数上限: 1,000 → 有料プランで 1000 万まで
- Workflow のステップ数上限: デフォルト 1,024 → デフォルト 10,000(設定で最大 25,000 まで拡張可能)

これは cdnjs だけじゃなく、Workers・Workflows を使う全ユーザーに効いてくる変更だよ。あと、記事では今後 ES モジュールへの変換を公開時にやる案(圧縮と同じ Workflows + Containers パターンを使う)も検討中って触れられてたけど、まだ約束はされてないみたい。

## まとめ

- 1 日 90 億リクエスト・キャッシュヒット率 98.6 % の cdnjs を Cloudflare 自社の Developer Platform(R2・KV・Workers Cache・Workflows・Containers・Durable Objects・Queues)に完全移行
- GCP と Cloudflare にまたがっていた旧構成の 5 つの課題(観測性・二重ストレージ・密結合・シャーディング・巨大リポジトリ)を解消
- SRI ハッシュの非決定性という移行時のつまずきから、Worker のサブリクエスト上限を 1,000 → 1000 万、Workflow のステップ上限を 1,024 → 10,000(最大 25,000)に引き上げ
- この上限引き上げは cdnjs 専用じゃなく、Workers・Workflows を使う全開発者に恩恵がある

大規模な配信基盤やパイプラインを Workers の上に組みたい人、Cloudflare が自社サービスをどう Dogfooding してるか気になる人に刺さる話だよ。
