キャッシュ戦略 - Amazon ElastiCache

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

キャッシュ戦略

以下のトピックでは、キャッシュを設定および維持するための戦略について説明します。

キャッシュするデータとデータへのアクセスパターンに基づいて、キャッシュを入力し維持するために実装する戦略とは何か。たとえば、ゲームサイトやトレンドのニュースのランキングトップ 10 で同じ同じ戦略は使用したくないでしょう。このセクションの後半では、一般的なキャッシュのメンテナンス戦略、利点および欠点について説明します。

遅延読み込み

その名前が示すようため、[遅延読み込み] は、必要なときにのみキャッシュにデータを読み込むキャッシュ戦略です。これは、以下で説明するように動作します。

Amazon ElastiCacheは、インメモリ key-value ストアで、アプリケーションとアプリケーションがアクセスするデータストア (データベース) 間にあります。アプリケーションがデータをリクエストする場合は、常に ElastiCache キャッシュに最初にリクエストを行います。データがキャッシュにあり最新である場合、ElastiCache はアプリケーションにデータを返します。データがキャッシュにない場合、または期限が切れている場合は、アプリケーションはデータストアからのデータをリクエストします。その後、データストアはアプリケーションにデータを返します。次に、アプリケーションは、ストアから受信したデータをキャッシュに書き込みます。このようにして、次回リクエストされたときに、より迅速に取得できます。

[キャッシュヒット] は、データがキャッシュにあり、期限切れでない場合に発生します。

  1. アプリケーションは、キャッシュに対してデータをリクエストします。

  2. キャッシュはアプリケーションにデータを返します。

[キャッシュミス] は、データがキャッシュにないか、期限切れの場合に発生します。

  1. アプリケーションは、キャッシュに対してデータをリクエストします。

  2. キャッシュにはリクエストされたデータがないため、null を返します。

  3. アプリケーションはデータベースに対してデータをリクエストし、取得します。

  4. アプリケーションは、新しいデータでキャッシュを更新します。

遅延読み込みの利点と欠点

遅延読み込みの利点は次のとおりです。

  • リクエストされたデータのみをキャッシュします。

    ほとんどのデータがリクエストされないため、遅延読み込みではデータでキャッシュがいっぱいになることを回避できます。

  • ノード障害は、アプリケーションにとって致命的ではありません。

    ノードで障害が発生して新しい空のノードに置き換えられた場合、アプリケーションはレイテンシーが長くなっても機能し続けます。新規ノードへのリクエストが行われると、それぞれのキャッシュミスにより、データベースのクエリが行われます。同時に、後続のリクエストがキャッシュからデータを取得できるように、データコピーがキャッシュに追加されます。

遅延読み込みの欠点は次のとおりです。

  • キャッシュミスのペナルティがあります。1 回のキャッシュのミスで 3 回のトリップ:

    1. キャッシュに対する最初のデータリクエスト

    2. データベースへのデータクエリ

    3. キャッシュにデータを書き込む

    これらのミスにより、アプリケーションによるデータの取得に相当な遅延が発生する可能性があります。

  • 古いデータ。

    キャッシュミスがある場合にのみデータがキャッシュに書き込まれる場合は、キャッシュ内のデータが古くなる可能性があります。この結果は、データベースのデータが変更されたときに、キャッシュへの更新がないために発生します。この問題に対処するには、書き込みスルー および TTL の追加 戦略を使用できます。

遅延読み込み擬似コードの例

次のコードは、遅延読み込みロジックの擬似コードの例です。

// ***************************************** // function that returns a customer's record. // Attempts to retrieve the record from the cache. // If it is retrieved, the record is returned to the application. // If the record is not retrieved from the cache, it is // retrieved from the database, // added to the cache, and // returned to the application // ***************************************** get_customer(customer_id) customer_record = cache.get(customer_id) if (customer_record == null) customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id) cache.set(customer_id, customer_record) return customer_record

この例では、データを取得するアプリケーションコードは次のとおりです。

customer_record = get_customer(12345)

書き込みスルー

書き込みスルー戦略では、データがデータベースに書き込まれると常にデータを追加するか、キャッシュのデータを更新します。

書き込みスルーの利点と欠点

書き込みスルーの利点は次のとおりです。

  • キャッシュのデータが古くなりません。

    キャッシュにデータベースにデータが書き込まれるたびにキャッシュのデータが更新されるため、キャッシュのデータが常に最新の状態になります。

  • 書き込みペナルティ対読み取りペナルティ。

    1 回の書き込みで 2 回のトリップ:

    1. キャッシュへの書き込み

    2. データベースへの書き込み

    レイテンシーをプロセスに追加します。つまり、エンドユーザーは一般的に、データの取得時よりもデータの更新時のレイテンシーに対して寛容です。更新は作業量が大きく時間がかかるのが常です。

書き込みスルーの欠点は次のとおりです。

  • 欠落データ。

    ノード障害またはスケールアウトにより、新規ノードをスピンアップすると、データが欠落しています。このデータは、データベースで追加または更新されるまで失われ続けます。これを最小限に抑えるには、[遅延読み込み] を書き込みスルーで指定します。

  • キャッシュの変動。

    ほとんどのデータは読み込まれないため、これはリソース浪費です。[有効期限 (TTL) の値を追加する] を使用すると、無駄なスペースを最小限に抑えることができます。

書き込みスルー擬似コードの例

以下は、書き込みスルーロジックの擬似コードの例です。

// ***************************************** // function that saves a customer's record. // ***************************************** save_customer(customer_id, values) customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values) cache.set(customer_id, customer_record) return success

この例では、データを取得するアプリケーションコードは次のとおりです。

save_customer(12345,{"address":"123 Main"})

TTL の追加

遅延読み取りはデータが古くなる可能性がありますが、空ノードによる障害は発生しません。書き込みスルーでは常に新しいデータとなりますが、空ノードの障害が発生して、過剰なデータがキャッシュに入力される可能性があります。それぞれの書き込みに有効期限 (TTL) の値を追加することで、それぞれの戦略のメリットが得られます。同時に、過剰なデータでキャッシュがいっぱいになる事態が避けられます。

[有効期限 (TTL)] は、キーの有効期限までの秒数を指定する整数値です。Memcached は、この値を秒単位で指定します。アプリケーションが期限切れのキーを読み込もうとすると、キーが見つからないものとして処理されます。データベースにキーについてクエリされ、キャッシュが更新されます。このアプローチは、値が古くなっていないことを保証するものではありません。ただし、これはデータが古くなりすぎることを防ぎ、キャッシュの値がデータベースから時々更新されることを必要とします。

詳細については、Memcached の set コマンドを参照してください。

TTL 擬似コードの例

以下は、TTL のある書き込みスルーロジックの擬似コードの例です。

// ***************************************** // function that saves a customer's record. // The TTL value of 300 means that the record expires // 300 seconds (5 minutes) after the set command // and future reads will have to query the database. // ***************************************** save_customer(customer_id, values) customer_record = db.query("UPDATE Customers WHERE id = {0}", customer_id, values) cache.set(customer_id, customer_record, 300) return success

以下は、TTL のある遅延読み込みロジックの擬似コードの例です。

// ***************************************** // function that returns a customer's record. // Attempts to retrieve the record from the cache. // If it is retrieved, the record is returned to the application. // If the record is not retrieved from the cache, it is // retrieved from the database, // added to the cache, and // returned to the application. // The TTL value of 300 means that the record expires // 300 seconds (5 minutes) after the set command // and subsequent reads will have to query the database. // ***************************************** get_customer(customer_id) customer_record = cache.get(customer_id) if (customer_record != null) if (customer_record.TTL < 300) return customer_record // return the record and exit function // do this only if the record did not exist in the cache OR // the TTL was >= 300, i.e., the record in the cache had expired. customer_record = db.query("SELECT * FROM Customers WHERE id = {0}", customer_id) cache.set(customer_id, customer_record, 300) // update the cache return customer_record // return the newly retrieved record and exit function

この例では、データを取得するアプリケーションコードは次のとおりです。

save_customer(12345,{"address":"123 Main"})
customer_record = get_customer(12345)

関連トピック