You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by cs...@apache.org on 2023/05/05 12:43:07 UTC
[accumulo] branch 2.1 updated: Reuse already read lastLocation information during location updates (#3331)
This is an automated email from the ASF dual-hosted git repository.
cshannon pushed a commit to branch 2.1
in repository https://gitbox.apache.org/repos/asf/accumulo.git
The following commit(s) were added to refs/heads/2.1 by this push:
new 25959b438c Reuse already read lastLocation information during location updates (#3331)
25959b438c is described below
commit 25959b438c75bc858efcae1b6652a55cc336e777
Author: Christopher L. Shannon <ch...@gmail.com>
AuthorDate: Fri May 5 08:43:01 2023 -0400
Reuse already read lastLocation information during location updates (#3331)
This change will reuse the previously read lastLocation information when
ManagerMetadataUtil updates last location to prevent unnecessary
metadata reads.
This closes #3301
---
.../core/metadata/schema/TabletMetadata.java | 10 ++
.../accumulo/server/manager/state/Assignment.java | 14 ++-
.../server/manager/state/MetaDataStateStore.java | 8 +-
.../server/manager/state/UnassignedTablet.java | 84 +++++++++++++++++
.../server/manager/state/ZooTabletStateStore.java | 8 +-
.../accumulo/server/util/ManagerMetadataUtil.java | 14 +--
.../manager/state/RootTabletStateStoreTest.java | 4 +-
.../server/util/ManagerMetadataUtilTest.java | 102 +++++++++++++++++++++
.../java/org/apache/accumulo/manager/Manager.java | 9 +-
.../accumulo/manager/TabletGroupWatcher.java | 51 ++++++-----
.../apache/accumulo/tserver/AssignmentHandler.java | 3 +-
.../accumulo/test/functional/SplitRecoveryIT.java | 2 +-
.../apache/accumulo/test/manager/MergeStateIT.java | 2 +-
.../accumulo/test/performance/NullTserver.java | 2 +-
14 files changed, 265 insertions(+), 48 deletions(-)
diff --git a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java
index 2fb16fb092..323f0cb142 100644
--- a/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java
+++ b/core/src/main/java/org/apache/accumulo/core/metadata/schema/TabletMetadata.java
@@ -192,6 +192,16 @@ public class TabletMetadata {
return Objects.hash(tServerInstance, lt);
}
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(32);
+ sb.append("Location [");
+ sb.append("server=").append(tServerInstance);
+ sb.append(", type=").append(lt);
+ sb.append("]");
+ return sb.toString();
+ }
+
public static Location last(TServerInstance instance) {
return new Location(instance, LocationType.LAST);
}
diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/Assignment.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/Assignment.java
index a9e52d1741..c59dac90c0 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/Assignment.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/Assignment.java
@@ -20,13 +20,21 @@ package org.apache.accumulo.server.manager.state;
import org.apache.accumulo.core.dataImpl.KeyExtent;
import org.apache.accumulo.core.metadata.TServerInstance;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
+
+import com.google.common.base.Preconditions;
public class Assignment {
- public KeyExtent tablet;
- public TServerInstance server;
+ public final KeyExtent tablet;
+ public final TServerInstance server;
+ public final Location lastLocation;
- public Assignment(KeyExtent tablet, TServerInstance server) {
+ public Assignment(KeyExtent tablet, TServerInstance server, Location lastLocation) {
+ Preconditions.checkArgument(
+ lastLocation == null || lastLocation.getType() == TabletMetadata.LocationType.LAST);
this.tablet = tablet;
this.server = server;
+ this.lastLocation = lastLocation;
}
}
diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java
index 680f4d1db9..bb27b32cda 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/MetaDataStateStore.java
@@ -63,8 +63,8 @@ class MetaDataStateStore implements TabletStateStore {
for (Assignment assignment : assignments) {
TabletMutator tabletMutator = tabletsMutator.mutateTablet(assignment.tablet);
tabletMutator.putLocation(Location.current(assignment.server));
- ManagerMetadataUtil.updateLastForAssignmentMode(context, ample, tabletMutator,
- assignment.tablet, assignment.server);
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, assignment.server,
+ assignment.lastLocation);
tabletMutator.deleteLocation(Location.future(assignment.server));
tabletMutator.deleteSuspension();
tabletMutator.mutate();
@@ -107,8 +107,8 @@ class MetaDataStateStore implements TabletStateStore {
for (TabletLocationState tls : tablets) {
TabletMutator tabletMutator = tabletsMutator.mutateTablet(tls.extent);
if (tls.current != null) {
- ManagerMetadataUtil.updateLastForAssignmentMode(context, ample, tabletMutator, tls.extent,
- tls.current.getServerInstance());
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator,
+ tls.current.getServerInstance(), tls.last);
tabletMutator.deleteLocation(tls.current);
if (logsForDeadServers != null) {
List<Path> logs = logsForDeadServers.get(tls.current.getServerInstance());
diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/UnassignedTablet.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/UnassignedTablet.java
new file mode 100644
index 0000000000..6f57d7d563
--- /dev/null
+++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/UnassignedTablet.java
@@ -0,0 +1,84 @@
+/*
+ * 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
+ *
+ * https://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.
+ */
+package org.apache.accumulo.server.manager.state;
+
+import java.util.Objects;
+
+import org.apache.accumulo.core.metadata.TServerInstance;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
+
+import com.google.common.base.Preconditions;
+
+public class UnassignedTablet {
+ private final Location location;
+ private final Location lastLocation;
+
+ public UnassignedTablet(Location location, Location lastLocation) {
+ Preconditions.checkArgument(
+ lastLocation == null || lastLocation.getType() == TabletMetadata.LocationType.LAST);
+ this.location = location;
+ this.lastLocation = lastLocation;
+ }
+
+ public Location getLocation() {
+ return location;
+ }
+
+ public Location getLastLocation() {
+ return lastLocation;
+ }
+
+ public TServerInstance getServerInstance() {
+ return location != null ? location.getServerInstance() : null;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ UnassignedTablet that = (UnassignedTablet) o;
+ return Objects.equals(location, that.location)
+ && Objects.equals(lastLocation, that.lastLocation);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(location, lastLocation);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("UnassignedTablet [").append("location:");
+ if (location != null) {
+ sb.append(location.getType()).append("=").append(location.getServerInstance());
+ }
+ sb.append(", lastLocation:");
+ if (lastLocation != null) {
+ sb.append(lastLocation.getType()).append("=").append(lastLocation.getServerInstance());
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+}
diff --git a/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java b/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java
index 0930b6c34f..ae7643d32d 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/manager/state/ZooTabletStateStore.java
@@ -138,8 +138,8 @@ class ZooTabletStateStore implements TabletStateStore {
TabletMutator tabletMutator = ample.mutateTablet(assignment.tablet);
tabletMutator.putLocation(Location.current(assignment.server));
- ManagerMetadataUtil.updateLastForAssignmentMode(context, ample, tabletMutator,
- assignment.tablet, assignment.server);
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, assignment.server,
+ assignment.lastLocation);
tabletMutator.deleteLocation(Location.future(assignment.server));
tabletMutator.mutate();
@@ -161,8 +161,8 @@ class ZooTabletStateStore implements TabletStateStore {
tabletMutator.deleteLocation(Location.future(futureOrCurrent));
tabletMutator.deleteLocation(Location.current(futureOrCurrent));
- ManagerMetadataUtil.updateLastForAssignmentMode(context, ample, tabletMutator, tls.extent,
- futureOrCurrent);
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, futureOrCurrent,
+ tls.last);
if (logsForDeadServers != null) {
List<Path> logs = logsForDeadServers.get(futureOrCurrent);
if (logs != null) {
diff --git a/server/base/src/main/java/org/apache/accumulo/server/util/ManagerMetadataUtil.java b/server/base/src/main/java/org/apache/accumulo/server/util/ManagerMetadataUtil.java
index e3d8ff63a6..c042ece5e6 100644
--- a/server/base/src/main/java/org/apache/accumulo/server/util/ManagerMetadataUtil.java
+++ b/server/base/src/main/java/org/apache/accumulo/server/util/ManagerMetadataUtil.java
@@ -64,6 +64,8 @@ import org.apache.zookeeper.KeeperException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.base.Preconditions;
+
public class ManagerMetadataUtil {
private static final Logger log = LoggerFactory.getLogger(ManagerMetadataUtil.class);
@@ -253,18 +255,18 @@ public class ManagerMetadataUtil {
* last location if needed and set the new last location
*
* @param context The server context
- * @param ample The metadata persistence layer
* @param tabletMutator The mutator being built
- * @param extent The tablet extent
* @param location The new location
+ * @param lastLocation The previous last location, which may be null
*/
- public static void updateLastForAssignmentMode(ClientContext context, Ample ample,
- Ample.TabletMutator tabletMutator, KeyExtent extent, TServerInstance location) {
+ public static void updateLastForAssignmentMode(ClientContext context,
+ Ample.TabletMutator tabletMutator, TServerInstance location, Location lastLocation) {
+ Preconditions.checkArgument(
+ lastLocation == null || lastLocation.getType() == TabletMetadata.LocationType.LAST);
+
// if the location mode is assignment, then preserve the current location in the last
// location value
if ("assignment".equals(context.getConfiguration().get(Property.TSERV_LAST_LOCATION_MODE))) {
- TabletMetadata lastMetadata = ample.readTablet(extent, TabletMetadata.ColumnType.LAST);
- Location lastLocation = (lastMetadata == null ? null : lastMetadata.getLast());
ManagerMetadataUtil.updateLocation(tabletMutator, lastLocation, Location.last(location));
}
}
diff --git a/server/base/src/test/java/org/apache/accumulo/server/manager/state/RootTabletStateStoreTest.java b/server/base/src/test/java/org/apache/accumulo/server/manager/state/RootTabletStateStoreTest.java
index e5ba3fec83..a6fdda4a0b 100644
--- a/server/base/src/test/java/org/apache/accumulo/server/manager/state/RootTabletStateStoreTest.java
+++ b/server/base/src/test/java/org/apache/accumulo/server/manager/state/RootTabletStateStoreTest.java
@@ -98,7 +98,7 @@ public class RootTabletStateStoreTest {
String sessionId = "this is my unique session data";
TServerInstance server =
new TServerInstance(HostAndPort.fromParts("127.0.0.1", 10000), sessionId);
- List<Assignment> assignments = Collections.singletonList(new Assignment(root, server));
+ List<Assignment> assignments = Collections.singletonList(new Assignment(root, server, null));
tstore.setFutureLocations(assignments);
int count = 0;
for (TabletLocationState location : tstore) {
@@ -135,7 +135,7 @@ public class RootTabletStateStoreTest {
assertEquals(count, 1);
KeyExtent notRoot = new KeyExtent(TableId.of("0"), null, null);
- final var assignmentList = List.of(new Assignment(notRoot, server));
+ final var assignmentList = List.of(new Assignment(notRoot, server, null));
assertThrows(IllegalArgumentException.class, () -> tstore.setLocations(assignmentList));
assertThrows(IllegalArgumentException.class, () -> tstore.setFutureLocations(assignmentList));
diff --git a/server/base/src/test/java/org/apache/accumulo/server/util/ManagerMetadataUtilTest.java b/server/base/src/test/java/org/apache/accumulo/server/util/ManagerMetadataUtilTest.java
new file mode 100644
index 0000000000..748dffaa65
--- /dev/null
+++ b/server/base/src/test/java/org/apache/accumulo/server/util/ManagerMetadataUtilTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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
+ *
+ * https://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.
+ */
+package org.apache.accumulo.server.util;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+import org.apache.accumulo.core.clientImpl.ClientContext;
+import org.apache.accumulo.core.conf.AccumuloConfiguration;
+import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.core.metadata.TServerInstance;
+import org.apache.accumulo.core.metadata.schema.Ample;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
+import org.easymock.EasyMock;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+public class ManagerMetadataUtilTest {
+
+ private AccumuloConfiguration conf;
+ private ClientContext context;
+ private Ample.TabletMutator tabletMutator;
+ private final TServerInstance server1 = new TServerInstance("127.0.0.1:10000", 0);
+ private final Location last1 = Location.last(server1);
+ private final TServerInstance server2 = new TServerInstance("127.0.0.2:10000", 1);
+ private final Location last2 = Location.last(server2);
+
+ @BeforeEach
+ public void before() {
+ conf = EasyMock.createMock(AccumuloConfiguration.class);
+ EasyMock.expect(conf.get(Property.TSERV_LAST_LOCATION_MODE)).andReturn("assignment");
+ context = EasyMock.createMock(ClientContext.class);
+ EasyMock.expect(context.getConfiguration()).andReturn(conf).once();
+ tabletMutator = EasyMock.createMock(Ample.TabletMutator.class);
+ }
+
+ @Test
+ public void testUpdateLastForAssignmentModeNullLastLocation() {
+ // Expect a put of last1 as the previous value
+ EasyMock.expect(tabletMutator.putLocation(last1)).andReturn(tabletMutator).once();
+ EasyMock.replay(conf, context, tabletMutator);
+
+ // Pass in a null last location value. There should be a call to
+ // tabletMutator.putLocation of last 1 but no deletion as lastLocation is null
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, server1, null);
+ EasyMock.verify(conf, context, tabletMutator);
+ }
+
+ @Test
+ public void testUpdateLastForAssignModeInvalidType() {
+ assertThrows(IllegalArgumentException.class, () -> {
+ // Should throw an IllegalArgumentException as the lastLocation is not LocationType.LAST
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, server1,
+ Location.current(server1));
+ });
+ }
+
+ @Test
+ public void testUpdateLastForAssignModeLastLocationSame() {
+ EasyMock.replay(conf, context, tabletMutator);
+
+ // Pass in a last location value that matches the new value of server 1
+ // There should be no call to tabletMutator.putLocation or tabletMutator.deleteLocation
+ // as the locations are equal so no expects() are defined and any method calls would
+ // throw an error
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, server1, last1);
+ EasyMock.verify(conf, context, tabletMutator);
+ }
+
+ @Test
+ public void testUpdateLastForAssignModeLastLocationDifferent() {
+ // Expect a delete of last1 as we are providing that as the previous last location
+ // which is different from server 2 location
+ EasyMock.expect(tabletMutator.deleteLocation(last1)).andReturn(tabletMutator).once();
+ EasyMock.expect(tabletMutator.putLocation(last2)).andReturn(tabletMutator).once();
+
+ EasyMock.replay(conf, context, tabletMutator);
+
+ // Pass in last1 as the last location value.
+ // There should be no read from Ample as we provided a value as an argument
+ // There should be a call to tabletMutator.putLocation and tabletMutator.deleteLocation
+ // as the last location is being updated as last1 does not match server 2
+ ManagerMetadataUtil.updateLastForAssignmentMode(context, tabletMutator, server2, last1);
+ EasyMock.verify(conf, context, tabletMutator);
+ }
+
+}
diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/Manager.java b/server/manager/src/main/java/org/apache/accumulo/manager/Manager.java
index 69fceb3b14..2beca9cd42 100644
--- a/server/manager/src/main/java/org/apache/accumulo/manager/Manager.java
+++ b/server/manager/src/main/java/org/apache/accumulo/manager/Manager.java
@@ -130,6 +130,7 @@ import org.apache.accumulo.server.manager.state.MergeInfo;
import org.apache.accumulo.server.manager.state.MergeState;
import org.apache.accumulo.server.manager.state.TabletServerState;
import org.apache.accumulo.server.manager.state.TabletStateStore;
+import org.apache.accumulo.server.manager.state.UnassignedTablet;
import org.apache.accumulo.server.rpc.HighlyAvailableServiceWrapper;
import org.apache.accumulo.server.rpc.ServerAddress;
import org.apache.accumulo.server.rpc.TServerUtils;
@@ -1805,9 +1806,11 @@ public class Manager extends AbstractServer
}
void getAssignments(SortedMap<TServerInstance,TabletServerStatus> currentStatus,
- Map<KeyExtent,TServerInstance> unassigned, Map<KeyExtent,TServerInstance> assignedOut) {
- AssignmentParamsImpl params =
- AssignmentParamsImpl.fromThrift(currentStatus, unassigned, assignedOut);
+ Map<KeyExtent,UnassignedTablet> unassigned, Map<KeyExtent,TServerInstance> assignedOut) {
+ AssignmentParamsImpl params = AssignmentParamsImpl.fromThrift(currentStatus,
+ unassigned.entrySet().stream().collect(HashMap::new,
+ (m, e) -> m.put(e.getKey(), e.getValue().getServerInstance()), Map::putAll),
+ assignedOut);
tabletBalancer.getAssignments(params);
}
}
diff --git a/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java b/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java
index 593d09438f..69bcfd03c0 100644
--- a/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java
+++ b/server/manager/src/main/java/org/apache/accumulo/manager/TabletGroupWatcher.java
@@ -74,6 +74,7 @@ import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.Fu
import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.ServerColumnFamily;
import org.apache.accumulo.core.metadata.schema.MetadataSchema.TabletsSection.TabletColumnFamily;
import org.apache.accumulo.core.metadata.schema.MetadataTime;
+import org.apache.accumulo.core.metadata.schema.TabletMetadata.Location;
import org.apache.accumulo.core.security.Authorizations;
import org.apache.accumulo.core.tabletserver.thrift.NotServingTabletException;
import org.apache.accumulo.core.util.threads.Threads.AccumuloDaemonThread;
@@ -93,6 +94,7 @@ import org.apache.accumulo.server.manager.state.DistributedStoreException;
import org.apache.accumulo.server.manager.state.MergeInfo;
import org.apache.accumulo.server.manager.state.MergeState;
import org.apache.accumulo.server.manager.state.TabletStateStore;
+import org.apache.accumulo.server.manager.state.UnassignedTablet;
import org.apache.accumulo.server.tablets.TabletTime;
import org.apache.accumulo.server.util.MetadataTableUtil;
import org.apache.hadoop.fs.Path;
@@ -145,7 +147,7 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
private final List<Assignment> assigned = new ArrayList<>();
private final List<TabletLocationState> assignedToDeadServers = new ArrayList<>();
private final List<TabletLocationState> suspendedToGoneServers = new ArrayList<>();
- private final Map<KeyExtent,TServerInstance> unassigned = new HashMap<>();
+ private final Map<KeyExtent,UnassignedTablet> unassigned = new HashMap<>();
private final Map<TServerInstance,List<Path>> logsForDeadServers = new TreeMap<>();
// read only lists of tablet servers
private final SortedMap<TServerInstance,TabletServerStatus> currentTServers;
@@ -240,7 +242,7 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
return mStats != null ? mStats : new MergeStats(new MergeInfo());
});
TabletGoalState goal = manager.getGoalState(tls, mergeStats.getMergeInfo());
- TServerInstance location = tls.getServer();
+ Location location = tls.getLocation();
TabletState state = tls.getState(currentTServers.keySet());
TabletLogger.missassigned(tls.extent, goal.toString(), state.toString(),
@@ -271,7 +273,7 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
}
switch (state) {
case HOSTED:
- if (location.equals(manager.migrations.get(tls.extent))) {
+ if (location.getServerInstance().equals(manager.migrations.get(tls.extent))) {
manager.migrations.remove(tls.extent);
}
break;
@@ -282,11 +284,11 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
hostSuspendedTablet(tLists, tls, location, tableConf);
break;
case UNASSIGNED:
- hostUnassignedTablet(tLists, tls.extent, location);
+ hostUnassignedTablet(tLists, tls.extent, new UnassignedTablet(location, tls.last));
break;
case ASSIGNED:
// Send another reminder
- tLists.assigned.add(new Assignment(tls.extent, tls.getFutureServer()));
+ tLists.assigned.add(new Assignment(tls.extent, tls.getFutureServer(), tls.last));
break;
}
} else {
@@ -303,7 +305,8 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
unassignDeadTablet(tLists, tls, wals);
break;
case HOSTED:
- TServerConnection client = manager.tserverSet.getConnection(location);
+ TServerConnection client =
+ manager.tserverSet.getConnection(location.getServerInstance());
if (client != null) {
client.unloadTablet(manager.managerLock, tls.extent, goal.howUnload(),
manager.getSteadyTime());
@@ -381,25 +384,25 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
}
private void hostUnassignedTablet(TabletLists tLists, KeyExtent tablet,
- TServerInstance location) {
+ UnassignedTablet unassignedTablet) {
// maybe it's a finishing migration
TServerInstance dest = manager.migrations.get(tablet);
if (dest != null) {
// if destination is still good, assign it
if (tLists.destinations.containsKey(dest)) {
- tLists.assignments.add(new Assignment(tablet, dest));
+ tLists.assignments.add(new Assignment(tablet, dest, unassignedTablet.getLastLocation()));
} else {
// get rid of this migration
manager.migrations.remove(tablet);
- tLists.unassigned.put(tablet, location);
+ tLists.unassigned.put(tablet, unassignedTablet);
}
} else {
- tLists.unassigned.put(tablet, location);
+ tLists.unassigned.put(tablet, unassignedTablet);
}
}
- private void hostSuspendedTablet(TabletLists tLists, TabletLocationState tls,
- TServerInstance location, TableConfiguration tableConf) {
+ private void hostSuspendedTablet(TabletLists tLists, TabletLocationState tls, Location location,
+ TableConfiguration tableConf) {
if (manager.getSteadyTime() - tls.suspend.suspensionTime
< tableConf.getTimeInMillis(Property.TABLE_SUSPEND_DURATION)) {
// Tablet is suspended. See if its tablet server is back.
@@ -415,20 +418,20 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
// Old tablet server is back. Return this tablet to its previous owner.
if (returnInstance != null) {
- tLists.assignments.add(new Assignment(tls.extent, returnInstance));
+ tLists.assignments.add(new Assignment(tls.extent, returnInstance, tls.last));
}
// else - tablet server not back. Don't ask for a new assignment right now.
} else {
// Treat as unassigned, ask for a new assignment.
- tLists.unassigned.put(tls.extent, location);
+ tLists.unassigned.put(tls.extent, new UnassignedTablet(location, tls.last));
}
}
- private void hostDeadTablet(TabletLists tLists, TabletLocationState tls, TServerInstance location,
+ private void hostDeadTablet(TabletLists tLists, TabletLocationState tls, Location location,
WalStateManager wals) throws WalMarkerException {
tLists.assignedToDeadServers.add(tls);
- if (location.equals(manager.migrations.get(tls.extent))) {
+ if (location.getServerInstance().equals(manager.migrations.get(tls.extent))) {
manager.migrations.remove(tls.extent);
}
TServerInstance tserver = tls.futureOrCurrentServer();
@@ -901,7 +904,7 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
}
private void getAssignmentsFromBalancer(TabletLists tLists,
- Map<KeyExtent,TServerInstance> unassigned) {
+ Map<KeyExtent,UnassignedTablet> unassigned) {
if (!tLists.currentTServers.isEmpty()) {
Map<KeyExtent,TServerInstance> assignedOut = new HashMap<>();
manager.getAssignments(tLists.currentTServers, unassigned, assignedOut);
@@ -915,16 +918,19 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
continue;
}
- TServerInstance lastLocation = unassigned.get(assignment.getKey());
- if (lastLocation != null
- && !assignment.getValue().getHostPort().equals(lastLocation.getHostPort())) {
+ final UnassignedTablet unassignedTablet = unassigned.get(assignment.getKey());
+ final TServerInstance serverInstance =
+ unassignedTablet != null ? unassignedTablet.getServerInstance() : null;
+ if (serverInstance != null
+ && !assignment.getValue().getHostPort().equals(serverInstance.getHostPort())) {
Manager.log.warn(
"balancer assigned {} to {} which is not the suggested location of {}",
assignment.getKey(), assignment.getValue().getHostPort(),
- lastLocation.getHostPort());
+ serverInstance.getHostPort());
}
- tLists.assignments.add(new Assignment(assignment.getKey(), assignment.getValue()));
+ tLists.assignments.add(new Assignment(assignment.getKey(), assignment.getValue(),
+ unassignedTablet != null ? unassignedTablet.getLastLocation() : null));
}
} else {
Manager.log.warn(
@@ -971,4 +977,5 @@ abstract class TabletGroupWatcher extends AccumuloDaemonThread {
}
}
}
+
}
diff --git a/server/tserver/src/main/java/org/apache/accumulo/tserver/AssignmentHandler.java b/server/tserver/src/main/java/org/apache/accumulo/tserver/AssignmentHandler.java
index 1c629a321a..8b4f117a21 100644
--- a/server/tserver/src/main/java/org/apache/accumulo/tserver/AssignmentHandler.java
+++ b/server/tserver/src/main/java/org/apache/accumulo/tserver/AssignmentHandler.java
@@ -181,7 +181,8 @@ class AssignmentHandler implements Runnable {
&& !tablet.minorCompactNow(MinorCompactionReason.RECOVERY)) {
throw new RuntimeException("Minor compaction after recovery fails for " + extent);
}
- Assignment assignment = new Assignment(extent, server.getTabletSession());
+ Assignment assignment =
+ new Assignment(extent, server.getTabletSession(), tabletMetadata.getLast());
TabletStateStore.setLocation(server.getContext(), assignment);
synchronized (server.openingTablets) {
diff --git a/test/src/main/java/org/apache/accumulo/test/functional/SplitRecoveryIT.java b/test/src/main/java/org/apache/accumulo/test/functional/SplitRecoveryIT.java
index c27f9fd570..7b5b59accc 100644
--- a/test/src/main/java/org/apache/accumulo/test/functional/SplitRecoveryIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/functional/SplitRecoveryIT.java
@@ -208,7 +208,7 @@ public class SplitRecoveryIT extends ConfigurableMacBase {
MetadataTableUtil.splitTablet(high, extent.prevEndRow(), splitRatio, context, zl, Set.of());
TServerInstance instance = new TServerInstance(location, zl.getSessionId());
- Assignment assignment = new Assignment(high, instance);
+ Assignment assignment = new Assignment(high, instance, null);
TabletMutator tabletMutator = context.getAmple().mutateTablet(extent);
tabletMutator.putLocation(Location.future(assignment.server));
diff --git a/test/src/main/java/org/apache/accumulo/test/manager/MergeStateIT.java b/test/src/main/java/org/apache/accumulo/test/manager/MergeStateIT.java
index 68aa73408b..e36c8b8dd8 100644
--- a/test/src/main/java/org/apache/accumulo/test/manager/MergeStateIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/manager/MergeStateIT.java
@@ -187,7 +187,7 @@ public class MergeStateIT extends ConfigurableMacBase {
TabletColumnFamily.SPLIT_RATIO_COLUMN.put(m, new Value("0.5"));
update(accumuloClient, m);
metaDataStateStore
- .setLocations(Collections.singletonList(new Assignment(tablet, state.someTServer)));
+ .setLocations(Collections.singletonList(new Assignment(tablet, state.someTServer, null)));
// onos... there's a new tablet online
stats = scan(state, metaDataStateStore);
diff --git a/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java b/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java
index 402c722feb..d11da541d5 100644
--- a/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java
+++ b/test/src/main/java/org/apache/accumulo/test/performance/NullTserver.java
@@ -355,7 +355,7 @@ public class NullTserver {
while (s.hasNext()) {
TabletLocationState next = s.next();
- assignments.add(new Assignment(next.extent, instance));
+ assignments.add(new Assignment(next.extent, instance, next.last));
}
}
// point them to this server