管理 Python Pipeline 相依性
相依性管理是關於指定您的 Pipeline 需要的相依性,並控制生產環境中使用哪些相依性。
注意: 用於 Pipeline 執行的遠端工作站通常在基於 Debian 的容器映像檔中安裝標準 Python 發行版。如果您的程式碼僅依賴標準 Python 套件,那麼您可能不需要在本頁上執行任何操作。
PyPI 相依性
如果您的 Pipeline 使用來自 Python 套件索引 的公開套件,您必須使這些套件在遠端工作站上可用。
對於僅包含單個 Python 檔案或筆記本的 Pipeline,提供相依性的最直接方法是提供 requirements.txt
檔案。對於更複雜的情況,請在套件中定義 Pipeline,並考慮在自訂容器中安裝您的相依性。
提供 requirements.txt 檔案
找出您的機器上安裝了哪些套件。執行以下命令
pip freeze > requirements.txt
此命令會建立一個
requirements.txt
檔案,其中列出您機器上安裝的所有套件,無論它們是從何處安裝的。編輯
requirements.txt
檔案,並刪除所有與您的程式碼無關的套件。使用以下命令列選項執行您的 Pipeline
--requirements_file requirements.txt
執行器將使用
requirements.txt
檔案將您的其他相依性安裝到遠端工作站上。
注意:作為
pip freeze
的替代方法,請使用諸如 pip-tools 之類的程式庫,從requirements.in
檔案編譯 Pipeline 所需的所有相依性。在requirements.in
檔案中,僅提及頂層相依性。
當您提供 --requirements_file
Pipeline 選項時,在 Pipeline 提交期間,Beam 會將指定的套件在本機下載到相依性快取目錄中,然後將相依性快取目錄暫存到執行器。在執行時,如果可用,Beam 會從相依性快取中安裝套件。這種機制使得可以在提交時將相依性套件暫存到執行器。在執行時,執行器工作站可能會從快取安裝套件,而無需連接到 PyPI。若要停用暫存相依性,請使用 --requirements_cache=skip
Pipeline 選項。如需更多資訊,請參閱 這些 Pipeline 選項的說明。
自訂容器
您可以傳遞一個 容器映像檔,其中包含 Pipeline 所需的所有相依性。請依照說明了解如何使用自訂容器映像檔執行 Pipeline。
如果您使用自訂容器映像檔,我們建議您在建置時直接從
--requirements_file
將相依性安裝到映像檔中。在這種情況下,您不需要在執行時傳遞--requirements_file
選項,這將縮短 Pipeline 啟動時間。# Add these lines with the path to the requirements.txt to the Dockerfile COPY <path to requirements.txt> /tmp/requirements.txt RUN python -m pip install -r /tmp/requirements.txt
本機 Python 套件或非公開 Python 相依性
如果您的 Pipeline 使用不可公開取得的套件 (例如,您從 GitHub 儲存庫下載的套件),請執行下列步驟使這些套件在遠端可用
識別您機器上安裝了哪些套件且不是公開的。執行以下命令
pip freeze
此命令會列出您機器上安裝的所有套件,無論它們是從何處安裝的。
多個檔案相依性
通常,您的 Pipeline 程式碼會跨越多個檔案。若要遠端執行您的專案,您必須將這些檔案分組為 Python 套件,並在執行 Pipeline 時指定套件。當遠端工作站啟動時,它們將安裝您的套件。若要將您的檔案分組為 Python 套件並使其在遠端可用,請執行下列步驟
為您的專案建立 setup.py 檔案。以下是一個非常基本的
setup.py
檔案。import setuptools setuptools.setup( name='PACKAGE-NAME', version='PACKAGE-VERSION', install_requires=[ # List Python packages your pipeline depends on. ], packages=setuptools.find_packages(), )
建構您的專案,使根目錄包含
setup.py
檔案、主要工作流程檔案和一個包含其餘檔案的目錄,例如root_dir/ setup.py main.py my_package/ my_pipeline_launcher.py my_custom_dofns_and_transforms.py other_utils_and_helpers.py
請參閱 Juliaset 以取得遵循此專案結構的範例。
在提交環境中安裝您的套件,例如使用以下命令
pip install -e .
使用以下命令列選項執行您的 Pipeline
--setup_file /path/to/setup.py
注意: 如果您的套件的相依性是在 setup.py
檔案的 install_requires
欄位中定義,則不需要提供 --requirements_file
選項 (請參閱步驟 1)。但是,與 --requirements_file
選項不同,當您使用 --setup_file
選項時,Beam 不會將相依套件暫存到執行器。只會暫存 Pipeline 套件。如果它們尚未在執行時環境中提供,則套件相依性會在執行時從 PyPI 安裝。
非 Python 相依性或具有非 Python 相依性的 PyPI 相依性
如果您的 Pipeline 使用非 Python 套件,例如需要使用 apt install
命令安裝的套件,或者使用在套件安裝期間依賴非 Python 相依性的 PyPI 套件,我們建議使用自訂容器安裝它們。否則,您必須執行下列步驟。
將非 Python 相依性的必要安裝命令 (例如
apt install
命令) 新增到setup.py
檔案中的CUSTOM_COMMANDS
清單中。請參閱 Juliaset setup.py 檔案以取得範例。注意: 您必須驗證這些命令是否在遠端工作站上執行。例如,如果您使用
apt
,遠端工作站需要apt
支援。使用以下命令列選項執行您的 Pipeline
--setup_file /path/to/setup.py
注意:由於自訂命令會在您的工作流程的相依性安裝完成後(透過 pip
)執行,您應該從管道的 requirements.txt
檔案以及 setup.py
檔案的 setuptools.setup()
呼叫中的 install_requires
參數中省略 PyPI 套件相依性。
預先建立 SDK 容器映像檔
在 Beam 執行器於 Docker 容器中啟動 SDK 工作站的管道執行模式中,額外的管道相依性(透過 --requirements_file
和其他執行階段選項指定)會在執行階段安裝到容器中。這可能會增加工作站的啟動時間。然而,有可能預先建置 SDK 容器,並在使用 --prebuild_sdk_container_engine
啟動工作站之前執行一次相依性安裝。有關如何使用 Google Cloud Dataflow 進行預先建置的說明,請參閱使用額外相依性預先建置 Python SDK 自訂容器映像檔。
注意:此功能僅適用於 Dataflow Runner v2
。
Pickling 和管理主要工作階段
當 Python SDK 將管道提交給遠端執行器執行時,管道內容(例如轉換使用者程式碼)會使用執行序列化的程式庫(也稱為 pickler)序列化(或 pickle)為位元組碼。Beam 使用的預設 pickler 程式庫是 dill
。若要使用 cloudpickle
pickler,請提供 --pickle_library=cloudpickle
管道選項。cloudpickle
的支援目前處於實驗性階段。
預設情況下,在主要管道模組中定義的全域匯入、函式和變數不會在 Beam 作業序列化期間儲存。因此,在任何遠端執行器上執行 DoFn
時,可能會遇到意外的 NameError
。若要解決此問題,請透過設定 --save_main_session
管道選項,將主要工作階段內容提供給管道。這會將全域命名空間的 pickle 狀態載入到 Dataflow 工作站上(如果使用 DataflowRunner
的話)。例如,請參閱處理 NameError,以在 DataflowRunner
上設定主要工作階段。
只有在任何遠端執行器上使用 dill
pickler 時,才需要在 Python SDK 中管理主要工作階段。因此,這個問題不會在 DirectRunner
中發生。
由於管道的序列化發生在作業提交時,而反序列化發生在執行階段,因此務必在作業提交時和執行階段使用相同版本的 pickling 程式庫。為確保這一點,Beam 通常會為 pickling 程式庫設定非常狹窄的支援版本範圍。如果由於任何原因,使用者無法使用 Beam 所需的 dill
或 cloudpickle
版本,並選擇安裝自訂版本,則他們也必須確保在執行階段使用相同的自訂版本(例如,在自訂容器中,或透過指定管道相依性需求)。
控制 Pipeline 使用的相依性
Pipeline 環境
若要在遠端執行器上執行 Python 管道,Apache Beam 會將管道轉換為與執行器無關的表示法,並提交以供執行。轉換發生在啟動環境中。您可以使用已安裝 Beam SDK 的 Python 虛擬環境,或使用 Dataflow Flex 範本、Notebook 環境、Apache Airflow 等工具啟動管道。
執行階段環境是執行器在管道執行期間使用的 Python 環境。此環境是管道程式碼在執行資料處理時的執行位置。執行階段環境包含 Apache Beam 和管道執行階段相依性。
建立可重現的環境
您可以使用數種工具來建置可重現的 Python 環境。
使用需求檔案。安裝相依性之後,請使用
pip freeze > requirements.txt
產生需求檔案。若要重建環境,請使用pip install -r requirements.txt
從 requirements.txt 檔案安裝相依性。使用限制檔案。您可以使用限制清單來限制套件的安裝,僅允許指定版本。
使用鎖定檔案。使用相依性管理工具,例如 PipEnv、Poetry 和 pip-tools,以指定最上層相依性、產生具有釘選版本的所有可轉移相依性的鎖定檔案,以及從這些鎖定檔案建立虛擬環境。
使用 Docker 容器映像檔。您可以將啟動和執行階段環境封裝在 Docker 容器映像檔中。如果映像檔包含所有必要的相依性,則環境只會在重建容器映像檔時變更。
使用版本控制來控制定義環境的組態檔案。
使 Pipeline 執行時環境可重現
當管道在遠端執行器上使用可重現的執行階段環境時,執行器上的工作站每次執行管道時都會使用相同的相依性。可重現的環境不受管道直接或可轉移相依性的版本發佈所造成的副作用影響。它不需要在執行階段進行相依性解析。
您可以使用下列方式建立可重現的執行階段環境。
在具有管道所有相依性的自訂容器映像檔中執行管道。使用
--sdk_container_image
管道選項。在
--requirements_file
管道選項中提供管道相依性的完整清單。使用--prebuild_sdk_container_engine
選項,在管道執行之前執行執行階段環境初始化序列。如果您的相依性沒有變更,請使用--sdk_container_image
選項重複使用預先建置的映像檔。
獨立的執行階段環境通常是可重現的。若要檢查執行階段環境是否為獨立,請限制在管道執行階段中對 PyPI 的網際網路存取。如果您使用 Dataflow 執行器,請參閱 --no_use_public_ips
管道選項的文件。
如果您需要重建或升級執行階段環境,請以可控制的方式進行,並瞭解已變更的相依性。
請勿在執行中的管道使用容器映像檔時修改它們。
避免將標籤
:latest
與您的自訂映像檔一起使用。請使用日期或唯一識別碼標記您的建置。如果發生錯誤,使用此類型的標籤可能會讓您將管道執行回復到先前已知的運作組態,並允許檢查變更。請考慮將
pip freeze
的輸出或requirements.txt
的內容儲存在版本控制系統中。
使 Pipeline 啟動環境可重現
啟動環境會執行管道的生產版本。在本地開發管道時,您可能會使用開發環境,其中包含用於開發的相依性,例如 Jupyter 或 Pylint。生產管道的啟動環境可能不需要這些額外的相依性。您可以獨立於開發環境建構和維護它。
為了減少對管道提交的副作用,最好能夠以可重現的方式重建啟動環境。
Dataflow Flex 範本提供容器化、可重現啟動環境的範例。
若要在乾淨的虛擬環境中建立可重現的 Beam 安裝,請使用需求檔案,其中列出 Beam 預設容器映像檔限制檔案中包含的所有 Python 相依性。
BEAM_VERSION=2.48.0
PYTHON_VERSION=`python -c "import sys; print(f'{sys.version_info.major}{sys.version_info.minor}')"`
pip install apache-beam==$BEAM_VERSION --constraint https://raw.githubusercontent.com/apache/beam/release-${BEAM_VERSION}/sdks/python/container/py${PY_VERSION}/base_image_requirements.txt
使用限制檔案,確保啟動環境中的 Beam 相依性與預設 Beam 容器中的版本相符。限制檔案也可能無需在安裝時進行相依性解析。
使啟動環境與執行時環境相容
啟動環境會將管道圖表轉換為與執行器無關的表示法。此過程涉及序列化(或 pickle)轉換的程式碼。序列化的內容會在工作站上反序列化。如果執行階段工作站環境與啟動環境顯著不同,則可能會因為下列原因而發生執行階段錯誤。
Apache Beam 版本在提交和執行階段環境中必須相符。Python 主要版本.次要版本也必須相符。否則,管道可能會失敗並出現類似
Pipeline construction environment and pipeline runtime environment are not compatible
的錯誤。在較舊的 SDK 版本中,錯誤可能會報告為SystemError: unknown opcode
。提交和執行階段環境中的
protobuf
版本需要相符或相容。管道程式碼中使用的程式庫可能需要相符。如果序列化的管道程式碼有對工作站上不可用的函式或模組的參考,則管道可能會在遠端執行器上失敗並出現
ModuleNotFound
或AttributeError
例外狀況。如果您遇到這類錯誤,請確保受影響的程式庫在遠端工作站上可用,並檢查是否需要儲存主要工作階段。在提交時使用的 pickling 程式庫版本必須與執行階段安裝的版本相符。為了強制執行此操作,Beam 會對序列化程式庫 (dill 和 cloudpickle) 的版本設定嚴格的限制。在下列情況下,您可以強制安裝與 Beam 所需版本不同的
dill
或cloudpickle
版本。- 您在提交和執行階段環境中安裝相同的版本。
- 所選版本適用於您的管道。
若要檢查執行階段環境是否與啟動環境相符,請檢查兩個環境中 pip freeze
輸出的差異。更新到最新版本的 Beam,因為環境相容性檢查包含在較新的 SDK 版本中。
最後,您可以透過從您在執行階段使用的容器化環境中啟動管道,來使用相同的環境。從自訂容器映像檔建置的 Dataflow Flex 範本提供此設定。在此案例中,您可以可重現的方式重新建立啟動和執行階段環境。由於兩個容器都是從相同的映像檔建立的,因此啟動和執行階段環境預設彼此相容。