This is an automated email from the ASF dual-hosted git repository. marcuse pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push: new 145dbd1f08 Add flag to exclude nodes from local DC when running nodetool rebuild 145dbd1f08 is described below commit 145dbd1f0875ae4c54392125e09ed05153c0dd8f Author: Saranya Krishnakumar <sarany...@apple.com> AuthorDate: Wed Oct 19 16:58:41 2022 -0700 Add flag to exclude nodes from local DC when running nodetool rebuild Patch by Saranya Krishnakumar; reviewed by Dinesh Joshi, Marcus Eriksson, Yifan Cai for CASSANDRA-17870 --- CHANGES.txt | 1 + .../org/apache/cassandra/dht/RangeStreamer.java | 27 ++++++++++++++++++++++ .../apache/cassandra/service/StorageService.java | 16 ++++++++++++- .../cassandra/service/StorageServiceMBean.java | 14 +++++++++++ src/java/org/apache/cassandra/tools/NodeProbe.java | 4 ++-- .../apache/cassandra/tools/nodetool/Rebuild.java | 9 ++++++-- .../cassandra/service/StorageServiceTest.java | 15 ++++++++++++ 7 files changed, 81 insertions(+), 5 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index eed3363cd4..fd4903ef48 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.2 + * Add flag to exclude nodes from local DC when running nodetool rebuild (CASSANDRA-17870) * Adding endpoint verification option to client_encryption_options (CASSANDRA-18034) * Replace 'wcwidth.py' with pypi module (CASSANDRA-17287) * Add nodetool forcecompact to remove tombstoned or ttl'd data ignoring GC grace for given table and partition keys (CASSANDRA-17711) diff --git a/src/java/org/apache/cassandra/dht/RangeStreamer.java b/src/java/org/apache/cassandra/dht/RangeStreamer.java index 08d834459a..9b7833b90a 100644 --- a/src/java/org/apache/cassandra/dht/RangeStreamer.java +++ b/src/java/org/apache/cassandra/dht/RangeStreamer.java @@ -203,6 +203,33 @@ public class RangeStreamer } } + /** + * Source filter which excludes nodes from local DC. + */ + public static class ExcludeLocalDatacenterFilter implements SourceFilter + { + private final IEndpointSnitch snitch; + private final String localDc; + + public ExcludeLocalDatacenterFilter(IEndpointSnitch snitch) + { + this.snitch = snitch; + this.localDc = snitch.getLocalDatacenter(); + } + + @Override + public boolean apply(Replica replica) + { + return !snitch.getDatacenter(replica).equals(localDc); + } + + @Override + public String message(Replica replica) + { + return "Filtered " + replica + " out because it belongs to the local datacenter"; + } + } + /** * Source filter which excludes the current node from source calculations */ diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index da130c60a0..7dab8745f3 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -1280,10 +1280,15 @@ public class StorageService extends NotificationBroadcasterSupport implements IE public void rebuild(String sourceDc) { - rebuild(sourceDc, null, null, null); + rebuild(sourceDc, null, null, null, false); } public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources) + { + rebuild(sourceDc, keyspace, tokens, specificSources, false); + } + + public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources, boolean excludeLocalDatacenterNodes) { // check ongoing rebuild if (!isRebuilding.compareAndSet(false, true)) @@ -1291,6 +1296,12 @@ public class StorageService extends NotificationBroadcasterSupport implements IE throw new IllegalStateException("Node is still rebuilding. Check nodetool netstats."); } + // fail if source DC is local and --exclude-local-dc is set + if (sourceDc != null && sourceDc.equals(DatabaseDescriptor.getLocalDataCenter()) && excludeLocalDatacenterNodes) + { + throw new IllegalArgumentException("Cannot set source data center to be local data center, when excludeLocalDataCenter flag is set"); + } + try { // check the arguments @@ -1317,6 +1328,9 @@ public class StorageService extends NotificationBroadcasterSupport implements IE if (sourceDc != null) streamer.addSourceFilter(new RangeStreamer.SingleDatacenterFilter(DatabaseDescriptor.getEndpointSnitch(), sourceDc)); + if (excludeLocalDatacenterNodes) + streamer.addSourceFilter(new RangeStreamer.ExcludeLocalDatacenterFilter(DatabaseDescriptor.getEndpointSnitch())); + if (keyspace == null) { for (String keyspaceName : Schema.instance.getNonLocalStrategyKeyspaces().names()) diff --git a/src/java/org/apache/cassandra/service/StorageServiceMBean.java b/src/java/org/apache/cassandra/service/StorageServiceMBean.java index c92ea72bd6..43208b1308 100644 --- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java +++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java @@ -782,9 +782,23 @@ public interface StorageServiceMBean extends NotificationEmitter * @param keyspace Name of the keyspace which to rebuild or null to rebuild all keyspaces. * @param tokens Range of tokens to rebuild or null to rebuild all token ranges. In the format of: * "(start_token_1,end_token_1],(start_token_2,end_token_2],...(start_token_n,end_token_n]" + * @param specificSources list of sources that can be used for rebuilding. Must be other nodes in the cluster. + * The format of the string is comma separated values. */ public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources); + /** + * Same as {@link #rebuild(String)}, but only for specified keyspace and ranges. It excludes local data center nodes + * + * @param sourceDc Name of DC from which to select sources for streaming or null to pick any node + * @param keyspace Name of the keyspace which to rebuild or null to rebuild all keyspaces. + * @param tokens Range of tokens to rebuild or null to rebuild all token ranges. In the format of: + * "(start_token_1,end_token_1],(start_token_2,end_token_2],...(start_token_n,end_token_n]" + * @param specificSources list of sources that can be used for rebuilding. Mostly other nodes in the cluster. + * @param excludeLocalDatacenterNodes Flag to indicate whether local data center nodes should be excluded as sources for streaming. + */ + public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources, boolean excludeLocalDatacenterNodes); + /** Starts a bulk load and blocks until it completes. */ public void bulkLoad(String directory); diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java index e296d39723..22ec00b5df 100644 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@ -1589,9 +1589,9 @@ public class NodeProbe implements AutoCloseable return withPort ? ssProxy.describeRingWithPortJMX(keyspaceName) : ssProxy.describeRingJMX(keyspaceName); } - public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources) + public void rebuild(String sourceDc, String keyspace, String tokens, String specificSources, boolean excludeLocalDatacenterNodes) { - ssProxy.rebuild(sourceDc, keyspace, tokens, specificSources); + ssProxy.rebuild(sourceDc, keyspace, tokens, specificSources, excludeLocalDatacenterNodes); } public List<String> sampleKeyRange() diff --git a/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java index a16e8f22f1..ed4e97c0f7 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java +++ b/src/java/org/apache/cassandra/tools/nodetool/Rebuild.java @@ -28,7 +28,7 @@ import org.apache.cassandra.tools.NodeTool.NodeToolCmd; public class Rebuild extends NodeToolCmd { @Arguments(usage = "<src-dc-name>", - description = "Name of DC from which to select sources for streaming. By default, pick any DC") + description = "Name of DC from which to select sources for streaming. By default, pick any DC (except local DC when --exclude-local-dc is set)") private String sourceDataCenterName = null; @Option(title = "specific_keyspace", @@ -46,6 +46,11 @@ public class Rebuild extends NodeToolCmd description = "Use -s to specify hosts that this node should stream from when -ts is used. Multiple hosts should be separated using commas (e.g. 127.0.0.1,127.0.0.2,...)") private String specificSources = null; + @Option(title = "exclude_local_dc", + name = {"--exclude-local-dc"}, + description = "Use --exclude-local-dc to exclude nodes in local data center as source for streaming.") + private boolean excludeLocalDatacenterNodes = false; + @Override public void execute(NodeProbe probe) { @@ -55,6 +60,6 @@ public class Rebuild extends NodeToolCmd throw new IllegalArgumentException("Cannot specify tokens without keyspace."); } - probe.rebuild(sourceDataCenterName, keyspace, tokens, specificSources); + probe.rebuild(sourceDataCenterName, keyspace, tokens, specificSources, excludeLocalDatacenterNodes); } } diff --git a/test/unit/org/apache/cassandra/service/StorageServiceTest.java b/test/unit/org/apache/cassandra/service/StorageServiceTest.java index cfc8908722..b379793214 100644 --- a/test/unit/org/apache/cassandra/service/StorageServiceTest.java +++ b/test/unit/org/apache/cassandra/service/StorageServiceTest.java @@ -306,4 +306,19 @@ public class StorageServiceTest storageService.setBatchSizeWarnThresholdInKiB(previousBatchSizeWarnThreshold); } } + + @Test + public void testLocalDatacenterNodesExcludedDuringRebuild() + { + StorageService service = StorageService.instance; + try + { + service.rebuild(DatabaseDescriptor.getLocalDataCenter(), "StorageServiceTest", null, null, true); + fail(); + } + catch (IllegalArgumentException e) + { + Assert.assertEquals("Cannot set source data center to be local data center, when excludeLocalDataCenter flag is set", e.getMessage()); + } + } } --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@cassandra.apache.org For additional commands, e-mail: commits-h...@cassandra.apache.org