jigneshjain25 commented on code in PR #74753:
URL: https://github.com/apache/airflow/pull/74753#discussion_r4327415162


##########
providers/google/docs/operators/cloud/dataproc.rst:
##########
@@ -186,6 +186,44 @@ You can use deferrable mode for this action in order to 
run the operator asynchr
     :start-after: [START how_to_cloud_dataproc_create_cluster_operator_async]
     :end-before: [END how_to_cloud_dataproc_create_cluster_operator_async]
 
+High Obtainability (HO) mode clusters
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+High Obtainability (HO) mode enables creating Dataproc clusters using abstract 
hardware requirements

Review Comment:
   Added direct links in `dataproc.rst` to the official Google Cloud 
documentation for [Dataproc High Obtainability 
mode](https://cloud.google.com/dataproc/docs/concepts/compute/high-obtainability)
 and the [FlexibleInstanceGroupConfig API 
reference](https://cloud.google.com/dataproc/docs/reference/rest/v1/ClusterConfig#FlexibleInstanceGroupConfig).



##########
providers/google/pyproject.toml:
##########
@@ -104,7 +104,7 @@ dependencies = [
     "google-cloud-dataflow-client>=0.12.0",
     "google-cloud-dataform>=0.10.0",
     "google-cloud-dataplex>=2.18.0",
-    "google-cloud-dataproc>=5.27.0",
+    "google-cloud-dataproc>=5.32.0",

Review Comment:
   Updated `uv.lock` with the `google-cloud-dataproc>=5.32.0` dependency bump 
and exact release package metadata and PyPI hashes.



##########
providers/google/tests/system/google/cloud/dataproc/example_dataproc_cluster_high_obtainability.py:
##########
@@ -0,0 +1,172 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Example Airflow DAG for a Dataproc High Obtainability (HO) mode cluster.
+
+In High Obtainability mode node groups are described by abstract requirements
+(``FlexibleInstanceGroupConfig``: number of instances, core count and hardware
+class) instead of concrete machine types. Dataproc resolves them into a ranked
+list of widely available machine families to minimize stockouts. HO clusters
+are always auto-zoned.
+
+The DAG creates an HO cluster, scales its primary workers through the
+authoritative ``config.worker_flexible_config.num_instances`` update path,
+scales the secondary workers through the legacy
+``config.secondary_worker_config.num_instances`` compatibility path (which the
+API keeps accepting for HO clusters), submits a Spark job and deletes the
+cluster.
+"""
+
+from __future__ import annotations
+
+import os
+from datetime import datetime
+
+from airflow.models.dag import DAG
+from airflow.providers.google.cloud.operators.dataproc import (
+    DataprocCreateClusterOperator,
+    DataprocDeleteClusterOperator,
+    DataprocSubmitJobOperator,
+    DataprocUpdateClusterOperator,
+    FlexibleInstanceGroupConfig,
+    flexible_scale_cluster_update,
+)
+
+try:
+    from airflow.sdk import TriggerRule
+except ImportError:
+    # Compatibility for Airflow < 3.1
+    from airflow.utils.trigger_rule import TriggerRule  # type: 
ignore[no-redef,attr-defined]
+
+from system.google import DEFAULT_GCP_SYSTEM_TEST_PROJECT_ID
+
+ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID", "default")
+DAG_ID = "dataproc_cluster_high_obtainability"
+PROJECT_ID = os.environ.get("SYSTEM_TESTS_GCP_PROJECT") or 
DEFAULT_GCP_SYSTEM_TEST_PROJECT_ID
+
+CLUSTER_NAME_BASE = f"cluster-{DAG_ID}".replace("_", "-")
+CLUSTER_NAME_FULL = CLUSTER_NAME_BASE + f"-{ENV_ID}".replace("_", "-")
+CLUSTER_NAME = CLUSTER_NAME_BASE if len(CLUSTER_NAME_FULL) >= 33 else 
CLUSTER_NAME_FULL
+REGION = "us-central1"
+
+# [START how_to_cloud_dataproc_create_ho_cluster_config]
+# Note: no machine types, disk types or zone are specified. HO clusters are
+# cluster-wide: master and primary workers must both use a flexible config.
+HO_CLUSTER_CONFIG = {
+    "master_flexible_config": FlexibleInstanceGroupConfig(
+        num_instances=1, core_count=4, hardware_class="STANDARD"
+    ),
+    # A plain dict with the same keys is accepted as well.
+    "worker_flexible_config": {
+        "num_instances": 2,
+        "core_count": 8,
+        "hardware_class": "PERFORMANCE",
+        "boot_disk_size_gb": 500,
+    },
+    "secondary_worker_flexible_config": {
+        "num_instances": 1,
+        "core_count": 8,
+        "hardware_class": "PERFORMANCE",
+    },
+    "software_config": {
+        "image_version": "2.2",
+    },
+}
+# [END how_to_cloud_dataproc_create_ho_cluster_config]
+
+SPARK_PI_JOB = {
+    "reference": {"project_id": PROJECT_ID},
+    "placement": {"cluster_name": CLUSTER_NAME},
+    "spark_job": {
+        "main_class": "org.apache.spark.examples.SparkPi",
+        "jar_file_uris": 
["file:///usr/lib/spark/examples/jars/spark-examples.jar"],
+        "args": ["10"],
+    },
+}
+
+with DAG(

Review Comment:
   The example DAG `dataproc_cluster_high_obtainability` was executed and 
verified end-to-end on GCP test project `dataproc-test-jnj` in `us-central1`.
   
   All tasks completed with `SUCCESS`:
   -  `create_ho_cluster`: SUCCESS (Cluster created with 1 master, 4 primary 
workers, and 1 secondary worker using 2 cores and 32GB pd-standard boot disk 
per instance)
   -  `scale_ho_cluster`: SUCCESS (Updated cluster in a single call with 
`config.worker_flexible_config.num_instances: 3` and 
`config.secondary_worker_flexible_config.num_instances: 0`)
   -  `spark_pi`: SUCCESS (SparkPi job completed successfully on the scaled 
cluster, outputting calculated Pi value)
   -  `delete_ho_cluster`: SUCCESS (Cluster cleanly torn down)



##########
providers/google/tests/system/google/cloud/dataproc/example_dataproc_cluster_high_obtainability.py:
##########
@@ -0,0 +1,172 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+"""Example Airflow DAG for a Dataproc High Obtainability (HO) mode cluster.
+
+In High Obtainability mode node groups are described by abstract requirements
+(``FlexibleInstanceGroupConfig``: number of instances, core count and hardware
+class) instead of concrete machine types. Dataproc resolves them into a ranked
+list of widely available machine families to minimize stockouts. HO clusters
+are always auto-zoned.
+
+The DAG creates an HO cluster, scales its primary workers through the
+authoritative ``config.worker_flexible_config.num_instances`` update path,
+scales the secondary workers through the legacy
+``config.secondary_worker_config.num_instances`` compatibility path (which the
+API keeps accepting for HO clusters), submits a Spark job and deletes the
+cluster.
+"""
+
+from __future__ import annotations
+
+import os
+from datetime import datetime
+
+from airflow.models.dag import DAG
+from airflow.providers.google.cloud.operators.dataproc import (
+    DataprocCreateClusterOperator,
+    DataprocDeleteClusterOperator,
+    DataprocSubmitJobOperator,
+    DataprocUpdateClusterOperator,
+    FlexibleInstanceGroupConfig,
+    flexible_scale_cluster_update,
+)
+
+try:
+    from airflow.sdk import TriggerRule
+except ImportError:
+    # Compatibility for Airflow < 3.1
+    from airflow.utils.trigger_rule import TriggerRule  # type: 
ignore[no-redef,attr-defined]
+
+from system.google import DEFAULT_GCP_SYSTEM_TEST_PROJECT_ID
+
+ENV_ID = os.environ.get("SYSTEM_TESTS_ENV_ID", "default")
+DAG_ID = "dataproc_cluster_high_obtainability"
+PROJECT_ID = os.environ.get("SYSTEM_TESTS_GCP_PROJECT") or 
DEFAULT_GCP_SYSTEM_TEST_PROJECT_ID
+
+CLUSTER_NAME_BASE = f"cluster-{DAG_ID}".replace("_", "-")
+CLUSTER_NAME_FULL = CLUSTER_NAME_BASE + f"-{ENV_ID}".replace("_", "-")
+CLUSTER_NAME = CLUSTER_NAME_BASE if len(CLUSTER_NAME_FULL) >= 33 else 
CLUSTER_NAME_FULL
+REGION = "us-central1"
+
+# [START how_to_cloud_dataproc_create_ho_cluster_config]
+# Note: no machine types, disk types or zone are specified. HO clusters are
+# cluster-wide: master and primary workers must both use a flexible config.
+HO_CLUSTER_CONFIG = {

Review Comment:
   Updated the example DAG to minimize resource consumption:
   - Configured 2 cores and 32GB boot disk per node across master, primary 
workers, and secondary workers.
   -  Converted to plain dictionaries instead of custom classes.
   -  Consolidated the scaling into a single `DataprocUpdateClusterOperator` 
call scaling `worker_flexible_config` to 3 and 
`secondary_worker_flexible_config` to 0 directly via `cluster` and 
`update_mask` without the helper function.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to