从 Jobs API 2.0 更新到 2.1

现在可以使用 Azure Databricks 作业编排多个任务。 本文详细介绍了对支持具有多个任务的作业的 作业 API 的更改,并提供了指导,可帮助你更新现有 API 客户端以使用此功能。

Databricks 建议为 API 脚本和客户端使用 Jobs API 2.1,特别是在涉及多个任务的作业时。

本文介绍将具有单个任务的作业定义为 单任务工作格式, 将具有多个任务的作业定义为 多任务工作格式

作业 API 2.0 和 2.1 现在支持 update 请求。 使用 update 请求更改现有作业,而不是 重置 请求,以最大程度地减少单任务格式作业和多任务格式作业之间的更改。

API 更改

作业 API 现在定义一个 TaskSettings 对象,用于捕获作业中每个任务的设置。 对于多任务格式作业,tasks 字段是 TaskSettings 数据结构的数组,包含在 JobSettings 对象中。 以前属于 JobSettings 的某些字段现在是多任务格式作业的任务设置的一部分。 JobSettings 还会更新以包含 format 字段。 format 字段指示作业的格式,STRING 值被设置为 SINGLE_TASKMULTI_TASK

您需要更新现有的 API 客户端,以便适应针对多任务格式作业的 JobSettings 所做的更改。 有关所需更改的详细信息,请参阅 API 客户端指南

作业 API 2.1 支持多任务格式。 所有 API 2.1 请求都必须符合此格式,并且响应采用此格式。

作业 API 2.0 已更新,增加了一个字段以支持多任务格式作业。 除非另有说明,本文档中的示例使用 API 2.0。 但是,Databricks 建议为新的和现有的 API 脚本和客户端推荐 API 2.1。

表示 API 2.0 和 2.1 的多任务格式作业的示例 JSON 文档:

{
  "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 支持配置任务级群集或一个或多个共享作业群集:

  • 任务级别群集在任务开始时创建并启动,并在任务完成时终止。
  • 共享作业群集允许同一作业中的多个任务使用该群集。 在使用群集的第一个任务开始时创建并启动群集,并在使用群集的最后一个任务完成后终止。 共享作业群集在空闲时不会终止,但仅在使用共享作业群集的所有任务完成后终止。 共享群集的多个非依赖任务可以同时启动。 如果共享作业群集在完成所有任务之前失败或终止,则会创建一个新群集。

若要配置共享作业群集,请在 JobSettings 对象中包含 JobCluster 数组。 每个作业最多可以指定 100 个群集。 下面是配置了两个共享群集的作业的 API 2.1 响应示例:

注意

如果任务具有库依赖项,则必须在 task 字段设置中配置库;无法在共享作业群集配置中配置库。 在以下示例中,ingest_orders 任务配置中的 libraries 字段演示了库依赖项的规范。

{
  "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"
}

对于单任务格式作业,除了添加 format 字段外,JobSettings 数据结构保持不变。 不包含 TaskSettings 数组,并且任务设置仍保留在 JobSettings 数据结构的顶层定义。 无需对现有 API 客户端进行更改即可处理单任务格式作业。

表示 API 2.0 的单任务格式作业的示例 JSON 文档:

{
  "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 调用的指南、示例和所需更改。

在本部分中:

创建

若要通过 在作业 API 中创建新作业 操作(POST /jobs/create)创建单任务格式作业,无需更改现有客户端。

若要创建多任务格式作业,请使用 JobSettings 中的 tasks 字段指定每个任务的设置。 以下示例创建包含两个笔记本任务的作业。 此示例适用于 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
    }
  ]
}

运行提交

若要在作业 API 中通过创建和触发一次性运行操作 (POST /runs/submit) 提交单任务格式作业的一次性运行,无需更改现有客户端。

若要提交多任务格式作业的一次性运行,请使用 JobSettings 中的 tasks 字段指定每个任务的设置,包括群集。 提交多任务格式作业时,必须在任务级别设置群集,因为 runs submit 请求不支持共享作业群集。 有关指定多个任务的示例 JobSettings,请参阅创建

更新

若要在作业 API 中通过部分更新作业操作 (POST /jobs/update) 更新单任务格式作业,无需更改现有客户端。

若要更新多任务格式作业的设置,必须使用唯一 task_key 字段来标识新的 task 设置。 有关指定多个任务的示例 JobSettings,请参阅创建

重置

若要在作业 API 中通过覆盖作业的所有设置操作 (POST /jobs/reset) 覆盖单任务格式作业的设置,无需更改现有客户端。

若要覆盖多任务格式作业的设置,请指定具有 TaskSettings 数据结构数组的 JobSettings 数据结构。 有关指定多个任务的示例 JobSettings,请参阅创建

使用 更新 更改单个字段,而无需从单任务切换到多任务格式。

列出

对于单任务格式作业,无需进行客户端更改即可处理来自作业 API 中列出所有作业操作 (GET /jobs/list) 的响应。

对于多任务格式作业,大多数设置都在任务级别定义,而不是作业级别。 群集配置可以在任务或作业级别设置。 若要修改客户端以访问 Job 结构中返回的多任务格式作业的群集或任务设置:

以下示例演示包含单任务作业和多任务格式作业的响应。 此示例适用于 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"
    }
  ]
}

获取

对于单任务格式的作业,无需对客户端进行更改,就能够在作业 API 中处理来自 获取作业 操作(GET /jobs/get)的响应。

多任务格式作业返回包含任务设置的 task 数据结构数组。 如果需要访问任务级别详细信息,则需要修改客户端以循环访问 tasks 数组并提取必填字段。

下面显示了针对多任务格式作业的 Get API 调用的示例响应。 此示例适用于 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 中获取作业运行操作 (GET /jobs/runs/get) 的响应。

多任务格式作业运行的响应包含 TaskSettings 的数组。 检索每个任务的运行结果:

  • 依次处理每个任务。
  • 分析每个任务的 run_id
  • 使用 run_id 调用获取运行的输出操作 (GET /jobs/runs/get-output) 以获取关于每个任务的运行的详细信息。 下面是来自此请求的示例响应:
{
  "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"
}

运行获取输出

对于单任务格式作业,无需进行客户端更改即可处理来自作业 API 中获取运行的输出操作 (GET /jobs/runs/get-output) 的响应。

对于多任务格式作业,对父运行调用 Runs get output 会导致错误,因为运行输出仅适用于单个任务。 若要获取多任务格式作业的输出和元数据,请执行以下操作:

  • 调用获取运行的输出请求。
  • 循环访问响应中的子 run_id 字段。
  • 使用子 run_id 值调用 Runs get output

运行列表

对于单任务格式作业,无需进行客户端更改即可处理来自列出作业运行操作 (GET /jobs/runs/list) 的响应。

对于多任务格式作业,将返回空 tasks 数组。 将 run_id 传递到获取作业运行操作 (GET /jobs/runs/get) 以检索任务。 下面显示了多任务格式作业 Runs list API 调用的示例响应:

{
  "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
}