將 Memcache 遷移至 Memorystore

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

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

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

如果 Python 應用程式使用 Memcache 只是為了縮短 ndb 或 Cloud NDB 要求的延遲時間,則可使用 Cloud NDB 內建的 Redis 支援功能,不必使用 Memcache 或 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 執行個體通訊的無伺服器 VPC 存取。建立這兩個獨立實體的順序不拘,可以按照任何順序設定。本指南中的操作說明會先介紹如何設定無伺服器 VPC 存取。

  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 檔案中指定 runtime 元素,並使用支援的 Python 3 版本。例如:

    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. 如果應用程式順利執行,請使用流量分割,逐步增加更新版應用程式的流量。在將更多流量導向更新版應用程式之前,請密切監控應用程式,確認是否有任何資料庫問題。

後續步驟