Muitos pipelines do Apache Beam podem ser executados com os ambientes de execução do Dataflow predefinidos. No entanto, alguns exemplos de utilização do processamento de dados beneficiam da utilização de bibliotecas ou classes adicionais. Nestes casos, pode ter de gerir as dependências da pipeline.
A seguinte lista apresenta alguns motivos pelos quais pode ter de gerir as dependências do pipeline:
- As dependências fornecidas pelo ambiente de tempo de execução predefinido são insuficientes para o seu exemplo de utilização.
- As dependências predefinidas têm conflitos de versões ou têm classes e bibliotecas incompatíveis com o código do pipeline.
- Tem de fixar versões específicas da biblioteca para o seu pipeline.
- Tem um pipeline do Python que precisa de ser executado com um conjunto consistente de dependências.
A forma como gere as dependências depende de a sua pipeline usar Java, Python ou Go.
Java
As classes e as bibliotecas incompatíveis podem causar problemas de dependência Java. Se o seu pipeline contiver código e definições específicos do utilizador, o código não pode conter versões misturadas de bibliotecas.
Problemas de dependência do Java
Quando o pipeline tem problemas de dependência do Java, pode ocorrer um dos seguintes erros:
NoClassDefFoundError
: este erro ocorre quando uma classe inteira não está disponível durante o tempo de execução.NoSuchMethodError
: este erro ocorre quando a classe no caminho de classe usa uma versão que não contém o método correto ou quando a assinatura do método foi alterada.NoSuchFieldError
: este erro ocorre quando a classe no caminho de classe usa uma versão que não tem um campo necessário durante a execução.FATAL ERROR
: este erro ocorre quando não é possível carregar corretamente uma dependência incorporada. Quando usar um ficheiro JAR uber (sombreado), não inclua bibliotecas que usem assinaturas no mesmo ficheiro JAR, como o Conscrypt.
Gestão de dependências
Para simplificar a gestão de dependências para pipelines Java, o Apache Beam usa artefactos da lista de materiais (BOM). A BOM ajuda as ferramentas de gestão de dependências a selecionar combinações de dependências compatíveis. Para mais informações, consulte o artigo Dependências do SDK Apache Beam para Java na documentação do Apache Beam.
Para usar uma BOM com o seu pipeline e adicionar explicitamente outras dependências à lista de dependências, adicione as seguintes informações ao ficheiro pom.xml
para o artefacto do SDK. Para importar a BOM das bibliotecas corretas, use
beam-sdks-java-google-cloud-platform-bom
.
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-google-cloud-platform-bom</artifactId>
<version>LATEST</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-runners-google-cloud-dataflow-java</artifactId>
</dependency>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-io-google-cloud-platform</artifactId>
</dependency>
</dependencies>
O artefacto beam-sdks-java-core
contém apenas o SDK principal. Tem de adicionar explicitamente outras dependências, como I/O e executores, à lista de dependências.
Python
Quando executa tarefas do Dataflow através do SDK Python do Apache Beam, a gestão de dependências é útil nos seguintes cenários:
- O seu pipeline usa pacotes públicos do Python Package Index (PiPy) e quer disponibilizar estes pacotes remotamente.
- Quer criar um ambiente reproduzível.
- Para reduzir o tempo de arranque, deve evitar a instalação de dependências nos trabalhadores no momento da execução.
Defina dependências de pipelines Python
Embora possa usar um único script ou bloco de notas Python para escrever um pipeline do Apache Beam, no ecossistema Python, o software é frequentemente distribuído como pacotes. Para facilitar a manutenção do seu pipeline, quando o código do pipeline abrange vários ficheiros, agrupe os ficheiros do pipeline como um pacote Python.
- Defina as dependências do pipeline no ficheiro
setup.py
do seu pacote. - Prepare o pacote para os trabalhadores através da opção de pipeline
--setup_file
.
Quando os trabalhadores remotos começam, instalam o seu pacote. Para ver um exemplo, consulte juliaset no GitHub do Apache Beam.
Para estruturar o seu pipeline como um pacote Python, siga estes passos:
Crie um ficheiro
setup.py
para o seu projeto. No ficheirosetup.py
, inclua o argumentoinstall_requires
para especificar o conjunto mínimo de dependências para o seu pipeline. O exemplo seguinte mostra um ficheirosetup.py
básico.import setuptools setuptools.setup( name='PACKAGE_NAME', version='PACKAGE_VERSION', install_requires=[], packages=setuptools.find_packages(), )
Adicione o ficheiro
setup.py
, o ficheiro de fluxo de trabalho principal e um diretório com os restantes ficheiros ao diretório raiz do seu projeto. Este agrupamento de ficheiros é o pacote Python para o seu pipeline. A estrutura do ficheiro tem o seguinte aspeto:root_dir/ package_name/ __init__.py my_pipeline_launcher.py my_custom_transforms.py ...other files... setup.py main.py
Para executar o pipeline, instale o pacote no ambiente de envio. Use a opção de pipeline
--setup_file
para preparar o pacote para os trabalhadores. Por exemplo:python -m pip install -e . python main.py --runner DataflowRunner --setup_file ./setup.py <...other options...>
Estes passos simplificam a manutenção do código do pipeline, especialmente quando o código aumenta em tamanho e complexidade. Para outras formas de especificar dependências, consulte o artigo Gerir dependências de pipelines Python na documentação do Apache Beam.
Use contentores personalizados para controlar o ambiente de tempo de execução
Para executar um pipeline com o SDK Python do Apache Beam, os trabalhadores do Dataflow precisam de um ambiente Python que contenha um intérprete, o SDK do Apache Beam e as dependências do pipeline. As imagens de contentores do Docker fornecem o ambiente adequado para executar o código do pipeline.
As imagens de contentores padrão são lançadas com cada versão do SDK do Apache Beam e incluem as dependências do SDK do Apache Beam. Para mais informações, consulte o artigo Dependências do SDK Apache Beam para Python na documentação do Apache Beam.
Quando o seu pipeline requer uma dependência que não está incluída na imagem do contentor predefinida, a dependência tem de ser instalada no tempo de execução. A instalação de pacotes em tempo de execução pode ter as seguintes consequências:
- O tempo de arranque do trabalhador aumenta devido à resolução de dependências, à transferência e à instalação.
- O pipeline requer uma ligação à Internet para ser executado.
- O não determinismo ocorre devido a lançamentos de software em dependências.
Para evitar estes problemas, forneça o ambiente de tempo de execução numa imagem de contentor Docker personalizada. A utilização de uma imagem de contentor Docker personalizada com as dependências do pipeline pré-instaladas tem as seguintes vantagens:
- Garante que o ambiente de execução do pipeline tem o mesmo conjunto de dependências sempre que inicia a tarefa do Dataflow.
- Permite controlar o ambiente de tempo de execução do seu pipeline.
- Evita a resolução de dependências potencialmente demorada no arranque.
Quando usar imagens de contentores personalizadas, considere as seguintes orientações:
- Evite usar a etiqueta
:latest
com as suas imagens personalizadas. Etiquete as suas compilações com uma data, uma versão ou um identificador único. Este passo permite-lhe reverter para uma configuração de funcionamento conhecida, se necessário. - Use um ambiente de lançamento compatível com a sua imagem do contentor. Para mais orientações sobre a utilização de contentores personalizados, consulte o artigo Crie uma imagem de contentor.
Para ver detalhes sobre a pré-instalação de dependências do Python, consulte o artigo Pré-instale dependências do Python.
Controle o ambiente de lançamento com modelos do Dataflow
Se o seu pipeline precisar de dependências adicionais, pode ter de as instalar no ambiente de tempo de execução e no ambiente de lançamento. O ambiente de lançamento executa a versão de produção do pipeline. Uma vez que o ambiente de lançamento tem de ser compatível com o ambiente de tempo de execução, use as mesmas versões das dependências em ambos os ambientes.
Para ter um ambiente de lançamento reproduzível e em contentores, use os modelos flexíveis do Dataflow. Para mais informações, consulte o artigo Crie e execute um modelo flexível. Quando usar modelos flexíveis, considere os seguintes fatores:
- Se configurar o pipeline como um pacote, instale o pacote no seu Dockerfile de modelo.
Para configurar o modelo flexível, especifique
FLEX_TEMPLATE_PYTHON_SETUP_FILE
. Para mais informações, consulte o artigo Defina variáveis de ambiente do Dockerfile necessárias. - Se usar uma imagem de contentor personalizada com o seu pipeline, forneça-a quando iniciar o modelo. Para mais informações, consulte o artigo Use um contentor personalizado para dependências.
- Para criar a imagem Docker do modelo flexível do Dataflow, use a mesma imagem de contentor personalizada que a imagem base. Para mais informações, consulte o artigo Use imagens de contentores personalizadas.
Esta construção torna o seu ambiente de lançamento reproduzível e compatível com o seu ambiente de tempo de execução.
Para ver um exemplo que segue esta abordagem, consulte o tutorial Modelo flexível para um pipeline com dependências e um contentor personalizado no GitHub.
Para mais informações, consulte os artigos Torne o ambiente de lançamento compatível com o ambiente de tempo de execução e Controle as dependências que o pipeline usa na documentação do Apache Beam.
Go
Quando executa tarefas do Dataflow através do SDK Go do Apache Beam, os módulos Go são usados para gerir dependências. O ficheiro seguinte contém as dependências de compilação e de tempo de execução predefinidas usadas pelo seu pipeline:
https://raw.githubusercontent.com/apache/beam/vVERSION_NUMBER/sdks/go.sum
Substitua VERSION_NUMBER pela versão do SDK que está a usar.
Para obter informações sobre como gerir dependências para o seu pipeline Go, consulte o artigo Gerir dependências na documentação do Go.