Memcache から Memorystore への移行

Memcache は Python 2 ランタイムにバンドルされた、分散型のインメモリ データストアです。多くの App Engine アプリは、永続ストレージに頼るのではなく Memcache を特定のタスクのキャッシュとして使用します。

Memorystore for Redis は Redis インメモリ データストアを活用したフルマネージドのサービスを提供し、ミリ秒未満のデータアクセスを実現するアプリケーション キャッシュをビルドします。

Python 2 アプリで Memcache を使用して ndb または Cloud NDB リクエストのレイテンシのみを削減する場合、Memcache または Memorystore for Redis の代わりに、Cloud NDB の Redis 用組み込みサポートを使用できます。

Memorystore の権限について確認する

Google Cloud サービスでのすべての操作について承認を得る必要があります。たとえば、Memorystore でホストされている Redis データベースを操作するには、アプリは Memorystore へのアクセス権を持つアカウントの認証情報を提供する必要があります。

デフォルトでは、App Engine のデフォルトのサービス アカウントの認証情報が提供されます。このアカウントには、アプリと同じプロジェクトのデータベースにアクセスする権限が付与されます。

次のいずれかの条件に当てはまる場合は、認証情報を明示的に提示する別の認証方法を使用する必要があります。

  • アプリと Memorystore データベースが異なる Google Cloud プロジェクトに属する。

  • デフォルトの App Engine サービス アカウントに割り当てられているロールが変更されている。

代替認証の方法については、サーバー間の本番環境アプリケーションの認証の設定をご覧ください。

移行プロセスの概要

Memcache の代わりに Memorystore を使用するように Python アプリを移行するには、次の手順を行います。

  1. Redis 用 Memorystore をセットアップします。そのためには、Memorystore で Redis インスタンスを作成し、アプリが Redis インスタンスとの通信に使用するサーバーレス VPC アクセスを作成する必要があります。 この 2 つの独立したエンティティの作成順序は厳格ではなく、任意の順序で設定できます。このガイドの手順では、まずサーバーレス VPC アクセスを設定します。

  2. Redis のクライアント ライブラリをインストールし、Redis コマンドを使用してデータをキャッシュに保存します。

    Memorystore for Redis は Redis 用クライアント ライブラリと互換性があります。このガイドでは、アプリから Redis コマンドを送信する際の redis-py 3.0 クライアント ライブラリの使用について説明します。

  3. 更新をテストする

  4. App Engine にアプリをデプロイする

Memorystore for Redis のセットアップ

Memorystore for Redis をセットアップするには:

  1. App Engine を VPC ネットワークに接続します。アプリは VPC コネクタを介してのみ Memorystore と通信できます。

    コネクタを使用するようにアプリを構成するの説明に沿って、app.yaml ファイルに VPC 接続情報を追加します。

  2. 作成する Redis インスタンスの IP アドレスとポート番号をメモします。この情報は、コードで Redis クライアントを作成するときに使用します。

  3. Memorystore で Redis インスタンスを作成します。

    Redis インスタンスのリージョンを選択するように求められたら、App Engine アプリが配置されているのと同じリージョンを選択します。

依存関係のインストール

アプリが App Engine で実行されているときに redis-py クライアント ライブラリを使用できるようにするには、次の手順を行います。

  1. アプリの requirements.txt ファイルに次の行を追加します。

     redis
    
  2. Python 2 ランタイムでアプリを実行している場合、次の手順を行います。

    1. pip(バージョン 6 以降)を -t <directory> フラグを指定して使用して、lib という名前のローカル フォルダにライブラリをインストールします。次に例を示します。

      pip install -t lib <library_name> -r requirements.txt

    2. アプリの appengine_config.py ファイルで lib ディレクトリが指定されていることを確認してください。

    App Engine は、appengine_config.py ファイルで指定されたディレクトリ内のすべてのライブラリをアップロードします。詳しくは、Python 2 ライブラリの使用をご覧ください。

App Engine Python 3 ランタイムは、アプリをデプロイするときに、アプリの requirements.txt ファイルのすべてのライブラリを自動的にアップロードします。

ローカル開発では、Python 2 の virtualenv や Python 3 の venv などの仮想環境に依存関係をインストールすることをおすすめします。

Redis クライアントの作成

Redis データベースを操作するには、コード内で Redis クライアントを作成し、Redis データベースへの接続を管理する必要があります。以下のセクションでは、redis-py クライアント ライブラリを使用した Redis クライアントの作成について説明します。

環境変数の指定

redis-py クライアント ライブラリは、2 つの環境変数を使用して Redis データベースの URL をアセンブルします。

  • Memorystore で作成した Redis データベースの IP アドレスを識別する変数。
  • Memorystore で作成した Redis データベースのポート番号を識別する変数。

コード内で直接定義するのではなく、アプリの app.yaml ファイル内でこれらの変数を定義することをおすすめします。これにより、ローカル環境や App Engine などのさまざまな環境でアプリを実行しやすくなります。

たとえば、app.yaml ファイルに次の行を追加します。

 env_variables:
      REDISHOST: '10.112.12.112'
      REDISPORT: '6379'

redis-py のインポートとクライアントの作成

REDISHOSTREDISPORT を定義した後に、次の行を使用して redis-py ライブラリをインポートしてクライアントを作成します。

  import redis

  redis_host = os.environ.get('REDISHOST', 'localhost')
  redis_port = int(os.environ.get('REDISPORT', 6379))
  redis_client = redis.Redis(host=redis_host, port=redis_port)

古いバージョンの redis-py をその他のアプリで使用している場合は、Client ではなく StrictClient クラスを使用しているかもしれません。redis-py では、StrictClient ではなく Client の使用をおすすめします。

Redis コマンドを使用したキャッシュへのデータの保存と取得

Memorystore Redis データベースではほとんどの Redis コマンドがサポートされています。キャッシュからのデータの保存と取得にはいくつかのコマンドが必要になります。次の表に、データのキャッシュに使用できる Redis コマンドを示します。アプリからこれらのコマンドを呼び出す方法については、クライアント ライブラリのドキュメントをご覧ください。

memcache では多くのコマンドに非同期の代替メソッドが用意されていますが、redis-py クライアント ライブラリでは必ずしも同等の非同期メソッドは提供されません。キャッシュとのやりとりがすべて非同期である必要がある場合は、Python 用のその他の Redis クライアント ライブラリを使用してください。
タスク Redis コマンド
データ キャッシュにエントリを作成し、
エントリの有効期限を設定する
SETNX
MSETNX
キャッシュからデータを取得する GET
MGET
既存のキャッシュ値を置き換える SET
MSET
数値キャッシュ値を増減する INCR
INCRBY
DECR
DECRBY
キャッシュからエントリを削除する DEL
UNLINK
キャッシュとの並行処理をサポートする(比較と設定 Redis トランザクションの詳細をご覧ください。redis-py クライアント ライブラリでは、すべてのトランザクションがパイプラインで発生する必要があります。

アップデートのテスト

アプリをローカルでテストする場合は、Redis のローカル インスタンスを実行して、本番環境用データとの通信を回避してください(Memorystore では、エミュレータは提供されません)。Redis をローカルにインストールして実行するには、Redis のドキュメントにある手順を行ってください。現在、Redis を Windows 上でローカルに実行することはできません。

Python 2 アプリのテストについて詳しくは、ローカルの開発用サーバーの使用をご覧ください。

アプリのデプロイ

アプリをローカル開発用サーバーでエラーなしで実行した場合は、次の手順を行います。

  1. App Engine でアプリをテストします。

  2. アプリがエラーなしで実行されている場合、トラフィック分割を使用して、更新したアプリのトラフィックを徐々に増やします。更新したアプリへのトラフィックを増やす前に、データベースの問題が発生していないか細かくモニタリングして確認してください。