第35章: 分散ストレージ階層(KV / D1 / R2 / Durable Objects)
伝統的なコンピュータアーキテクチャでは、CPUの近くにレジスタや高速なSRAM(L1/L2/L3キャッシュ)があり、その下にDRAM(メインメモリ)、さらに低速かつ大容量なSSD/HDDや外部ネットワークストレージが存在します。
Cloudflare OS においても、地球全体を単一のコンピュータと見立てた「グローバル・メモリ階層(Global Storage Hierarchy)」が設計されています。
エッジでミリ秒未満のレイテンシを実現しつつ、一貫性とデータ永続性をいかに担保するか。本章では、ストレージ製品群をコンピュータのハードウェア階層にマッピングし、CAP定理のトレードオフと実践的なデータ配置戦略を解説します。
1. Cloudflare OSのストレージ階層モデル
| ハードウェア相当 | Cloudflare サービス | 特性 | レイテンシ | 一貫性モデル (CAP) | 推奨ユースケース |
|---|---|---|---|---|---|
| CPU L1/L2 キャッシュ | Workers Cache API / KV | 超高速・エッジ直近 | < 10ms | AP(結果的一貫性) | セッション検証、静的設定、フラグ |
| RAM (メインメモリ) | Durable Objects (In-Memory) | 単一インスタンス・強整合性 | 10ms - 50ms | CP(強い一貫性) | 共同編集、在庫引当、レートリミット |
| ローカル NVMe SSD | Cloudflare D1 (SQLite) | リレーショナル・分散リード | 20ms - 100ms | 読み取り: AP / 書き込み: CP | ユーザーマスタ、注文履歴、CMS |
| 外部 HDD / Cold Storage | Cloudflare R2 (S3互換) | 大容量・低コスト・イグレス無料 | 50ms - 200ms | 強整合性 (オブジェクト単位) | 画像・動画、ログアーカイブ、バックアップ |
2. 各レイヤーのアーキテクチャ詳細
2.1 Cache API & KV(エッジキャッシュ階層)
- 仕組み: 全世界330都市以上のデータセンターに配置されたKey-Valueストア。Cache APIはデータセンターローカルに留まり、KVはバックグラウンドで全世界のPoPへ非同期レプリケーションされます。
- トレードオフ: 書き込みが全拠点へ伝播するまでに最大60秒の遅延(Eventual Consistency)が発生します。「今すぐ全拠点で最新値が読めなくても致命的ではないが、10ms未満で高速に応答したい」データに最適です。
2.2 Durable Objects(グローバルRAM階層)
- 仕組み: 地球上の「特定の1箇所」にのみ存在するステートフルなActorインスタンス。メモリ上にJavaScriptオブジェクトを常駐させ、ミリ秒未満のIn-Memory操作と、同一トランザクション内でのローカルストレージ(SQLiteバックエンド)への永続化を行います。
- トレードオフ: 全世界からのアクセスがそのDOが存在する特定リージョンへルーティングされるため、遠隔地からのアクセスにはネットワークRTT(往復時間)が生じます。しかし、競合状態(Race Condition)を完全に排除できるため、厳密なトランザクションが要求される領域で不可欠です。
2.3 Cloudflare D1(エッジRDBMS階層)
- 仕組み: サーバーレスSQLiteをベースとし、プライマリデータベース(書き込み担当)と、世界各拠点に自動配置されるリードレプリカ(読み取り担当)で構成されます。
- トレードオフ: SELECTクエリは最寄りのエッジで極めて高速に実行されますが、INSERT/UPDATE/DELETEなどの書き込みは単一のプライマリノードへ中継されます。
2.4 Cloudflare R2(ブロック/オブジェクトストレージ階層)
- 仕組み: AWS S3互換の分散オブジェクトストレージ。最大の革新は データ転送料(Egress料金)が完全無料 である点です。
- トレードオフ: ミリ秒単位の頻繁なランダムアクセスには不向きですが、Workersのエッジとゼロコピーで連携し、動画ストリーミングや大容量ファイル配信のハブとして機能します。
3. 実践:階層型キャッシュ・データアクセスパターンの実装
コンピュータのL1キャッシュミス時にRAMやディスクへフォールバックするのと同様のパターンをWorkersで構築します。
import { Hono } from 'hono';
type Bindings = { KV_CACHE: KVNamespace; DB: D1Database; STORAGE: R2Bucket;};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/user/:id', async (c) => { const userId = c.req.param('id'); const cacheKey = `user:cache:${userId}`;
// 1. [L1 Cache] KVから超高速取得を試みる (レイテンシ ~10ms) const cached = await c.env.KV_CACHE.get(cacheKey, 'json'); if (cached) { return c.json({ data: cached, source: 'L1_CACHE (KV)' }); }
// 2. [SSD / DB] キャッシュミスのためD1から取得 (レイテンシ ~50ms) const user = await c.env.DB.prepare( 'SELECT id, name, email, avatar_key, updated_at FROM users WHERE id = ?' ).bind(userId).first();
if (!user) { return c.json({ error: 'User not found' }, 404); }
// 3. 次回アクセスのためにL1キャッシュに非同期書き込み (TTL: 60秒) c.executionCtx.waitUntil( c.env.KV_CACHE.put(cacheKey, JSON.stringify(user), { expirationTtl: 60 }) );
return c.json({ data: user, source: 'PRIMARY_STORAGE (D1)' });});
export default app;4. CAP定理とストレージ選定の判断フローチャート
flowchart TD
Start[データ設計の開始] --> Q1{厳密な書き込み一貫性や<br/>複数ノード間の排他制御が必要か?}
Q1 -- Yes --> Q2{リレーショナルなクエリ<br/>SQLが必要か?}
Q2 -- Yes --> D1[Cloudflare D1<br/>プライマリ書き込み + レプリカ読み取り]
Q2 -- No --> DO[Durable Objects<br/>単一整合性 + In-Memoryステート]
Q1 -- No --> Q3{データ形式は?}
Q3 -- 構造化/JSON/Key-Value --> Q4{超低レイテンシ読み取りが最優先か?}
Q4 -- Yes --> KV[Workers KV / Cache API<br/>結果的一貫性・グローバル分散]
Q4 -- No --> D1
Q3 -- 非構造化バイナリ/画像/PDF --> R2[Cloudflare R2<br/>Egress無料の大容量ストレージ]
💡 用語解説コラム
[!NOTE] CAP定理(CAP Theorem) 分散システムにおいては、「一貫性(Consistency)」「可用性(Availability)」「分断耐性(Partition tolerance)」の3つのうち、同時に最大2つしか満たすことができないという定理。CloudflareのKVは可用性と分断耐性を重視したAP型、Durable Objectsは一貫性と分断耐性を重視したCP型の設計思想を持っています。
[!NOTE] エッジのメモリ階層化(Tiered Storage) コンピュータのCPU・キャッシュ・メモリ・ディスクの関係性を、エッジコンピューティング環境(PoPキャッシュ・KV・DO・D1/R2)にそのまま適用したシステム設計。頻繁に読み出されるデータほどネットワーク的・物理的にユーザーに近いノードへキャッシュし、更新頻度や整合性の重い操作ほど集中管理されたレイヤーに委ねます。