This commit is contained in:
SATO Yusuke
2024-12-02 18:03:11 +00:00
committed by GitHub

View File

@@ -1088,9 +1088,9 @@ NoSQLに適するサンプルデータ:
<i><a href=http://horicky.blogspot.com/2010/10/scalable-system-design-patterns.html>Source: Scalable system design patterns</a></i>
</p>
キャッシュはページの読み込み時間を削減し、サーバーやデータベースへの負荷を低減することができます。このモデルでは、実際の処理を保存するために、ディスパッチャーがまず以前にリクエストが送信されたかどうかを確認し、前の結果を受け取ります。
キャッシュはページの読み込み時間を削減し、サーバーやデータベースへの負荷を低減することができます。このモデルでは、まずディスパッチャーは同じリクエストが以前に送信されていないか確認し、前の結果があればそれを返します。これにより、実際の処理を実行せずに済ませています。
データベースはそのパーティションに渡って統合された読み取り書き込みの分配を要求しますが、人気アイテムはその分配を歪めてシステム全体のボトルネックになってしまうことがあります。データベースの前にキャッシュを差し込むことでこのように、均一でない負荷やトラフィックの急激な増加を吸収することができます。
データベースには、全パーティションに対して均一に読み書きが分散している方がメリットがある処理がよくあります。頻繁に読み書きされるアイテムがあると、その分散が歪められ、ボトルネックができてしまうことがあります。データベースの前にキャッシュを差し込むことでこのように、均一でない負荷やトラフィックの急激な増加を吸収することができます。
### クライアントキャッシング
@@ -1106,15 +1106,15 @@ NoSQLに適するサンプルデータ:
### データベースキャッシング
データベースは普通、一般的な使用状況に適するようなキャッシングの設定を初期状態で持っています。この設定を特定の仕様に合わせて調整することでパフォーマンスを向上させることができます。
データベースは普通、ある程度のキャッシュがデフォルトで設定されています。この設定は一般的なユースケースに最適化されています。そのため、この設定を特定の用途に合わせて調整することでパフォーマンスを向上できます。
### アプリケーションキャッシング
メムキャッシュなどのIn-memoryキャッシュやRedisはアプリケーションとデータストレージの間キーバリューストアです。データはRAMで保持されるため、データがディスクで保存される一般的なデータベースよりもだいぶ速いです。RAM容量はディスクよりも限られているので、[least recently used (LRU)](https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used)などの[cache invalidation](https://en.wikipedia.org/wiki/Cache_algorithms) アルゴリズムが 'コールド' なエントリを弾き、'ホット' なデータをRAMに保存します。
MemcachedなどのIn-memoryキャッシュやRedisはアプリケーションとデータストレージの間に配置されるキーバリューストアです。データはRAMで保持されるため、データがディスクで保存される一般的なデータベースよりもだいぶ速いです。RAM容量はディスクよりも限られているので、[least recently used (LRU)](https://en.wikipedia.org/wiki/Cache_algorithms#Least_Recently_Used)などの[cache invalidation](https://en.wikipedia.org/wiki/Cache_algorithms) アルゴリズムが 'コールド' なエントリを弾き、'ホット' なデータをRAMに保存します。
Redisはさらに以下のような機能を備えています:
* パージステンス設定
* 永続化オプション
* ソート済みセット、リストなどの組み込みデータ構造
キャッシュには様々なレベルのものがありますが、いずれも大きく二つのカテゴリーのいずれかに分類することができます: **データベースクエリ****オブジェクト** です:
@@ -1124,11 +1124,11 @@ Redisはさらに以下のような機能を備えています:
* Fully-formed serializable objects
* Fully-rendered HTML
一般的に、ファイルベースキャッシングはクローンを作り出してオートスケーリング難しくしてしまうので避けるべきです。
一般的に、ファイルベースキャッシングはクローニングやオートスケーリング難しくなるため避けるべきです。
### データベースクエリレベルでのキャッシング
データベースをクエリする際には必ずクエリをキーとしてハッシュして結果をキャッシュに保存しましょう。この手法はキャッシュ期限切れ問題に悩むことになります:
データベースへ問い合わせる際、クエリをハッシュ化したものをキーとして、問い合わせ結果をキャッシュに保存する方法です。この手法はキャッシュ期限切れ問題に悩むことになります:
* 複雑なクエリによりキャッシュされた結果を削除することが困難
* テーブルセルなどのデータ断片が変化した時に、その変化したセルを含むかもしれない全てのキャッシュされたクエリを削除する必要がある。
@@ -1179,11 +1179,11 @@ def get_user(self, user_id):
[Memcached](https://memcached.org/) は通常このように使われる。
その後のキャッシュデータ読み込みは速です。キャッシュアサイドはレージーローディングであるとも言われます。リクエストされたデータのみがキャッシュされ、リクエストされていないデータでキャッシュが溢れるのを防止します。
その後のキャッシュにあるデータ読み込みは速です。キャッシュアサイドは遅延読み込みとも呼ばれます。リクエストされたデータのみがキャッシュされ、リクエストされていないデータでキャッシュが溢れるのを防止します。
##### 欠点: キャッシュアサイド
* キャッシュミスは三つのトリップを呼び出すことになり、体感できるほどの遅延が起きてしまいます。
* キャッシュミスごとにやり取りが三回発生するため、体感できるほどの遅延が起きることがあります。
* データベースのデータが更新されるとキャッシュデータは古いものになってしまいます。time-to-live (TTL)を設定することでキャッシュエントリの更新を強制的に行う、もしくはライトスルーを採用することでこの問題は緩和できます。
* ノードが落ちると、新規の空のノードで代替されることでレイテンシーが増加することになります。
@@ -1237,7 +1237,7 @@ def set_user(user_id, values):
##### 欠点: ライトビハインド
* キャッシュがデータストア内のコンテンツにヒットする前にキャッシュが落ちるとデータ欠損が起きる可能性があります。
* キャッシュ内のコンテンツがデータストアにたどり着く前にキャッシュが落ちるとデータ欠損が起きる可能性があります。
* キャッシュアサイドやライトスルーよりも実装が複雑になります。
#### リフレッシュアヘッド