Skip to content

Commit 5ca100f

Browse files
author
wardli
committed
[Subtask]: In master-slave mode, each AMS should automatically senses the optimizer. #3929
1 parent 32d4087 commit 5ca100f

13 files changed

Lines changed: 50 additions & 654 deletions

File tree

amoro-ams/src/main/java/org/apache/amoro/server/AmoroManagementConf.java

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -116,34 +116,6 @@ public class AmoroManagementConf {
116116
"This setting controls whether to enable the AMS horizontal scaling feature, "
117117
+ "which is currently under development and testing.");
118118

119-
public static final ConfigOption<Integer> BUCKET_ID_TOTAL_COUNT =
120-
ConfigOptions.key("bucket-id.total-count")
121-
.intType()
122-
.defaultValue(100)
123-
.withDescription(
124-
"Total count of bucket IDs for assignment. Bucket IDs range from 1 to this value.");
125-
126-
public static final ConfigOption<Duration> NODE_OFFLINE_TIMEOUT =
127-
ConfigOptions.key("node-offline.timeout")
128-
.durationType()
129-
.defaultValue(Duration.ofMinutes(5))
130-
.withDescription(
131-
"Timeout duration to determine if a node is offline. After this duration, the node's bucket IDs will be reassigned.");
132-
133-
public static final ConfigOption<Duration> ASSIGN_INTERVAL =
134-
ConfigOptions.key("bucket-assign.interval")
135-
.durationType()
136-
.defaultValue(Duration.ofSeconds(60))
137-
.withDescription(
138-
"Interval for bucket assignment service to detect node changes and redistribute bucket IDs.");
139-
140-
public static final ConfigOption<Duration> BUCKET_TABLE_SYNC_INTERVAL =
141-
ConfigOptions.key("bucket-table-sync.interval")
142-
.durationType()
143-
.defaultValue(Duration.ofSeconds(60))
144-
.withDescription(
145-
"Interval for syncing tables assigned to bucket IDs in master-slave mode. Each node periodically loads tables from database based on its assigned bucket IDs.");
146-
147119
public static final ConfigOption<Duration> CATALOG_META_CACHE_EXPIRATION_INTERVAL =
148120
ConfigOptions.key("catalog-meta-cache.expiration-interval")
149121
.durationType()

amoro-ams/src/main/java/org/apache/amoro/server/AmoroServiceContainer.java

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
import org.apache.amoro.shade.thrift.org.apache.thrift.transport.TTransportException;
8282
import org.apache.amoro.shade.thrift.org.apache.thrift.transport.TTransportFactory;
8383
import org.apache.amoro.shade.thrift.org.apache.thrift.transport.layered.TFramedTransport;
84-
import org.apache.amoro.shade.zookeeper3.org.apache.curator.framework.CuratorFramework;
8584
import org.apache.amoro.utils.IcebergThreadPools;
8685
import org.apache.amoro.utils.JacksonUtil;
8786
import org.apache.commons.lang3.StringUtils;
@@ -273,43 +272,18 @@ public void startOptimizingService() throws Exception {
273272

274273
List<ActionCoordinator> actionCoordinators = defaultRuntimeFactory.supportedCoordinators();
275274

276-
// In master-slave mode, create BucketAssignStore and AmsAssignService
277-
BucketAssignStore bucketAssignStore = null;
278-
if (IS_MASTER_SLAVE_MODE && haContainer != null) {
279-
String clusterName = serviceConfig.getString(AmoroManagementConf.HA_CLUSTER_NAME);
280-
// Choose BucketAssignStore implementation based on HA container type
281-
CuratorFramework zkClient = null;
282-
if (haContainer instanceof org.apache.amoro.server.ha.ZkHighAvailabilityContainer) {
283-
org.apache.amoro.server.ha.ZkHighAvailabilityContainer zkHaContainer =
284-
(org.apache.amoro.server.ha.ZkHighAvailabilityContainer) haContainer;
285-
zkClient = zkHaContainer.getZkClient();
286-
bucketAssignStore = new ZkBucketAssignStore(zkClient, clusterName);
287-
LOG.info("Using ZkBucketAssignStore for master-slave mode");
288-
} else if (haContainer
289-
instanceof org.apache.amoro.server.ha.DataBaseHighAvailabilityContainer) {
290-
bucketAssignStore = new DatabaseBucketAssignStore(clusterName);
291-
LOG.info("Using DatabaseBucketAssignStore for master-slave mode");
292-
} else {
293-
LOG.warn(
294-
"Unsupported HA container type for master-slave mode: {}",
295-
haContainer.getClass().getName());
296-
}
297-
298-
// Create and start AmsAssignService for bucket assignment
299-
if (bucketAssignStore != null) {
300-
amsAssignService = new AmsAssignService(haContainer, serviceConfig, zkClient);
301-
amsAssignService.start();
302-
LOG.info("AmsAssignService started for master-slave mode");
303-
}
304-
}
305-
306275
tableService =
307276
new DefaultTableService(
308277
serviceConfig, catalogManager, defaultRuntimeFactory, haContainer, bucketAssignStore);
309278
processService = new ProcessService(tableService, actionCoordinators, executeEngineManager);
310279
optimizingService =
311280
new DefaultOptimizingService(
312-
serviceConfig, catalogManager, optimizerManager, tableService, bucketAssignStore, haContainer);
281+
serviceConfig,
282+
catalogManager,
283+
optimizerManager,
284+
tableService,
285+
bucketAssignStore,
286+
haContainer);
313287

314288
LOG.info("Setting up AMS table executors...");
315289
InlineTableExecutors.getInstance().setup(tableService, serviceConfig);
@@ -693,12 +667,6 @@ private void initContainerConfig() {
693667
containerProperties.putIfAbsent(
694668
OptimizerProperties.AMS_OPTIMIZER_URI,
695669
AmsUtil.getAMSThriftAddress(serviceConfig, Constants.THRIFT_OPTIMIZING_SERVICE_NAME));
696-
// Add master-slave mode flag to container properties
697-
// Read from serviceConfig directly since IS_MASTER_SLAVE_MODE is set after
698-
// initContainerConfig()
699-
if (serviceConfig.getBoolean(USE_MASTER_SLAVE_MODE)) {
700-
containerProperties.put(OptimizerProperties.OPTIMIZER_MASTER_SLAVE_MODE, "true");
701-
}
702670
// put addition system properties
703671
container.setProperties(containerProperties);
704672
containerList.add(container);

amoro-ams/src/main/java/org/apache/amoro/server/DatabaseBucketAssignStore.java

Lines changed: 0 additions & 178 deletions
This file was deleted.

amoro-ams/src/main/java/org/apache/amoro/server/DefaultOptimizingService.java

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.apache.amoro.resource.ResourceType;
4040
import org.apache.amoro.server.catalog.CatalogManager;
4141
import org.apache.amoro.server.dashboard.model.OptimizerResourceInfo;
42+
import org.apache.amoro.server.ha.HighAvailabilityContainer;
4243
import org.apache.amoro.server.manager.AbstractOptimizerContainer;
4344
import org.apache.amoro.server.optimizing.OptimizingProcess;
4445
import org.apache.amoro.server.optimizing.OptimizingQueue;
@@ -56,8 +57,6 @@
5657
import org.apache.amoro.server.resource.QuotaProvider;
5758
import org.apache.amoro.server.table.DefaultTableRuntime;
5859
import org.apache.amoro.server.table.RuntimeHandlerChain;
59-
import org.apache.amoro.server.BucketAssignStore;
60-
import org.apache.amoro.server.ha.HighAvailabilityContainer;
6160
import org.apache.amoro.server.table.TableService;
6261
import org.apache.amoro.shade.guava32.com.google.common.base.Preconditions;
6362
import org.apache.amoro.shade.guava32.com.google.common.collect.Sets;
@@ -126,15 +125,6 @@ public class DefaultOptimizingService extends StatedPersistentBase
126125
private final HighAvailabilityContainer haContainer;
127126
private final boolean isMasterSlaveMode;
128127

129-
public DefaultOptimizingService(
130-
Configurations serviceConfig,
131-
CatalogManager catalogManager,
132-
OptimizerManager optimizerManager,
133-
TableService tableService,
134-
BucketAssignStore bucketAssignStore) {
135-
this(serviceConfig, catalogManager, optimizerManager, tableService, bucketAssignStore, null);
136-
}
137-
138128
public DefaultOptimizingService(
139129
Configurations serviceConfig,
140130
CatalogManager catalogManager,
@@ -579,14 +569,23 @@ public void run() {
579569
// Use 1/4 of optimizerTouchTimeout as sync interval (default ~30 seconds), used for
580570
// master-slave follower sync.
581571
long syncInterval = Math.max(5000, optimizerTouchTimeout / 4);
572+
// In non-master-slave mode, this node is always the leader.
573+
boolean wasLeader = !isMasterSlaveMode;
582574
while (!stopped) {
583575
try {
584-
if (isMasterSlaveMode && (haContainer == null || !haContainer.hasLeadership())) {
585-
// Not leader: let subclass handle follower state (e.g. sync optimizer list from DB)
586-
onFollowerTick(syncInterval);
587-
} else {
576+
boolean isLeader = !isMasterSlaveMode || haContainer.hasLeadership();
577+
if (!wasLeader && isLeader) {
578+
// Follower → Leader transition: subclass takes over monitoring of inherited optimizers.
579+
onBecomeLeader();
580+
}
581+
wasLeader = isLeader;
582+
583+
if (isLeader) {
588584
T keepingTask = suspendingQueue.take();
589585
this.processTask(keepingTask);
586+
} else {
587+
// Not leader: let subclass handle follower state (e.g. sync optimizer list from DB)
588+
onFollowerTick(syncInterval);
590589
}
591590
} catch (InterruptedException ignored) {
592591
} catch (Throwable t) {
@@ -600,6 +599,8 @@ public void run() {
600599
protected void onFollowerTick(long syncInterval) throws InterruptedException {
601600
Thread.sleep(syncInterval);
602601
}
602+
603+
protected void onBecomeLeader() {}
603604
}
604605

605606
private class OptimizerKeeper extends AbstractKeeper<OptimizerKeepingTask> {
@@ -639,6 +640,17 @@ protected void onFollowerTick(long syncInterval) throws InterruptedException {
639640
Thread.sleep(syncInterval);
640641
}
641642

643+
@Override
644+
protected void onBecomeLeader() {
645+
LOG.info(
646+
"Became leader, starting heartbeat monitoring for {} inherited optimizers",
647+
authOptimizers.size());
648+
// All optimizers in authOptimizers were loaded from DB by the follower sync loop.
649+
// Their touchTime reflects the latest DB-persisted heartbeat, which is the correct
650+
// baseline for the new leader's expiry detection.
651+
authOptimizers.values().forEach(this::keepInTouch);
652+
}
653+
642654
/**
643655
* Load optimizer information from database. This is used in master-slave mode for follower
644656
* nodes to sync optimizer state from database. This method performs incremental updates by

0 commit comments

Comments
 (0)