將 Memcache 遷移至 Memorystore

在處理某些工作時,高效能且可擴充的 Python 網路應用程式通常會使用記憶體內建的分散式資料快取,而非完善的永久儲存空間。

這時可使用 Memcache 這個 App Engine 解決方案,這是一種分散式記憶體內資料儲存庫,可用於特定工作做為快取。

遷移舊版套裝組合服務時,建議使用 Memorystore 取代 App Engine Memcache。Memorystore 是一項全代管的雲端快取服務,支援開放原始碼快取引擎 Redis 和 Memcached。本指南將介紹如何使用 Memorystore for Redis,產生應用程式快取,在不到 1 毫秒的時間內快速存取資料。

如果 Python 應用程式使用 Memcache 只為了減少 ndb 或 Cloud NDB 要求的延遲時間,您可以使用 Cloud NDB 內建的 Redis 支援功能,而非 Memcache 或 Cloud Memorystore for Redis。

開始前,請確認應用程式會維持在 Memorystore for Redis 配額範圍內。

使用 Python 應用程式記憶體快取的時機

在 Python 應用程式中,工作階段資料、使用者偏好設定和其他網頁查詢傳回的資料都很適合使用快取。一般來說,如果經常執行的查詢傳回的結果不需要立即顯示在應用程式中,您可以將結果快取。如此一來,後續要求就可以先查看快取,然後只有在找不到結果或暫存的結果因為逾期而消除的情況下,才去查詢資料庫。

如果您只將值儲存在 Memorystore 中,而未在永久儲存空間中備份,請務必確保在值到期並從快取中移除時,應用程式仍能正常運作。舉例來說,如果使用者的工作階段會因為資料突然消失,變成運作不良,那麼資料除了存放在 Memorystore,可能也應該儲存在資料庫。

事前準備

如果您尚未設定 Python 開發環境,請使用與 Google Cloud相容的 Python 版本,並安裝測試工具來建立隔離的 Python 環境。

瞭解 Memorystore 權限

您必須對每項與 Google Cloud 服務的互動進行授權。舉例來說,如要與 Memorystore 代管的 Redis 資料庫互動,應用程式必須提供已授權存取 Memorystore 的帳戶憑證。

根據預設,您的應用程式會提供 App Engine 預設服務帳戶的憑證,該帳戶已獲授權存取與應用程式相同專案中的資料庫。

如果符合下列任一條件,就必須使用其他驗證方法,明確提供憑證:

  • 您的應用程式和 Memorystore 資料庫位於不同的Google Cloud 專案中。

  • 您已變更指派給預設 App Engine 服務帳戶的角色。

如要瞭解其他驗證技術,請參閱「設定伺服器對伺服器正式版應用程式的驗證作業」。

轉換程序總覽

如要在 Python 應用程式中使用 Memorystore 而非 Memcache,請按照下列步驟操作:

  1. 設定 Memorystore for Redis,這需要您在 Memorystore 上建立 Redis 執行個體,並建立應用程式用來與 Redis 執行個體通訊的無伺服器虛擬私有雲端存取。建立這兩個獨立實體的順序並無硬性規定,可以按照任何順序設定。本指南的操作說明會先說明如何設定無伺服器虛擬私有雲存取。

  2. 安裝 Redis 用戶端程式庫,並使用 Redis 指令快取資料。

    Memorystore for Redis 與 任何 Redis 用戶端程式庫相容。

    本指南說明如何使用 redis-py 用戶端程式庫,從應用程式傳送 Redis 指令。

  3. 測試更新內容

  4. 將應用程式部署至 App Engine

設定 Memorystore for Redis

如要設定 Memorystore for Redis,請按照下列步驟操作:

  1. 將 App Engine 連線至虛擬私有雲網路。您的應用程式只能透過虛擬私有雲連接器與 Memorystore 通訊。

    請務必按照「設定應用程式使用連接器」一文所述,將 VPC 連線資訊新增至 app.yaml 檔案。

  2. 請記下您建立的 Redis 執行個體的 IP 位址和通訊埠編號。您可以在程式碼中建立 Redis 用戶端時使用這項資訊。

  3. 在 Memorystore 中建立 Redis 執行個體

    收到系統提示時,請選取 Redis 執行個體的所在地區,並選取與 App Engine 應用程式相同的地區

安裝依附元件

如要使用 redis-py 用戶端程式庫,請按照下列步驟操作:

  1. 更新 app.yaml 檔案。請按照您使用的 Python 版本的操作說明操作:

    Python 2

    如果是 Python 2 應用程式,請新增最新版本的 grpciosetuptools 程式庫。

    以下是 app.yaml 檔案範例:

    runtime: python27
    threadsafe: yes
    api_version: 1
    
    libraries:
    - name: grpcio
      version: latest
    - name: setuptools
      version: latest
    

    Python 3

    針對 Python 3 應用程式,請在 app.yaml 檔案中使用支援的 Python 3 版本指定 runtime 元素。例如:

    runtime: python310 # or another support version
    

    Python 3 執行階段會自動安裝程式庫,因此您不需要指定先前 Python 2 執行階段內建的程式庫。如果 Python 3 應用程式在遷移時使用其他舊版內含服務,您可以繼續指定必要的內建程式庫。否則,您可以刪除 app.yaml 檔案中不必要的資料行。

  2. 更新 requirements.txt 檔案。請按照您使用的 Python 版本的操作說明操作:

    Python 2

    將 Memorystore for Redis 的 Cloud 用戶端程式庫新增至 requirements.txt 檔案中的依附元件清單。

    redis
    

    執行 pip install -t lib -r requirements.txt 即可更新應用程式可用的程式庫清單。

    Python 3

    將 Memorystore for Redis 的 Cloud 用戶端程式庫新增至 requirements.txt 檔案中的依附元件清單。

    redis
    

    在 Python 3 執行階段部署應用程式時,App Engine 會自動安裝這些依附元件,因此請刪除 lib 資料夾 (如果有)。

  3. 針對 Python 2 應用程式,如果應用程式使用 lib 目錄中指定的內建或複製程式庫,您必須在 appengine_config.py 檔案中指定這些路徑,該檔案位於與 app.yaml 檔案相同的資料夾中:

    import pkg_resources
    from google.appengine.ext import vendor
    
    # Set PATH to your libraries folder.
    PATH = 'lib'
    # Add libraries installed in the PATH folder.
    vendor.add(PATH)
    # Add libraries to pkg_resources working set to find the distribution.
    pkg_resources.working_set.add_entry(PATH)
    

建立 Redis 用戶端

如要與 Redis 資料庫互動,程式碼需要建立 Redis 用戶端,以便管理與 Redis 資料庫的連線。以下各節將說明如何使用 redis-py 用戶端程式庫建立 Redis 用戶端。

指定環境變數

redis-py 用戶端程式庫會使用兩個環境變數組合 Redis 資料庫的網址:

  • 用於識別您在 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,可能會使用 StrictClient 類別,而非 Client。不過,redis-py 現在建議使用 Client,而非 StrictClient

使用 Redis 指令在快取中儲存及擷取資料

雖然 Memorystore Redis 資料庫支援大部分 Redis 指令,但您只需使用幾個指令,即可儲存快取資料並從中擷取資料。下表列出可用於快取資料的 Redis 指令。如要瞭解如何從應用程式呼叫這些指令,請參閱用戶端程式庫的說明文件。

請注意,對於 Python 2 應用程式,雖然 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 說明文件中的指示操作。請注意,目前無法在 Windows 本機上執行 Redis。

如要進一步瞭解如何測試 Python 應用程式,請參閱「使用本機開發伺服器」。

部署您的應用程式

應用程式在本機開發伺服器中執行時,如果沒有發生錯誤,請按照下列步驟操作:

  1. 在 App Engine 上測試應用程式

  2. 如果應用程式執行時沒有發生錯誤,請使用流量分配功能,逐步增加更新後應用程式的流量。在將更多流量導向更新後的應用程式前,請密切監控應用程式是否有任何資料庫問題。

後續步驟