缓存设计(2) – 分散
符合REST限制的分布式缓存系统不仅节约计算资源,还节省网络资源。

本文将探讨缓存在存储位置上的问题。
缓存发生的地方
现金存在以下三个选项之一。
-
- 服务器端
-
- 内容分发网络(共享缓存)
- 客户端

我们将设计一个分布式的缓存系统,以实现理想的现金系统,无论是HTML还是API。
谁知道缓存的TTL?
如果内容不是基于事件驱动,而是根据内容的准确生存期(TTL = 存活时间)进行控制,则服务器端确定TTL。例如,有效期到产品发布日的活动网站,或者可以精确计算出周一市场开盘时间的股票数据。
HTTP缓存通过在响应头中添加Cache-Control头来向CDN和客户端传达缓存的TTL。
禁用缓存
缓存被禁用的原因有两个:一个是指定的TTL时间已经过期,另一个是由事件造成的。
通过TTL使CDN缓存失效。
使用TTL进行无效化十分简便,可以同时应用于CDN和客户端。通过以秒为单位指定内容的有效期。
通过事件取消CDN缓存
一方面,需要注意通过事件来使缓存无效。通过服务器端Web应用程序的事件来使服务器端缓存无效是容易的,但是要对CDN进行无效化时,就需要使用支持即时清除的CDN,例如Fastly或Akamai。这时,为了确保事件驱动内容不被缓存清除,需要将缓存时间设置为最长(1年)。
インスタントパージが利用できないCDNでは、イベントドリブンコンテンツをCDNでキャッシュすることができません。キャッシュ時間をゼロにして、must-revalidateで都度確認するようにします。
ETag管理が最適されていると、最小限のネットワークおよびCPU資源の消費ですみますが、インスタントパージ可能なCDNのキャッシュの効率性には及びません。
クライアントキャッシュ
Cache-Control: max-age=3600
レスポンスディレクティブのmax-age=3600 は、レスポンスが生成されてから3600 秒後まで、レスポンスが新鮮なままであることを示します。このヘッダーはCDNでもキャッシュを作成しますが、クライアントでもキャッシュを作成します。最も強力なキャッシュで、ネットワークコストを節約します。
只有在能够精确预测TTL的情况下才使用。在此期间,不能在事件中更改内容。
对于事件驱动内容,客户端会通过条件式请求来确认内容是否有变化。如果没有变化,将会返回HTTP状态码304,因此客户端可以在客户端端重用保存的缓存。
また、パーソナライズされたページなど、クライアント間でキャッシュが共有できないときはprivateを使います。
Cache-Control: private, max-age=3600
CDNキャッシュ
当不需要将缓存保存到客户端时,可以使用以下两种选项之一的头部进行指定。
Cache-Control: s-maxage=3600
Surrogate-Control: max-age=3600
服务器端的缓存
サーバーサイドは3つのレイヤーで構成します。
-
- ETagリポジトリレイヤー
-
- サーバーサイドキャッシュレイヤー
- オリジンレイヤー
-
- CDNから到達したHTTPリクエストが、条件付きリクエストの場合には、コンテンツに変更がないかをETag リポジトリレイヤーが判定してなければ304を返します。ストレージに容量はあまり必要ないのでMemcachedのようなストレージが向いています。
-
- 対応するURLのサーバーサイドのキャッシュがあればそれを返却します。Redisなどを使います。
- キャッシュがなければ、オリジンレイヤーでレスポンスを返しますが、その時のキャッシュ可能なコンテンツはETagをETagレポジトリに格納してレスポンスデータをサーバーサイドキャッシュに格納します。
生成缓存的顺序
以下是缓存内容从服务器传输到客户端的情况:
-
- オリジンサーバーがコンテンツを生成します。
-
- コンテンツのETagをETagレポジトリに格納します。
-
- コンテンツのキャッシュをサーバーサイドのキャッシュに保存します。
-
- オリジンはHTTPヘッダーでETagを返します。 ETag: “”
-
- CDNはそのETagとその内容をCDNキャッシュに保存します。
- クライアントはコンテンツをローカルにキャッシュします。
当客户A的请求生成此缓存时,另一个客户B将从存储在CDN缓存中的4中受益。
中国語での選択肢:
對於Web瀏覽器,它能理解並遵從Cache-Control標頭;然而,對於API客戶端,為了理解Cache-Control標頭,需要使用符合RFC7234標準的客戶端。
支持RFC7234的API客户端
-
- JavaScript
- PHP
现金的强势排序 de
按照较强大的缓存顺序进行列举。
-
- ネットワークコストの発生しないクライアントキャッシュ(TTL)
-
- 都度確認をするクライアントキャッシュ(ETag)
-
- 304を返すCDN(ETag)
-
- キャッシュコンテンツを返すCDN
-
- 304を返すサーバーサイド(Etag)
- キャッシュコンテンツを返すサーバーサイド
现金系统设计
サーバーサイドのアプリケーションは、コンテンツの変更の際にキャッシュ管理処理をトリガーします。
-
- サーバーサイドのキャッシュを保存 (Redisなど)
-
- サーバーサイドでETagを保存 (memcacheなど)
- CDNに対してのAPIでパージ操作
BEAR.Sundayは一般的なMVCフレームワークよりこれらの操作に適した特徴があります。
-
- リソースはURIがあり、その操作はステートレス
-
- リソースのメソッドにセマンティックがありどれが読み込みで(onGet)どれが更新か区別がある
- AOP可能
大部分的缓存操作将在应用程序中进行操作之前通过框架自动化完成。