Partilhar via


Aviso de Descontinuação de Tarefa de Submissão do Spark & Guia de Migração

Advertência

A tarefa Spark Submit foi preterida e está pendente de remoção. O uso desse tipo de tarefa é proibido para novos casos de uso e fortemente desencorajado para clientes existentes. Consulte a documentação original para este tipo de tarefa em Spark Submit (legado). Continue lendo para obter instruções de migração.

Por que o Spark Submit está sendo preterido?

O tipo de tarefa Spark Submit está sendo preterido devido a limitações técnicas e lacunas de recursos que não estão nas tarefas de script JAR,Notebook ou Python . Essas tarefas oferecem melhor integração com os recursos do Databricks, melhor desempenho e maior confiabilidade.

Medidas de descontinuação

A Databricks está implementando as seguintes medidas em conexão com a descontinuação:

  • Criação restrita: somente usuários que usaram tarefas do Spark Submit no mês anterior, a partir de novembro de 2025, podem criar novas tarefas do Spark Submit . Se precisar de uma exceção, entre em contato com o suporte da sua conta.
  • Restrições de versões em tempo de execução do Databricks: A utilização do Spark Submit está restrita às versões existentes do Databricks em tempo de execução e às versões de manutenção. As versões existentes do Databricks Runtime com o Spark Submit continuarão a receber versões de manutenção de segurança e correção de bugs até que a funcionalidade seja completamente desligada. Os Databricks Runtime 17.3+ e 18.x+ não suportam este tipo de tarefa.
  • Avisos da interface do usuário: os avisos aparecem em toda a interface do usuário do Databricks onde as tarefas do Spark Submit estão em uso e as comunicações são enviadas aos administradores do espaço de trabalho em contas de usuários existentes.

Migrar cargas de trabalho da JVM para tarefas JAR

Para cargas de trabalho JVM, migre as suas tarefas do Spark Submit para tarefas JAR. As tarefas JAR oferecem melhor suporte a funcionalidades e integração com Databricks.

Siga estas etapas para migrar:

  1. Crie uma nova tarefa JAR no seu trabalho.
  2. Nos parâmetros da tarefa Spark Submit, identifique os três primeiros argumentos. Eles geralmente seguem este padrão: ["--class", "org.apache.spark.mainClassName", "dbfs:/path/to/jar_file.jar"]
  3. Remova o --class parâmetro.
  4. Defina o nome da classe principal (por exemplo, org.apache.spark.mainClassName) como a classe principal para sua tarefa JAR.
  5. Forneça o caminho para o arquivo JAR (por exemplo, dbfs:/path/to/jar_file.jar) na configuração da tarefa JAR.
  6. Copie quaisquer argumentos restantes da sua tarefa Spark Submit para os parâmetros da tarefa JAR.
  7. Execute a tarefa JAR e verifique se ela funciona conforme o esperado.

Para obter informações detalhadas sobre como configurar tarefas JAR, consulte Tarefa JAR.

Migrar cargas de trabalho de R

Se estiveres a iniciar um script R diretamente de uma tarefa Spark Submit, vários caminhos de migração estão disponíveis.

Opção A: Usar tarefas do Bloco de Anotações

Migre seu script R para um bloco de anotações Databricks. As tarefas de notebooks suportam um conjunto completo de funcionalidades, incluindo a escalabilidade automática de clusters, e proporcionam uma melhor integração com a plataforma Databricks.

Opção B: Scripts Bootstrap R a partir de uma tarefa do Bloco de Anotações

Use uma tarefa do Bloco de Anotações para inicializar seus scripts R. Crie um bloco de anotações com o código a seguir e faça referência ao seu arquivo R como um parâmetro de trabalho. Modifique para adicionar parâmetros usados pelo script R, se necessário:

dbutils.widgets.text("script_path", "", "Path to script")
script_path <- dbutils.widgets.get("script_path")
source(script_path)

Encontrar trabalhos que usam o Spark Enviar tarefas

Você pode usar os seguintes scripts Python para identificar trabalhos em seu espaço de trabalho que contêm tarefas do Spark Submit. Será necessário um acesso pessoal válido ou outro token e o URL da sua área de trabalho deverá ser utilizado.

Opção A: Verificação rápida (execute esta primeiro, apenas para trabalhos persistentes)

Este script verifica apenas trabalhos persistentes (criados através de /jobs/create ou da interface web) e não inclui trabalhos efémeros criados via /runs/submit. Este é o método de primeira linha recomendado para identificar o uso do Spark Submit porque é muito mais rápido.

#!/usr/bin/env python3
"""
Requirements:
    databricks-sdk>=0.20.0

Usage:
    export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com"
    export DATABRICKS_TOKEN="your-token"
    python3 list_spark_submit_jobs.py

Output:
    CSV format with columns: Job ID, Owner ID/Email, Job Name

Incorrect:
    export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com/?o=12345678910"
"""

import csv
import os
import sys
from databricks.sdk import WorkspaceClient
from databricks.sdk.errors import PermissionDenied


def main():
    # Get credentials from environment
    workspace_url = os.environ.get("DATABRICKS_HOST")
    token = os.environ.get("DATABRICKS_TOKEN")

    if not workspace_url or not token:
        print(
            "Error: Set DATABRICKS_HOST and DATABRICKS_TOKEN environment variables",
            file=sys.stderr,
        )
        sys.exit(1)

    # Initialize client
    client = WorkspaceClient(host=workspace_url, token=token)

    # Scan workspace for persistent jobs with Spark Submit tasks
    # Using list() to scan only persistent jobs (faster than list_runs())
    print(
        "Scanning workspace for persistent jobs with Spark Submit tasks...",
        file=sys.stderr,
    )
    jobs_with_spark_submit = []
    total_jobs = 0

    # Iterate through all jobs (pagination is handled automatically by the SDK)
    skipped_jobs = 0
    for job in client.jobs.list(expand_tasks=True, limit=25):
        try:
            total_jobs += 1
            if total_jobs % 1000 == 0:
                print(f"Scanned {total_jobs} jobs total", file=sys.stderr)

            # Check if job has any Spark Submit tasks
            if job.settings and job.settings.tasks:
                has_spark_submit = any(
                    task.spark_submit_task is not None for task in job.settings.tasks
                )

                if has_spark_submit:
                    # Extract job information
                    job_id = job.job_id
                    owner_email = job.creator_user_name or "Unknown"
                    job_name = job.settings.name or f"Job {job_id}"

                    jobs_with_spark_submit.append(
                        {"job_id": job_id, "owner_email": owner_email, "job_name": job_name}
                    )
        except PermissionDenied:
            # Skip jobs that the user doesn't have permission to access
            skipped_jobs += 1
            continue

    # Print summary to stderr
    print(f"Scanned {total_jobs} jobs total", file=sys.stderr)
    if skipped_jobs > 0:
        print(
            f"Skipped {skipped_jobs} jobs due to insufficient permissions",
            file=sys.stderr,
        )
    print(
        f"Found {len(jobs_with_spark_submit)} jobs with Spark Submit tasks",
        file=sys.stderr,
    )
    print("", file=sys.stderr)

    # Output CSV to stdout
    if jobs_with_spark_submit:
        writer = csv.DictWriter(
            sys.stdout,
            fieldnames=["job_id", "owner_email", "job_name"],
            quoting=csv.QUOTE_MINIMAL,
        )
        writer.writeheader()
        writer.writerows(jobs_with_spark_submit)
    else:
        print("No jobs with Spark Submit tasks found.", file=sys.stderr)


if __name__ == "__main__":
    main()

Opção B: Verificação abrangente (mais lenta, inclui trabalhos efêmeros dos últimos 30 dias)

Se você precisa identificar trabalhos efêmeros criados via /runs/submit, use este script mais exaustivo. Esse script verifica todos os trabalhos executados nos últimos 30 dias em seu espaço de trabalho, incluindo trabalhos persistentes (criados via /jobs/create) e trabalhos efêmeros. Esse script pode levar horas para ser executado em espaços de trabalho grandes.

#!/usr/bin/env python3
"""
Requirements:
    databricks-sdk>=0.20.0

Usage:
    export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com"
    export DATABRICKS_TOKEN="your-token"
    python3 list_spark_submit_runs.py

Output:
    CSV format with columns: Job ID, Run ID, Owner ID/Email, Job/Run Name

Incorrect:
    export DATABRICKS_HOST="https://your-workspace.cloud.databricks.com/?o=12345678910"
"""

import csv
import os
import sys
import time
from databricks.sdk import WorkspaceClient
from databricks.sdk.errors import PermissionDenied


def main():
    # Get credentials from environment
    workspace_url = os.environ.get("DATABRICKS_HOST")
    token = os.environ.get("DATABRICKS_TOKEN")

    if not workspace_url or not token:
        print(
            "Error: Set DATABRICKS_HOST and DATABRICKS_TOKEN environment variables",
            file=sys.stderr,
        )
        sys.exit(1)

    # Initialize client
    client = WorkspaceClient(host=workspace_url, token=token)

    thirty_days_ago_ms = int((time.time() - 30 * 24 * 60 * 60) * 1000)

    # Scan workspace for runs with Spark Submit tasks
    # Using list_runs() instead of list() to include ephemeral jobs created via /runs/submit
    print(
        "Scanning workspace for runs with Spark Submit tasks from the last 30 days... (this will take more than an hour in large workspaces)",
        file=sys.stderr,
    )
    runs_with_spark_submit = []
    total_runs = 0
    seen_job_ids = set()

    # Iterate through all runs (pagination is handled automatically by the SDK)
    skipped_runs = 0
    for run in client.jobs.list_runs(
        expand_tasks=True,
        limit=25,
        completed_only=True,
        start_time_from=thirty_days_ago_ms,
    ):
        try:
            total_runs += 1
            if total_runs % 1000 == 0:
                print(f"Scanned {total_runs} runs total", file=sys.stderr)

            # Check if run has any Spark Submit tasks
            if run.tasks:
                has_spark_submit = any(
                    task.spark_submit_task is not None for task in run.tasks
                )

                if has_spark_submit:
                    # Extract job information from the run
                    job_id = run.job_id if run.job_id else "N/A"
                    run_id = run.run_id if run.run_id else "N/A"
                    owner_email = run.creator_user_name or "Unknown"
                    # Use run name if available, otherwise try to construct a name
                    run_name = run.run_name or (
                        f"Run {run_id}" if run_id != "N/A" else "Unnamed Run"
                    )

                    # Track unique job IDs to avoid duplicates for persistent jobs
                    # (ephemeral jobs may have the same job_id across multiple runs)
                    key = (job_id, run_id)
                    if key not in seen_job_ids:
                        seen_job_ids.add(key)
                        runs_with_spark_submit.append(
                            {
                                "job_id": job_id,
                                "run_id": run_id,
                                "owner_email": owner_email,
                                "job_name": run_name,
                            }
                        )
        except PermissionDenied:
            # Skip runs that the user doesn't have permission to access
            skipped_runs += 1
            continue

    # Print summary to stderr
    print(f"Scanned {total_runs} runs total", file=sys.stderr)
    if skipped_runs > 0:
        print(
            f"Skipped {skipped_runs} runs due to insufficient permissions",
            file=sys.stderr,
        )
    print(
        f"Found {len(runs_with_spark_submit)} runs with Spark Submit tasks",
        file=sys.stderr,
    )
    print("", file=sys.stderr)

    # Output CSV to stdout
    if runs_with_spark_submit:
        writer = csv.DictWriter(
            sys.stdout,
            fieldnames=["job_id", "run_id", "owner_email", "job_name"],
            quoting=csv.QUOTE_MINIMAL,
        )
        writer.writeheader()
        writer.writerows(runs_with_spark_submit)
    else:
        print("No runs with Spark Submit tasks found.", file=sys.stderr)


if __name__ == "__main__":
    main()

Precisa de ajuda?

Se precisar de ajuda adicional, entre em contato com o suporte da sua conta.