You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by aw...@apache.org on 2018/04/12 20:12:08 UTC
cassandra git commit: nodetool describecluster should be more
informative [Forced Update!]
Repository: cassandra
Updated Branches:
refs/heads/trunk 42efbddd3 -> 40aeaf0c1 (forced update)
nodetool describecluster should be more informative
Patch by Preetika Tyagi, Reviewed by Ariel Weisberg for CASSANDRA-13853
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/40aeaf0c
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/40aeaf0c
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/40aeaf0c
Branch: refs/heads/trunk
Commit: 40aeaf0c12b24dbc0f554fbd00a42fe739767ac7
Parents: 3747a6c
Author: Preetika Tyagi <pr...@intel.com>
Authored: Wed Apr 11 15:18:17 2018 -0400
Committer: Ariel Weisberg <aw...@apple.com>
Committed: Thu Apr 12 16:11:18 2018 -0400
----------------------------------------------------------------------
CHANGES.txt | 1 +
src/java/org/apache/cassandra/gms/Gossiper.java | 22 +++++
.../org/apache/cassandra/gms/GossiperMBean.java | 4 +
.../cassandra/service/StorageService.java | 11 +++
.../cassandra/service/StorageServiceMBean.java | 5 ++
.../org/apache/cassandra/tools/NodeProbe.java | 10 +++
.../tools/nodetool/DescribeCluster.java | 94 +++++++++++++++++++-
7 files changed, 144 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 754b9f3..0935434 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0
+ * nodetool describecluster should be more informative (CASSANDRA-13853)
* Compaction performance improvements (CASSANDRA-14261)
* Refactor Pair usage to avoid boxing ints/longs (CASSANDRA-14260)
* Add options to nodetool tablestats to sort and limit output (CASSANDRA-13889)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/gms/Gossiper.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/gms/Gossiper.java b/src/java/org/apache/cassandra/gms/Gossiper.java
index 24b659b..0f3a5cd 100644
--- a/src/java/org/apache/cassandra/gms/Gossiper.java
+++ b/src/java/org/apache/cassandra/gms/Gossiper.java
@@ -32,6 +32,7 @@ import javax.management.ObjectName;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
import com.google.common.util.concurrent.Uninterruptibles;
import org.apache.cassandra.locator.InetAddressAndPort;
@@ -1732,6 +1733,27 @@ public class Gossiper implements IFailureDetectionEventListener, GossiperMBean
return state != null ? state.getReleaseVersion() : null;
}
+ public Map<String, List<String>> getReleaseVersionsWithPort()
+ {
+ Map<String, List<String>> results = new HashMap<String, List<String>>();
+ Iterable<InetAddressAndPort> allHosts = Iterables.concat(Gossiper.instance.getLiveMembers(), Gossiper.instance.getUnreachableMembers());
+
+ for (InetAddressAndPort host : allHosts)
+ {
+ CassandraVersion version = getReleaseVersion(host);
+ String stringVersion = version == null ? "" : version.toString();
+ List<String> hosts = results.get(stringVersion);
+ if (hosts == null)
+ {
+ hosts = new ArrayList<>();
+ results.put(stringVersion, hosts);
+ }
+ hosts.add(host.getHostAddress(true));
+ }
+
+ return results;
+ }
+
@Nullable
public UUID getSchemaVersion(InetAddressAndPort ep)
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/gms/GossiperMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/gms/GossiperMBean.java b/src/java/org/apache/cassandra/gms/GossiperMBean.java
index 1b116e1..92df2cd 100644
--- a/src/java/org/apache/cassandra/gms/GossiperMBean.java
+++ b/src/java/org/apache/cassandra/gms/GossiperMBean.java
@@ -19,6 +19,7 @@ package org.apache.cassandra.gms;
import java.net.UnknownHostException;
import java.util.List;
+import java.util.Map;
public interface GossiperMBean
{
@@ -34,4 +35,7 @@ public interface GossiperMBean
public List<String> getSeeds();
+ /** Returns each node's database release version */
+ public Map<String, List<String>> getReleaseVersionsWithPort();
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index 91206c1..e5911f3 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -79,6 +79,7 @@ import org.apache.cassandra.repair.messages.RepairOption;
import org.apache.cassandra.schema.CompactionParams.TombstoneOption;
import org.apache.cassandra.schema.KeyspaceMetadata;
import org.apache.cassandra.schema.MigrationManager;
+import org.apache.cassandra.schema.ReplicationParams;
import org.apache.cassandra.schema.Schema;
import org.apache.cassandra.schema.SchemaConstants;
import org.apache.cassandra.schema.SchemaPullVerbHandler;
@@ -2968,6 +2969,16 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
return Schema.instance.getVersion().toString();
}
+ public String getKeyspaceReplicationInfo(String keyspaceName)
+ {
+ Keyspace keyspaceInstance = Schema.instance.getKeyspaceInstance(keyspaceName);
+ if (keyspaceInstance == null)
+ throw new IllegalArgumentException(); // ideally should never happen
+ ReplicationParams replicationParams = keyspaceInstance.getMetadata().params.replication;
+ String replicationInfo = replicationParams.klass.getSimpleName() + " " + replicationParams.options.toString();
+ return replicationInfo;
+ }
+
@Deprecated
public List<String> getLeavingNodes()
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/service/StorageServiceMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageServiceMBean.java b/src/java/org/apache/cassandra/service/StorageServiceMBean.java
index 0676419..206a37b 100644
--- a/src/java/org/apache/cassandra/service/StorageServiceMBean.java
+++ b/src/java/org/apache/cassandra/service/StorageServiceMBean.java
@@ -100,6 +100,11 @@ public interface StorageServiceMBean extends NotificationEmitter
*/
public String getSchemaVersion();
+ /**
+ * Fetch the replication factor for a given keyspace.
+ * @return An integer that represents replication factor for the given keyspace.
+ */
+ public String getKeyspaceReplicationInfo(String keyspaceName);
/**
* Get the list of all data file locations from conf
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/tools/NodeProbe.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java
index 1bace2e..04a5781 100644
--- a/src/java/org/apache/cassandra/tools/NodeProbe.java
+++ b/src/java/org/apache/cassandra/tools/NodeProbe.java
@@ -387,6 +387,11 @@ public class NodeProbe implements AutoCloseable
ssProxy.forceKeyspaceFlush(keyspaceName, tableNames);
}
+ public String getKeyspaceReplicationInfo(String keyspaceName)
+ {
+ return ssProxy.getKeyspaceReplicationInfo(keyspaceName);
+ }
+
public void repairAsync(final PrintStream out, final String keyspace, Map<String, String> options) throws IOException
{
RepairRunner runner = new RepairRunner(out, ssProxy, keyspace, options);
@@ -906,6 +911,11 @@ public class NodeProbe implements AutoCloseable
return spProxy;
}
+ public GossiperMBean getGossProxy()
+ {
+ return gossProxy;
+ }
+
public String getEndpoint()
{
Map<String, String> hostIdToEndpoint = ssProxy.getHostIdToEndpoint();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/40aeaf0c/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java b/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java
index ed91b8b..da02db6 100644
--- a/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java
+++ b/src/java/org/apache/cassandra/tools/nodetool/DescribeCluster.java
@@ -17,19 +17,29 @@
*/
package org.apache.cassandra.tools.nodetool;
-import static java.lang.String.format;
-import io.airlift.airline.Command;
-
+import java.util.Collection;
import java.util.List;
import java.util.Map;
+import java.util.SortedMap;
+
+import com.google.common.collect.ArrayListMultimap;
+import io.airlift.airline.Command;
import org.apache.cassandra.locator.DynamicEndpointSnitch;
+import org.apache.cassandra.locator.InetAddressAndPort;
import org.apache.cassandra.tools.NodeProbe;
+import org.apache.cassandra.tools.NodeTool;
import org.apache.cassandra.tools.NodeTool.NodeToolCmd;
+import static java.lang.String.format;
+
@Command(name = "describecluster", description = "Print the name, snitch, partitioner and schema version of a cluster")
public class DescribeCluster extends NodeToolCmd
{
+ private boolean resolveIp = false;
+ private String keyspace = null;
+ private Collection<String> joiningNodes, leavingNodes, movingNodes, liveNodes, unreachableNodes;
+
@Override
public void execute(NodeProbe probe)
{
@@ -54,5 +64,83 @@ public class DescribeCluster extends NodeToolCmd
{
System.out.println(format("\t\t%s: %s%n", version, schemaVersions.get(version)));
}
+
+ // Collect status information of all nodes
+ boolean withPort = true;
+ joiningNodes = probe.getJoiningNodes(withPort);
+ leavingNodes = probe.getLeavingNodes(withPort);
+ movingNodes = probe.getMovingNodes(withPort);
+ liveNodes = probe.getLiveNodes(withPort);
+ unreachableNodes = probe.getUnreachableNodes(withPort);
+
+ // Get the list of all keyspaces
+ List<String> keyspaces = probe.getKeyspaces();
+
+ System.out.println("Stats for all nodes:");
+ System.out.println("\tLive: " + liveNodes.size());
+ System.out.println("\tJoining: " + joiningNodes.size());
+ System.out.println("\tMoving: " + movingNodes.size());
+ System.out.println("\tLeaving: " + leavingNodes.size());
+ System.out.println("\tUnreachable: " + unreachableNodes.size());
+
+ Map<String, String> tokensToEndpoints = probe.getTokenToEndpointMap(withPort);
+ Map<String, Float> ownerships = null;
+ try
+ {
+ ownerships = probe.effectiveOwnershipWithPort(keyspace);
+ }
+ catch (IllegalStateException ex)
+ {
+ ownerships = probe.getOwnershipWithPort();
+ System.out.println("Error: " + ex.getMessage());
+ }
+ catch (IllegalArgumentException ex)
+ {
+ System.out.println("%nError: " + ex.getMessage());
+ System.exit(1);
+ }
+
+ SortedMap<String, SetHostStatWithPort> dcs = NodeTool.getOwnershipByDcWithPort(probe, resolveIp, tokensToEndpoints, ownerships);
+
+ System.out.println("\nData Centers: ");
+ for (Map.Entry<String, SetHostStatWithPort> dc : dcs.entrySet())
+ {
+ System.out.print("\t" + dc.getKey());
+
+ ArrayListMultimap<InetAddressAndPort, HostStatWithPort> hostToTokens = ArrayListMultimap.create();
+ for (HostStatWithPort stat : dc.getValue())
+ hostToTokens.put(stat.endpoint, stat);
+
+ int totalNodes = 0; // total number of nodes in a datacenter
+ int downNodes = 0; // number of down nodes in a datacenter
+
+ for (InetAddressAndPort endpoint : hostToTokens.keySet())
+ {
+ totalNodes++;
+ if (unreachableNodes.contains(endpoint.toString()))
+ downNodes++;
+ }
+ System.out.print(" #Nodes: " + totalNodes);
+ System.out.println(" #Down: " + downNodes);
+ }
+
+ // display database version for each node
+ System.out.println("\nDatabase versions:");
+ Map<String, List<String>> databaseVersions = probe.getGossProxy().getReleaseVersionsWithPort();
+ for (String version : databaseVersions.keySet())
+ {
+ System.out.println(format("\t%s: %s%n", version, databaseVersions.get(version)));
+ }
+
+ System.out.println("Keyspaces:");
+ for (String keyspaceName : keyspaces)
+ {
+ String replicationInfo = probe.getKeyspaceReplicationInfo(keyspaceName);
+ if (replicationInfo == null)
+ {
+ System.out.println("something went wrong for keyspace: " + keyspaceName);
+ }
+ System.out.println("\t" + keyspaceName + " -> Replication class: " + replicationInfo);
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org