データを格納および取得するための 2 つのテクニックを学びます。アプリケーションで使用する方法を選択するときは、データアクセスパターンに基づいてアーキテクチャを簡素化する方法を選択してください。

ただし、最初に、Redis に接続できることを確認してください。

モジュールの所要時間: 60 分



[ElastiCache ダッシュボード] に戻ります。

ステップ 4.1

(クリックして拡大)

ステップ 4.1
ステップ 4.2

(クリックして拡大)

ステップ 4.2

例では、エンドポイントが言及されるたびに、構成エンドポイントのホスト名を使用する必要があります。

ステップ 4.3

(クリックして拡大)

ステップ 4.3

構文: シェル

$ python

コマンドが中断される場合は、例の後半にある注意事項を参照してください。 

構文: python

syntax: python
>>> import redis
>>> client = redis.Redis.from_url('redis://endpoint:6379')
>>> client.ping()

True

注意: 切断された場合は、セキュリティグループの設定によってブロックされていることを意味します。EC2 インスタンスが、ElastiCache インスタンスに割り当てられたセキュリティグループにアクセスできることを確認します。たとえば、EC2 インスタンスがデフォルトのセキュリティグループに割り当てられていたとします。Amazon ElastiCache インスタンスのセキュリティグループを変更し、デフォルトのセキュリティグループ内のインスタンスからポート 6379 での接続を許可するカスタム TCP ルールを追加できます。

ソースでは、セキュリティグループ名の入力を開始し、セキュリティグループ ID をクリックできるようになります。セキュリティグループの詳細を確認する必要がある場合は、ドキュメントまたはセキュリティグループルールのリファレンスをご確認ください。

ステップ 4.5

(クリックして拡大)

ステップ 4.5

リポジトリには、EC2 インスタンスで実行できる Python コードがいくつかあります。ただし、最初にいくつかの環境変数を設定する必要があります。

構文: シェル

$ export REDIS_URL=redis://your_redis_endpoint:6379/
$ export DB_HOST=your_mysql_endpoint
$ export DB_USER=admin
$ export DB_PASS=your_admin_password
$ export DB_NAME=tutorial

mysql_endpoint、redis_endpoint、および password の値は、前のステップで保存したものです。


コードサンプルに実装されている 2 つのメソッドのうち最初のメソッドは、SQL クエリ結果のシリアル化された表現をキャッシュすることによって機能します。次の Python スニペットは、ロジックを示しています。

構文: python

def fetch(sql):

  result = cache.get(sql)
  if result:
    return deserialize(result)
  else:
    result = db.query(sql)
    cache.setex(sql, ttl, serialize(result))
    return result

最初に、SQL ステートメントがキーとして Redis で使用され、値が存在するかどうかを確認するためにキャッシュの検査を行います。値が存在しない場合は、SQL ステートメントを使用してデータベースをクエリします。データベースクエリの結果は Redis に保存されます。ttl 変数は、アプリケーションの性質に応じて、適切な値に設定する必要があります。ttl が期限切れになると、Redis はキーを削除し、関連するメモリを解放します。このコードはチュートリアルリポジトリから入手してそのまま実行することができますが、特定の時点で変数の値を確認したい場合は、こちらに print ステートメントを追加してください。

戦略の面から見たこのアプローチの欠点は、データベースでデータが変更されたときに、以前の結果がキャッシュされていて、その ttl がまだ経過していない場合、変更が自動的にユーザーに反映されないことです。

フェッチ関数の使用例:

構文: python

print(fetch("SELECT * FROM planet"))

結果は次のようになります。

構文: python

[{'id': 10, 'name': 'Mercury'},
 {'id': 11, 'name': 'Venus'},
 {'id': 12, 'name': 'Earth'},
 {'id': 13, 'name': 'Mars'},
 {'id': 14, 'name': 'Jupiter'},
 {'id': 15, 'name': 'Saturn'},
 {'id': 16, 'name': 'Uranus'},
 {'id': 17, 'name': 'Neptune'}]

もちろん、これは非常に基本的な例ですが、キャッシュから得た結果とデータベースから直接得た結果に差がないこのキャッシュパターンを実装することで、アプリケーションは大きなメリットを得ることができます。


実装する 2 番目の例では、データベースレコードを Redis ハッシュにマップします。

構文: python

def planet(id):

  key = "planet:" + str(id)
  result = cache.hgetall(key)

  if result:
      return result

  else:
      sql = "SELECT `id`, `name` FROM `planet` WHERE `id`=%s"
      result = db_record(sql, (id,))

      if result:
          cache.hmset(key, result)
          cache.expire(key, ttl)
      return result

Redis のキースペースはフラットですが、コロンで区切られた文字列を使用して構造をシミュレートするための規則があります。この例で、ID 1 のレコードのキーは「planet:1」になります。このスニペットは一般的なパターンを示すのに十分ですが、より抽象化が可能です。1 つのモジュールがキーの生成を担当し、別のモジュールが SQL 文字列の構築を担当するなどができます。さらに、ご使用のプログラミング言語で構築された、目的のツールがある可能性があります。
この例では、キャッシュまたはデータベースからレコードを取得します。同様に、オブジェクトをデータベースに永続化する担当関数が存在する場合もあります。


2 つの例では、有効期限または ttl を使用しました。その後、Redis がキーを削除します。ほとんどの場合はこれで十分ですが、古いデータはキャッシュからできるだけ早く削除することをお勧めします。使用例の場合は、書き込みスルーキャッシュ戦略などの他のオプションを確認してください。詳細については、このチュートリアルの最後にリンクがあります。興味がある場合は話してみましょう。例では EXPIRE コマンドを使用していますが、Redis には EXPIREAT も用意されています。これにより、キーを削除する日時を正確に指定できます。絶対的な Unix タイムスタンプ (1970 年 1 月 1 日からの秒単位の経過時間) をパラメータとして受け取ります。


データの量が構成済みの maxmemory 設定を超えると、Redis は選択された削除ポリシーに応じて異なる応答方法を使用します。デフォルトでは、Redis 向け ElastiCache は、最も長い間使用されていない ttl が設定されたキーをメモリから削除するように構成されています。削除ポリシーパラメータは maxmemory-policy と呼ばれ、ElastiCache のデフォルト値は volatile-lru になります。この使用例のもう 1 つの興味深いオプションは、volatile-ttl ポリシーです。これにより、最短の ttl を持つキーを削除してメモリを解放するよう、Redis に指示します。


この戦略を実装したら、アプリケーションをテストして、最良の ttl 値と最良の削除戦略をお探しください。空のキャッシュと完全なキャッシュを使用して、アプリケーションのパフォーマンスを確認します。