You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ma...@apache.org on 2022/11/18 07:06:13 UTC
[cassandra] branch trunk updated: Add flag to exclude nodes from local DC when running nodetool rebuild
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 <sa...@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-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org