Fornecendo um Arquivo Compactado de Dependência

Seus aplicativos Java ou Scala podem precisar de arquivos JAR extras que você não pode ou não quer empacotar em um Fat JAR. Ou talvez você queira incluir código nativo ou outros ativos para disponibilizar no runtime do Spark.

Quando as opções de script spark-submit não funcionam, o serviço Data Flow tem a opção de fornecer um arquivo ZIP (archive.zip) junto com seu aplicativo para agrupar dependências de terceiros. O arquivo ZIP pode ser criado usando uma ferramenta baseada no Docker. O archive.zip é instalado em todos os nós do Spark antes de executar o aplicativo. Se você construir o archive.zip corretamente, as bibliotecas Python serão adicionadas ao runtime e os arquivos JAR serão adicionados ao classpath do Spark. As bibliotecas adicionadas são isoladas em uma Execução. Isso significa que eles não interferem em outras Execuções simultâneas ou Execuções posteriores. Apenas um arquivo compactado pode ser fornecido por Execução.

Qualquer coisa no archive deve ser compatível com o runtime do serviço Data Flow. Por exemplo, o serviço Data Flow é executado no Oracle Linux usando versões específicas do Java e Python. O código binário compilado para outros OSs ou arquivos JAR compilados para outras versões do Java pode causar falha na Execução. O serviço Data Flow fornece ferramentas para ajudar você a criar arquivos compactados com software compatível. No entanto, esses arquivos são arquivos Zip comuns, então você é livre para criá-los de qualquer maneira que quiser. Se você usar suas próprias ferramentas, será responsável por garantir a compatibilidade.

Os arquivos compactados de dependência, da mesma forma que os aplicativos Spark, são carregados no serviço Data Flow. Sua definição de Aplicativo Data Flow contém um link para esse arquivo compactado, que pode ser substituído no runtime. Quando você executa seu Aplicativo, o arquivo compactado é baixado e instalado antes da execução do job do Spark. O arquivo compactado é privado para a Execução. Isso significa, por exemplo, que você pode executar simultaneamente duas instâncias distintas do mesmo Aplicativo, com diferentes dependências, mas sem conflitos. As dependências não persistem entre Execuções; portanto, não há problemas com versões conflitantes para outros aplicativos Spark que você possa executar.

Criando um Arquivo Compactado de Dependência com o Pacote de Dependência do Serviço Data Flow

  1. Faça download do docker.
  2. Faça download da imagem da ferramenta do empacotador:
    Forma do ARM:
    docker pull phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest
    Forma do AMD:
    docker pull phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest
  3. Para dependências Python, crie um arquivo requirements.txt. Por exemplo, pode ser semelhante a:
    numpy==1.18.1
    pandas==1.0.3
    pyarrow==0.14.0
    Observação

    Não inclua pyspark ou py4j. Essas dependências são fornecidas pelo serviço Data Flow e a inclusão delas causa a falha das Execuções.
    O Data Flow Dependency Packager usa a ferramenta pip do Python para instalar todas as dependências. Se você tiver rodas Python que não podem ser baixadas de origens públicas, coloque-as em um diretório abaixo do local onde você cria o pacote. Veja-os em requirements.txt com um prefixo /opt/dataflow/. Por exemplo:
    /opt/dataflow/<my-python-wheel.whl>

    em que <my-python-wheel.whl> representa o nome da roda Python. O Pip o vê como arquivo local e o instala normalmente.

  4. Para dependências do Java, crie um arquivo chamado packages.txt. Por exemplo, pode ser semelhante a:
    ml.dmlc:xgboost4j:0.90
    ml.dmlc:xgboost4j-spark:0.90
    https://repo1.maven.org/maven2/com/nimbusds/nimbus-jose-jwt/8.11/nimbus-jose-jwt-8.11.jar

    O Data Flow Dependency Packager usa o Apache Maven para fazer download de arquivos JAR de dependência. Se você tiver arquivos JAR que não podem ser baixados de origens públicas, coloque-os em um diretório abaixo do local onde você cria o pacote. Quaisquer arquivos JAR em qualquer subdiretório no qual você cria o pacote é incluído no arquivo compactado.

  5. Use o contêiner do docker para criar o arquivo compactado.
    Observação

    A versão do Python deve ser definida como 3.11 ao usar o Spark 3.5.0, 3.8 ao usar o Spark 3.2.1 e 3.6 ao usar o Spark 3.0.2 ou o Spark 2.4.4. Nos comandos a seguir, <python_version> representa esse número.

    Use esse comando se estiver usando o MacOS ou o Linux:

    AMD64:

    docker run --platform linux/amd64 --rm -v $(pwd):/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest -p <python_version>
                                

    ARM64:

    docker run --platform linux/arm64 --rm -v $(pwd):/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest -p <python_version>
                                

    Se estiver usando o prompt de comando do Windows como Administrador, use este comando:

    AMD64:

    docker run --platform linux/amd64 --rm -v %CD%:/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest -p <python_version>
                                

    ARM64:

    docker run --platform linux/arm64 --rm -v %CD%:/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest -p <python_version>
                                

    Se estiver usando o Windows Powershell como Administrador, use este comando:

    AMD64:

    docker run --platform linux/amd64 --rm -v ${PWD}:/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest -p <python_version>
                                

    ARM64:

    docker run --platform linux/arm64 --rm -v ${PWD}:/opt/dataflow 
    --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest -p <python_version>
                                

    Para usar o Podman para criar o archive, use este comando no Linux:

    AMD64:

    podman run --platform linux/amd64 --rm -v $(pwd):/opt/dataflow:Z -u root 
    -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest -p <python_version>
                                

    ARM64:

    podman run --platform linux/arm64 --rm -v $(pwd):/opt/dataflow:Z -u root 
    -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest -p <python_version>
                                

    Esses comandos criam um arquivo chamado archive.zip.

    O diretório de trabalho é representado por pwd. O flag -v indica o mapeamento de volume do docker para o sistema de arquivos local.

  6. Você pode adicionar conteúdo estático. Talvez você queira incluir outro conteúdo no arquivo compactado. Por exemplo, talvez você queira implantar um arquivo de dados, um arquivo de modelo ML ou um executável que o programa do Spark chama no runtime. Você faz isso adicionando arquivos ao archive.zip depois de criá-lo na Etapa 4.

    Para aplicativos Java:

    1. Descompacte o arquivo archive.zip.
    2. Adicione os arquivos JAR somente no diretório java/.
    3. Compacte o arquivo.
    4. Faça upload dele para o Object Storage.
    Para aplicativos Python:
    1. Descompacte o arquivo archive.zip.
    2. Adicione módulos locais somente a estes três subdiretórios do diretório python/:
      python/lib
      python/lib32
      python/lib64
    3. Compacte o arquivo.
    4. Faça upload dele para o armazenamento de objeto.
    Observação

    Somente esses quatro diretórios são permitidos para armazenar as dependências do Java e do Python.

    Quando o aplicativo Data Flow é executado, o conteúdo estático estático está disponível em qualquer nó no diretório em que você optou por colocá-lo. Por exemplo, se você adicionou arquivos em python/lib/ no arquivo compactado, eles estarão disponíveis no diretório /opt/dataflow/python/lib/ em qualquer nó.

  7. Faça upload de archive.zip para o armazenamento de objetos.
  8. Adicione a biblioteca ao aplicativo. Consulte Criando um Aplicativo Java ou Scala do Serviço Data Flow ou Criando um Aplicativo PySpark do Serviço Data Flow para obter como fazer isso.

A Estrutura do Arquivo Compactado de Dependência

Arquivos compactados de dependência são arquivos ZIP comuns. Os usuários avançados podem querer criar arquivos compactados com suas próprias ferramentas, em vez de usar o Data Flow Dependency Packager. Um arquivo de dependência construído corretamente tem esta estrutura de tópicos geral:

python
python/lib
python/lib/python3.6/<your_library1>
python/lib/python3.6/<your_library2>
python/lib/python3.6/<...>
python/lib/python3.6/<your_libraryN>
python/lib/user
python/lib/user/<your_static_data>
java
java/<your_jar_file1>
java/<...>
java/<your_jar_fileN>
O Observação

O serviço Data Flow extrai arquivos compactados no diretório /opt/dataflow.

Valide um Arquivo Archive.zip Usando o Pacote de Dependência do Serviço Data Flow

Você pode usar o Pacote de Dependência do Serviço Data Flow para validar um arquivo archive.zip localmente, antes de fazer upload do arquivo para o serviço Object Storage.

Navegue até o diretório que contém o arquivo archive.zip e execute os seguintes comandos, dependendo da forma:

ARM64:
docker run --platform linux/arm64 --rm -v $(pwd):/opt/dataflow  --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_arm64_v8:latest  -p 3.11 --validate archive.zip
AMD64:
docker run --platform linux/amd64 --rm -v $(pwd):/opt/dataflow  --pull always -it phx.ocir.io/axmemlgtri2a/dataflow/dependency-packager-linux_x86_64:latest   -p 3.11 --validate archive.zip

Exemplo de Arquivos Requirements.txt e Packages.txt

Este exemplo de um arquivo requirements.txt inclui o serviço Data Flow SDK for Python versão 2.14.3 em um Aplicativo Data Flow:
-i https://pypi.org/simple
certifi==2020.4.5.1
cffi==1.14.0
configparser==4.0.2
cryptography==2.8
oci==2.14.3
pycparser==2.20
pyopenssl==19.1.0
python-dateutil==2.8.1
pytz==2020.1
six==1.15.0
Este exemplo de um arquivo requirements.txt inclui uma combinação de origens PyPI, origens web e origens locais para arquivos de roda Python:
-i https://pypi.org/simple
blis==0.4.1
catalogue==1.0.0
certifi==2020.4.5.1
chardet==3.0.4
cymem==2.0.3
https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.0/en_core_web_sm-2.2.0.tar.gz#egg=en-core-web-sm
idna==2.9
importlib-metadata==1.6.0 ; python_version < '3.8'
murmurhash==1.0.2
numpy==1.18.3
plac==1.1.3
preshed==3.0.2
requests==2.23.0
spacy==2.2.4
srsly==1.0.2
thinc==7.4.0
tqdm==4.45.0
urllib3==1.25.9
wasabi==0.6.0
zipp==3.1.0
/opt/dataflow/mywheel-0.1-py3-none-any.whl
Para estabelecer conexão com bancos de dados Oracle, como o ADW, inclua arquivos JAR JDBC Oracle. Faça download e extraia os arquivos JAR de driver compatível em um diretório no local onde você cria o pacote. Por exemplo, para empacotar o driver JDBC Oracle 18.3 (18c), certifique-se de que todos estes JARs estejam presentes:
ojdbc8-18.3.jar
oraclepki-18.3.jar
osdt_cert-18.3.jar
osdt_core-18.3.jar
ucp-18.3.jar