This is an automated email from the ASF dual-hosted git repository.
ayushtkn pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hive.git
The following commit(s) were added to refs/heads/master by this push:
new 6d4ff6d0f43 HIVE-30091: Fix K8s operator LLAP/TezAM replica resolution
when autoscaling is disabled (#6814)
6d4ff6d0f43 is described below
commit 6d4ff6d0f4389472ca116145f8e1faf007782692
Author: Tanishq Chugh <[email protected]>
AuthorDate: Fri Sep 25 04:05:07 2026 +0530
HIVE-30091: Fix K8s operator LLAP/TezAM replica resolution when autoscaling
is disabled (#6814)
* HIVE-30091: Fix K8s operator LLAP/TezAM replica resolution when
autoscaling is disabled
* Address copilot comments
* Rename method to clearAutoscalingState to avoid shadowing
---
.../autoscaling/HiveClusterAutoscaler.java | 19 ++++
.../operator/reconciler/HiveClusterReconciler.java | 112 ++++++++++++++-------
2 files changed, 92 insertions(+), 39 deletions(-)
diff --git
a/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/autoscaling/HiveClusterAutoscaler.java
b/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/autoscaling/HiveClusterAutoscaler.java
index f6016043fc6..5be325e4085 100644
---
a/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/autoscaling/HiveClusterAutoscaler.java
+++
b/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/autoscaling/HiveClusterAutoscaler.java
@@ -81,6 +81,25 @@ public static void setManagedReplicas(String namespace,
String clusterName,
MANAGED_REPLICAS.put(cacheKey(namespace, clusterName, component),
replicas);
}
+ /**
+ * Removes the autoscaler-managed replica count for a component. Used when
autoscaling is disabled so
+ * a pre-existing in-memory scale decision if any is cleared up.
+ */
+ public static void cleanupManagedReplicas(String namespace, String
clusterName, String component) {
+ MANAGED_REPLICAS.remove(cacheKey(namespace, clusterName, component));
+ }
+
+ /**
+ * Clears all in-memory autoscaling state for a component when autoscaling
is disabled.
+ */
+ public void resetComponentAutoscalingState(String namespace, String
clusterName, String component) {
+ String key = cacheKey(namespace, clusterName, component);
+ MANAGED_REPLICAS.remove(key);
+ pendingScaleDowns.remove(key);
+ autoscalers.remove(key);
+ lastScaleTimes.remove(key);
+ }
+
private record PendingScaleDown(int targetReplicas, Instant annotatedAt,
List<String> podsToDeregister) {}
private final BackgroundMetricsScraper bgScraper;
diff --git
a/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/reconciler/HiveClusterReconciler.java
b/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/reconciler/HiveClusterReconciler.java
index 557ebe99d54..ccb1390c90b 100644
---
a/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/reconciler/HiveClusterReconciler.java
+++
b/packaging/src/kubernetes/src/java/org/apache/hive/kubernetes/operator/reconciler/HiveClusterReconciler.java
@@ -162,6 +162,15 @@ public UpdateControl<HiveCluster> reconcile(HiveCluster
resource, Context<HiveCl
break;
}
+ boolean canEvaluateAutoscaling = (rescheduleSeconds == 0 &&
anyAutoscalingEnabled(resource.getSpec()));
+
+ HiveClusterAutoscaler scaler = autoscaler;
+ if (scaler == null && canEvaluateAutoscaling) {
+ scaler = getOrCreateAutoscaler(client);
+ }
+
+ resetAutoscalingStateForDisabledComponents(resource, scaler);
+
// --- Imperative LLAP cluster management ---
// Must also run while suspended: resolve*ReplicaCount() return 0 when
// spec.suspend() is set, and skipping the call would leave LLAP/TezAM
@@ -169,8 +178,7 @@ public UpdateControl<HiveCluster> reconcile(HiveCluster
resource, Context<HiveCl
reconcileLlapClusters(resource, client);
// --- Autoscaling evaluation (only when enabled and not suspended) ---
- if (rescheduleSeconds == 0 && anyAutoscalingEnabled(resource.getSpec())) {
- HiveClusterAutoscaler scaler = getOrCreateAutoscaler(client);
+ if (canEvaluateAutoscaling) {
HiveClusterAutoscaler.AutoscalingEvaluation eval =
scaler.evaluate(resource, client);
for (Map.Entry<String, Integer> entry : eval.patches().entrySet()) {
patchReplicas(client, resource, entry.getKey(), entry.getValue());
@@ -553,6 +561,42 @@ private HiveClusterAutoscaler
getOrCreateAutoscaler(KubernetesClient client) {
return autoscaler;
}
+ /**
+ * Clears autoscaling state for components with autoscaling disabled in spec.
+ */
+ private static void resetAutoscalingStateForDisabledComponents(HiveCluster
resource, HiveClusterAutoscaler scaler) {
+ HiveClusterSpec spec = resource.getSpec();
+ String ns = resource.getMetadata().getNamespace();
+ String clusterName = resource.getMetadata().getName();
+
+ if (!spec.hiveServer2().autoscaling().isEnabled()) {
+ clearAutoscalingState(scaler, ns, clusterName,
ConfigUtils.COMPONENT_HIVESERVER2);
+ }
+ if (spec.metastore().isEnabled() &&
!spec.metastore().autoscaling().isEnabled()) {
+ clearAutoscalingState(scaler, ns, clusterName,
ConfigUtils.COMPONENT_METASTORE);
+ }
+ for (var llap : spec.llapClusters()) {
+ if (!llap.isEnabled()) {
+ continue;
+ }
+ if (!llap.autoscaling().isEnabled()) {
+ clearAutoscalingState(scaler, ns, clusterName,
ConfigUtils.llapComponentKey(llap.name()));
+ }
+ if (spec.tezAm().isEnabled() && !llap.tezAm().autoscaling().isEnabled())
{
+ clearAutoscalingState(scaler, ns, clusterName,
ConfigUtils.tezAmComponentKey(llap.name()));
+ }
+ }
+ }
+
+ private static void clearAutoscalingState(HiveClusterAutoscaler scaler,
+ String namespace, String clusterName, String component) {
+ if (scaler != null) {
+ scaler.resetComponentAutoscalingState(namespace, clusterName, component);
+ } else {
+ HiveClusterAutoscaler.cleanupManagedReplicas(namespace, clusterName,
component);
+ }
+ }
+
private static boolean anyAutoscalingEnabled(HiveClusterSpec spec) {
if (spec.hiveServer2().autoscaling().isEnabled()) {
return true;
@@ -713,12 +757,12 @@ private int resolveLlapReplicaCount(HiveCluster resource,
return 0;
}
String componentKey = ConfigUtils.llapComponentKey(llapSpec.name());
- Integer managed = HiveClusterAutoscaler.getManagedReplicas(ns,
clusterName, componentKey);
- if (managed != null) {
- return managed;
- }
- // First reconcile before autoscaler runs: start at minReplicas if
autoscaling enabled
if (llapSpec.autoscaling().isEnabled()) {
+ Integer managed = HiveClusterAutoscaler.getManagedReplicas(ns,
clusterName, componentKey);
+ if (managed != null) {
+ return managed;
+ }
+ // First reconcile before autoscaler runs: start at minReplicas if
autoscaling enabled
return llapSpec.autoscaling().minReplicas();
}
return llapSpec.replicas();
@@ -734,21 +778,17 @@ private int resolveTezAmReplicaCount(HiveCluster resource,
return 0;
}
LlapSpec.LlapTezAmSpec tezAmSpec = llapSpec.tezAm();
- // Check if autoscaler has a managed value for this specific TezAM
String tezAmComponentKey = ConfigUtils.tezAmComponentKey(llapSpec.name());
- Integer tezAmManaged = HiveClusterAutoscaler.getManagedReplicas(ns,
clusterName, tezAmComponentKey);
- if (tezAmManaged != null) {
- return tezAmManaged;
- }
- // TezAM follows LLAP's autoscaling gate: only run if LLAP is running.
- String llapComponentKey = ConfigUtils.llapComponentKey(llapSpec.name());
- Integer llapManaged = HiveClusterAutoscaler.getManagedReplicas(ns,
clusterName, llapComponentKey);
- if (llapManaged != null && llapManaged == 0) {
- return 0;
+ // Check if autoscaler has a managed value for this specific TezAM
+ if (tezAmSpec.autoscaling().isEnabled()) {
+ Integer tezAmManaged = HiveClusterAutoscaler.getManagedReplicas(ns,
clusterName, tezAmComponentKey);
+ if (tezAmManaged != null) {
+ return tezAmManaged;
+ }
}
- if (llapSpec.autoscaling().isEnabled() && llapManaged == null
- && llapSpec.autoscaling().minReplicas() == 0) {
- // First reconcile before autoscaler runs: LLAP starts at 0, so TezAM
stays down too.
+
+ int llapDesired = resolveLlapReplicaCount(resource, llapSpec, ns,
clusterName);
+ if (llapDesired == 0) {
return 0;
}
if (tezAmSpec.autoscaling().isEnabled()) {
@@ -1012,35 +1052,29 @@ private void wakeCluster(HiveCluster resource) {
// the dependent resources (Deployments/StatefulSets) on the next reconcile
// and use these values for spec.replicas. We don't call patchReplicas()
// because the workloads may have been garbage-collected while suspended.
- // With autoscaling disabled the wake value is the spec's static replica
- // count — using minReplicas (0 by default) would pin the component to 0.
- int hs2Wake = spec.hiveServer2().autoscaling().isEnabled()
- ? Math.max(1, spec.hiveServer2().autoscaling().minReplicas())
- : spec.hiveServer2().replicas();
- HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.COMPONENT_HIVESERVER2, hs2Wake);
+ if (spec.hiveServer2().autoscaling().isEnabled()) {
+ HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.COMPONENT_HIVESERVER2,
+ Math.max(1, spec.hiveServer2().autoscaling().minReplicas()));
+ }
- if (spec.metastore().isEnabled() && spec.autoSuspend().includeMetastore())
{
- int hmsWake = spec.metastore().autoscaling().isEnabled()
- ? Math.max(1, spec.metastore().autoscaling().minReplicas())
- : spec.metastore().replicas();
- HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.COMPONENT_METASTORE, hmsWake);
+ if (spec.metastore().isEnabled() && spec.autoSuspend().includeMetastore()
+ && spec.metastore().autoscaling().isEnabled()) {
+ HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.COMPONENT_METASTORE,
+ Math.max(1, spec.metastore().autoscaling().minReplicas()));
}
for (var llap : spec.llapClusters()) {
- if (llap.isEnabled()) {
- int llapWake = llap.autoscaling().isEnabled()
- ? llap.autoscaling().minReplicas() : llap.replicas();
- HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.llapComponentKey(llap.name()), llapWake);
+ if (llap.isEnabled() && llap.autoscaling().isEnabled()) {
+ HiveClusterAutoscaler.setManagedReplicas(ns, name,
ConfigUtils.llapComponentKey(llap.name()),
+ llap.autoscaling().minReplicas());
}
}
if (spec.tezAm().isEnabled()) {
for (var llap : spec.llapClusters()) {
- if (llap.isEnabled()) {
- int tezWake = llap.tezAm().autoscaling().isEnabled()
- ? llap.tezAm().autoscaling().minReplicas() :
llap.tezAm().replicas();
+ if (llap.isEnabled() && llap.tezAm().autoscaling().isEnabled()) {
HiveClusterAutoscaler.setManagedReplicas(ns, name,
- ConfigUtils.tezAmComponentKey(llap.name()), tezWake);
+ ConfigUtils.tezAmComponentKey(llap.name()),
llap.tezAm().autoscaling().minReplicas());
}
}
}