Поделиться через


Обновление API заданий 2.0 до версии 2.1

Теперь вы можете управлять несколькими задачами с помощью заданий Azure Databricks. В этой статье описаны изменения в API заданий, которые поддерживают задания с несколькими задачами и предоставляют рекомендации по обновлению существующих клиентов API для работы с этой новой функцией.

Databricks рекомендует использовать API заданий версии 2.1 для скриптов и клиентов API, особенно при использовании заданий с несколькими задачами.

В этой статье задания с одной задачей называются однозадачными заданиями, а с несколькими задачами — многозадачными.

API заданий версий 2.0 и 2.1 теперь поддерживают запрос update. Используйте запрос update, чтобы изменить существующее задание, вместо запроса reset. Это позволит минимизировать изменения между однозадачными и многозадачными заданиями.

Изменения API

API заданий теперь определяет объект TaskSettings для записи параметров для каждой задачи в задании. Для многозадачных заданий поле tasks, которое является массивом структур данных TaskSettings, включается в объект JobSettings. Некоторые поля, которые ранее входили в JobSettings, теперь входят в параметры задачи для многозадачных заданий. JobSettings также обновлено с включением поля format. Поле format указывает формат задания и является значением STRING, для которого задано SINGLE_TASK или MULTI_TASK.

Вам нужно обновить существующие клиенты API для применения этих изменений к JobSettings для многозадачных заданий. Дополнительные сведения о необходимых изменениях см. в разделе Руководство по клиенту API.

API заданий версии 2.1 поддерживает многозадачный формат. Все запросы API 2.1 должны соответствовать многозадачному формату, а ответы должны быть также структурированы в многозадачном формате. Новые функции сначала будут выпущены в API 2.1.

В API заданий версии 2.0 добавлено дополнительное поле для поддержки многозадачных заданий. Если не указано иное, в примерах в этом документе используется API 2.0. Но для Databricks рекомендуется API 2.1 для работы с новыми и существующими скриптами и клиентами API.

Пример документа JSON, представляющего многозадачное задание для API 2.0 и 2.1:

{
  "job_id": 53,
  "settings": {
    "name": "A job with multiple tasks",
    "email_notifications": {},
    "timeout_seconds": 0,
    "max_concurrent_runs": 1,
    "tasks": [
      {
        "task_key": "clean_data",
        "description": "Clean and prepare the data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/clean-data"
        },
        "existing_cluster_id": "1201-my-cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      },
      {
        "task_key": "analyze_data",
        "description": "Perform an analysis of the data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/analyze-data"
        },
        "depends_on": [
          {
            "task_key": "clean_data"
          }
        ],
        "existing_cluster_id": "1201-my-cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      }
    ],
    "format": "MULTI_TASK"
  },
  "created_time": 1625841911296,
  "creator_user_name": "user@databricks.com",
  "run_as_user_name": "user@databricks.com"
}

API заданий версии 2.1 поддерживает конфигурацию кластеров на уровне задач или один либо несколько общих кластеров заданий:

  • Кластер уровня задач создается и запускается при запуске задачи, а его работа завершается после выполнения задачи.
  • Общий кластер заданий разрешает использовать кластер нескольким задачам в одном задании. Кластер создается и запускается при запуске первой задачи, использующей кластер, и завершает работу после завершения последней задачи, использующей кластер. Общий кластер заданий не завершает работу в простое, а только после выполнения всех использующих его задач. Вы можете одновременно запустить несколько независимых задач, совместно использующих кластер. Если общий кластер заданий прекращает работу (с ошибкой или без) до завершения всех задач, создается новый кластер.

Чтобы настроить общие кластеры заданий, включите массив JobCluster в объект JobSettings. Для одного задания можно указать не более 100 кластеров. Ниже приведен пример ответа API 2.1 для задания, настроенного с двумя общими кластерами:

Примечание.

Если задача имеет зависимости от библиотеки, вам нужно настроить библиотеки в параметрах поля task. Библиотеки нельзя настроить в конфигурации общего кластера заданий. В следующем примере поле libraries в конфигурации задачи ingest_orders демонстрирует спецификацию зависимости библиотеки.

{
  "job_id": 53,
  "settings": {
    "name": "A job with multiple tasks",
    "email_notifications": {},
    "timeout_seconds": 0,
    "max_concurrent_runs": 1,
    "job_clusters": [
      {
        "job_cluster_key": "default_cluster",
        "new_cluster": {
          "spark_version": "7.3.x-scala2.12",
          "node_type_id": "i3.xlarge",
          "spark_conf": {
            "spark.speculation": true
          },
          "aws_attributes": {
            "availability": "SPOT",
            "zone_id": "us-west-2a"
          },
          "autoscale": {
            "min_workers": 2,
            "max_workers": 8
          }
        }
      },
      {
        "job_cluster_key": "data_processing_cluster",
        "new_cluster": {
          "spark_version": "7.3.x-scala2.12",
          "node_type_id": "r4.2xlarge",
          "spark_conf": {
            "spark.speculation": true
          },
          "aws_attributes": {
            "availability": "SPOT",
            "zone_id": "us-west-2a"
          },
          "autoscale": {
            "min_workers": 8,
            "max_workers": 16
          }
        }
      }
    ],
    "tasks": [
      {
        "task_key": "ingest_orders",
        "description": "Ingest order data",
        "depends_on": [ ],
        "job_cluster_key": "auto_scaling_cluster",
        "spark_jar_task": {
          "main_class_name": "com.databricks.OrdersIngest",
          "parameters": [
            "--data",
            "dbfs:/path/to/order-data.json"
          ]
        },
        "libraries": [
          {
            "jar": "dbfs:/mnt/databricks/OrderIngest.jar"
          }
        ],
        "timeout_seconds": 86400,
        "max_retries": 3,
        "min_retry_interval_millis": 2000,
        "retry_on_timeout": false
      },
      {
        "task_key": "clean_orders",
        "description": "Clean and prepare the order data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/clean-data"
        },
        "job_cluster_key": "default_cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      },
      {
        "task_key": "analyze_orders",
        "description": "Perform an analysis of the order data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/analyze-data"
        },
        "depends_on": [
          {
            "task_key": "clean_data"
          }
        ],
        "job_cluster_key": "data_processing_cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      }
    ],
    "format": "MULTI_TASK"
  },
  "created_time": 1625841911296,
  "creator_user_name": "user@databricks.com",
  "run_as_user_name": "user@databricks.com"
}

Для однозадачных заданий структура данных JobSettings не изменяется, за исключением добавления поля format. Массив TaskSettings не включается, а параметры задачи все так же определяются на верхнем уровне структуры данных JobSettings. Вам не нужно вносить изменения в существующие клиенты API, чтобы обрабатывать однозадачные задания.

Пример документа JSON, представляющего однозадачное задание для API 2.0:

{
  "job_id": 27,
  "settings": {
    "name": "Example notebook",
    "existing_cluster_id": "1201-my-cluster",
    "libraries": [
      {
        "jar": "dbfs:/FileStore/jars/spark_examples.jar"
      }
    ],
    "email_notifications": {},
    "timeout_seconds": 0,
    "schedule": {
      "quartz_cron_expression": "0 0 0 * * ?",
      "timezone_id": "US/Pacific",
      "pause_status": "UNPAUSED"
    },
    "notebook_task": {
      "notebook_path": "/notebooks/example-notebook",
      "revision_timestamp": 0
    },
    "max_concurrent_runs": 1,
    "format": "SINGLE_TASK"
  },
  "created_time": 1504128821443,
  "creator_user_name": "user@databricks.com"
}

Руководство по клиенту API

В этом разделе приведены рекомендации, примеры и необходимые изменения для вызовов API, которые затронуты новой функцией многозадачных заданий.

В этом разделе рассматриваются следующие вопросы.

Create

Чтобы создать однозадачное задание с помощью операции создания задания (POST /jobs/create) в API заданий, вам не нужно изменять существующие клиенты.

Чтобы создать многозадачное задание, используйте поле tasks в JobSettings для указания параметров каждой задачи. В следующем примере выполняется создание задания с двумя задачами записных книжек. Этот пример предназначен для API 2.0 и 2.1:

Примечание.

Для каждого задания можно назначить не более 100 задач.

{
  "name": "Multi-task-job",
  "max_concurrent_runs": 1,
  "tasks": [
    {
      "task_key": "clean_data",
      "description": "Clean and prepare the data",
      "notebook_task": {
        "notebook_path": "/Users/user@databricks.com/clean-data"
      },
      "existing_cluster_id": "1201-my-cluster",
      "timeout_seconds": 3600,
      "max_retries": 3,
      "retry_on_timeout": true
    },
    {
      "task_key": "analyze_data",
      "description": "Perform an analysis of the data",
      "notebook_task": {
        "notebook_path": "/Users/user@databricks.com/analyze-data"
      },
      "depends_on": [
        {
          "task_key": "clean_data"
        }
      ],
      "existing_cluster_id": "1201-my-cluster",
      "timeout_seconds": 3600,
      "max_retries": 3,
      "retry_on_timeout": true
    }
  ]
}

Отправка выполнений

Чтобы отправить одноразовое выполнение однозадачного задания с помощью операции создания и запуска одноразового выполнения (POST /runs/submit) в API заданий, вам не нужно изменять существующие клиенты.

Чтобы отправить одноразовое выполнение многозадачного задания, используйте поле tasks в JobSettings для указания параметров каждой задачи, в том числе кластеров. При отправке многозадачного задания кластеры нужно задать на уровне задач, так как запрос runs submit не поддерживает общие кластеры заданий. См. раздел Создание с примером JobSettings с указанием нескольких задач.

Обновление

Чтобы обновить однозадачное задание с помощью операции частичного обновления задания (POST /jobs/update) в API заданий, вам не нужно изменять существующие клиенты.

Чтобы обновить параметры многозадачного задания, вам нужно использовать уникальное поле task_key для идентификации новых параметров task. См. раздел Создание с примером JobSettings с указанием нескольких задач.

Сброс

Чтобы перезаписать параметры однозадачного задания с помощью операции перезаписи всех параметров для задания (POST /jobs/reset) в API заданий, вам не нужно изменять существующие клиенты.

Чтобы перезаписать параметры многозадачного задания, укажите структуру данных JobSettings с массивом структур данных TaskSettings. См. раздел Создание с примером JobSettings с указанием нескольких задач.

Используйте операцию обновления, чтобы изменить отдельные поля без перехода с однозадачного на многозадачное задание.

Список

Для однозадачных заданий не требуется вносить изменения в клиент для обработки ответа от операции вывода всех заданий (GET /jobs/list) в API заданий.

Для многозадачных заданий большинство параметров определяются на уровне задач, а не на уровне задания. Конфигурацию кластера можно задать на уровне задач или задания. Чтобы изменить клиенты для доступа к кластеру или параметры задачи для многозадачного задания, возвращаемого в структуре Job, сделайте следующее:

  • Выполните анализ поля job_id для многозадачного задания.
  • Передайте job_id в операцию получения задания (GET /jobs/get) в API заданий, чтобы получить сведения о задании. В разделе о получении вы найдете пример ответа от вызова API Get для многозадачного задания.

В следующем примере приведен ответ с однозадачными и многозадачными заданиями. Этот пример предназначен для API 2.0:

{
  "jobs": [
    {
      "job_id": 36,
      "settings": {
        "name": "A job with a single task",
        "existing_cluster_id": "1201-my-cluster",
        "email_notifications": {},
        "timeout_seconds": 0,
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/example-notebook",
          "revision_timestamp": 0
        },
        "max_concurrent_runs": 1,
        "format": "SINGLE_TASK"
      },
      "created_time": 1505427148390,
      "creator_user_name": "user@databricks.com"
    },
    {
      "job_id": 53,
      "settings": {
        "name": "A job with multiple tasks",
        "email_notifications": {},
        "timeout_seconds": 0,
        "max_concurrent_runs": 1,
        "format": "MULTI_TASK"
      },
      "created_time": 1625841911296,
      "creator_user_name": "user@databricks.com"
    }
  ]
}

Получение

Для однозадачных заданий не требуется вносить изменения в клиент для обработки ответа от операции получения задания (GET /jobs/get) в API заданий.

Многозадачные задания возвращают массив структур данных task с параметрами задач. Если требуется доступ к сведениям на уровне задач, вам нужно изменить клиенты для итерации массива tasks и извлечения требуемых полей.

Ниже приведен пример ответа от вызова API Get для многозадачного задания. Этот пример предназначен для API 2.0 и 2.1:

{
  "job_id": 53,
  "settings": {
    "name": "A job with multiple tasks",
    "email_notifications": {},
    "timeout_seconds": 0,
    "max_concurrent_runs": 1,
    "tasks": [
      {
        "task_key": "clean_data",
        "description": "Clean and prepare the data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/clean-data"
        },
        "existing_cluster_id": "1201-my-cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      },
      {
        "task_key": "analyze_data",
        "description": "Perform an analysis of the data",
        "notebook_task": {
          "notebook_path": "/Users/user@databricks.com/analyze-data"
        },
        "depends_on": [
          {
            "task_key": "clean_data"
          }
        ],
        "existing_cluster_id": "1201-my-cluster",
        "max_retries": 3,
        "min_retry_interval_millis": 0,
        "retry_on_timeout": true,
        "timeout_seconds": 3600,
        "email_notifications": {}
      }
    ],
    "format": "MULTI_TASK"
  },
  "created_time": 1625841911296,
  "creator_user_name": "user@databricks.com",
  "run_as_user_name": "user@databricks.com"
}

Получение выполнений

Для однозадачных заданий не требуется вносить изменения в клиент для обработки ответа от операции получения выполнения задания (GET /jobs/runs/get) в API заданий.

Ответ для выполнения многозадачного задания содержит массив TaskSettings. Чтобы получить результаты выполнения для каждой задачи, сделайте следующее:

  • Выполните итерацию через каждую задачу.
  • Выполните анализ run_id для каждой задачи.
  • Вызовите операцию получения выходных данных для выполнения (GET /jobs/runs/get-output) с run_id, чтобы получить сведения о выполнении для каждой задачи. Ниже приведен пример ответа из этого запроса:
{
  "job_id": 53,
  "run_id": 759600,
  "number_in_job": 7,
  "original_attempt_run_id": 759600,
  "state": {
    "life_cycle_state": "TERMINATED",
    "result_state": "SUCCESS",
    "state_message": ""
  },
  "cluster_spec": {},
  "start_time": 1595943854860,
  "setup_duration": 0,
  "execution_duration": 0,
  "cleanup_duration": 0,
  "trigger": "ONE_TIME",
  "creator_user_name": "user@databricks.com",
  "run_name": "Query logs",
  "run_type": "JOB_RUN",
  "tasks": [
    {
      "run_id": 759601,
      "task_key": "query-logs",
      "description": "Query session logs",
      "notebook_task": {
        "notebook_path": "/Users/user@databricks.com/log-query"
      },
      "existing_cluster_id": "1201-my-cluster",
      "state": {
        "life_cycle_state": "TERMINATED",
        "result_state": "SUCCESS",
        "state_message": ""
      }
    },
    {
      "run_id": 759602,
      "task_key": "validate_output",
      "description": "Validate query output",
      "depends_on": [
        {
          "task_key": "query-logs"
        }
      ],
      "notebook_task": {
        "notebook_path": "/Users/user@databricks.com/validate-query-results"
      },
      "existing_cluster_id": "1201-my-cluster",
      "state": {
        "life_cycle_state": "TERMINATED",
        "result_state": "SUCCESS",
        "state_message": ""
      }
    }
  ],
  "format": "MULTI_TASK"
}

Выходные данные получения процессов выполнения

Для однозадачных заданий не требуется вносить изменения в клиент для обработки ответа от операции получения выходных данных выполнения (GET /jobs/runs/get-output) в API заданий.

Для многозадачных заданий вызов Runs get output для родительского выполнения приведет к ошибке, так как выходные данные выполнения доступны только для отдельных задач. Чтобы получить выходные данные и метаданные для многозадачного задания, сделайте следующее:

Перечень выполнений

Для однозадачных заданий не требуется вносить изменения в клиент для обработки ответа от операции вывода выполнений для задания (GET /jobs/runs/list).

Для многозадачных заданий возвращается пустой массив tasks. Передайте run_id в операцию получения выполнения задания (GET /jobs/runs/get), чтобы получить задачи. Ниже приведен пример ответа от вызова API Runs list для многозадачного задания:

{
  "runs": [
    {
      "job_id": 53,
      "run_id": 759600,
      "number_in_job": 7,
      "original_attempt_run_id": 759600,
      "state": {
          "life_cycle_state": "TERMINATED",
          "result_state": "SUCCESS",
          "state_message": ""
      },
      "cluster_spec": {},
      "start_time": 1595943854860,
      "setup_duration": 0,
      "execution_duration": 0,
      "cleanup_duration": 0,
      "trigger": "ONE_TIME",
      "creator_user_name": "user@databricks.com",
      "run_name": "Query logs",
      "run_type": "JOB_RUN",
      "tasks": [],
      "format": "MULTI_TASK"
    }
  ],
  "has_more": false
}