Repository: cassandra Updated Branches: refs/heads/trunk d6e508f33 -> 7e362e78c
Nodetool tablehistograms to print statics for all the tables Patch by Jaydeepkumar Chovatia; Reviewed by Chris Lohfink for CASSANDRA-14185 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/7e362e78 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/7e362e78 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/7e362e78 Branch: refs/heads/trunk Commit: 7e362e78c342d8ca016de12218732a3e5f7dcc36 Parents: d6e508f Author: jaydeepkumar1984 <[email protected]> Authored: Mon Jan 22 13:46:09 2018 -0800 Committer: Jeff Jirsa <[email protected]> Committed: Mon Jan 29 18:19:40 2018 -0800 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../tools/nodetool/TableHistograms.java | 174 +++++++++++-------- 2 files changed, 100 insertions(+), 75 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/7e362e78/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index a5bdb42..e28ffd9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 4.0 + * Nodetool tablehistograms to print statics for all the tables (CASSANDRA-14185) * Migrate dtests to use pytest and python3 (CASSANDRA-14134) * Allow storage port to be configurable per node (CASSANDRA-7544) * Make sub-range selection for non-frozen collections return null instead of empty (CASSANDRA-14182) http://git-wip-us.apache.org/repos/asf/cassandra/blob/7e362e78/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java b/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java index 5286e18..910176a 100644 --- a/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java +++ b/src/java/org/apache/cassandra/tools/nodetool/TableHistograms.java @@ -23,8 +23,13 @@ import io.airlift.airline.Arguments; import io.airlift.airline.Command; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.Map; +import org.apache.cassandra.db.ColumnFamilyStoreMBean; import org.apache.cassandra.metrics.CassandraMetricsRegistry; import org.apache.cassandra.tools.NodeProbe; import org.apache.cassandra.tools.NodeTool.NodeToolCmd; @@ -34,107 +39,126 @@ import org.apache.commons.lang3.ArrayUtils; @Command(name = "tablehistograms", description = "Print statistic histograms for a given table") public class TableHistograms extends NodeToolCmd { - @Arguments(usage = "<keyspace> <table> | <keyspace.table>", description = "The keyspace and table name") + @Arguments(usage = "[<keyspace> <table> | <keyspace.table>]", description = "The keyspace and table name") private List<String> args = new ArrayList<>(); @Override public void execute(NodeProbe probe) { - String keyspace = null, table = null; + Map<String, List<String>> tablesList = new HashMap<>(); if (args.size() == 2) { - keyspace = args.get(0); - table = args.get(1); + tablesList.put(args.get(0), new ArrayList<String>(Arrays.asList(args.get(1)))); } else if (args.size() == 1) { String[] input = args.get(0).split("\\."); checkArgument(input.length == 2, "tablehistograms requires keyspace and table name arguments"); - keyspace = input[0]; - table = input[1]; + tablesList.put(input[0], new ArrayList<String>(Arrays.asList(input[1]))); } else { - checkArgument(false, "tablehistograms requires keyspace and table name arguments"); - } - - // calculate percentile of row size and column count - long[] estimatedPartitionSize = (long[]) probe.getColumnFamilyMetric(keyspace, table, "EstimatedPartitionSizeHistogram"); - long[] estimatedColumnCount = (long[]) probe.getColumnFamilyMetric(keyspace, table, "EstimatedColumnCountHistogram"); - - // build arrays to store percentile values - double[] estimatedRowSizePercentiles = new double[7]; - double[] estimatedColumnCountPercentiles = new double[7]; - double[] offsetPercentiles = new double[]{0.5, 0.75, 0.95, 0.98, 0.99}; - - if (ArrayUtils.isEmpty(estimatedPartitionSize) || ArrayUtils.isEmpty(estimatedColumnCount)) - { - System.err.println("No SSTables exists, unable to calculate 'Partition Size' and 'Cell Count' percentiles"); - - for (int i = 0; i < 7; i++) + // get a list of table stores + Iterator<Map.Entry<String, ColumnFamilyStoreMBean>> tableMBeans = probe.getColumnFamilyStoreMBeanProxies(); + while (tableMBeans.hasNext()) { - estimatedRowSizePercentiles[i] = Double.NaN; - estimatedColumnCountPercentiles[i] = Double.NaN; + Map.Entry<String, ColumnFamilyStoreMBean> entry = tableMBeans.next(); + String keyspaceName = entry.getKey(); + ColumnFamilyStoreMBean tableProxy = entry.getValue(); + if (!tablesList.containsKey(keyspaceName)) + { + tablesList.put(keyspaceName, new ArrayList<String>()); + } + tablesList.get(keyspaceName).add(tableProxy.getTableName()); } } - else - { - EstimatedHistogram partitionSizeHist = new EstimatedHistogram(estimatedPartitionSize); - EstimatedHistogram columnCountHist = new EstimatedHistogram(estimatedColumnCount); - if (partitionSizeHist.isOverflowed()) + Iterator<Map.Entry<String, List<String>>> iter = tablesList.entrySet().iterator(); + while(iter.hasNext()) + { + Map.Entry<String, List<String>> entry = iter.next(); + String keyspace = entry.getKey(); + for (String table : entry.getValue()) { - System.err.println(String.format("Row sizes are larger than %s, unable to calculate percentiles", partitionSizeHist.getLargestBucketOffset())); - for (int i = 0; i < offsetPercentiles.length; i++) + // calculate percentile of row size and column count + long[] estimatedPartitionSize = (long[]) probe.getColumnFamilyMetric(keyspace, table, "EstimatedPartitionSizeHistogram"); + long[] estimatedColumnCount = (long[]) probe.getColumnFamilyMetric(keyspace, table, "EstimatedColumnCountHistogram"); + + // build arrays to store percentile values + double[] estimatedRowSizePercentiles = new double[7]; + double[] estimatedColumnCountPercentiles = new double[7]; + double[] offsetPercentiles = new double[]{0.5, 0.75, 0.95, 0.98, 0.99}; + + if (ArrayUtils.isEmpty(estimatedPartitionSize) || ArrayUtils.isEmpty(estimatedColumnCount)) + { + System.out.println("No SSTables exists, unable to calculate 'Partition Size' and 'Cell Count' percentiles"); + + for (int i = 0; i < 7; i++) + { estimatedRowSizePercentiles[i] = Double.NaN; - } - else - { - for (int i = 0; i < offsetPercentiles.length; i++) - estimatedRowSizePercentiles[i] = partitionSizeHist.percentile(offsetPercentiles[i]); - } + estimatedColumnCountPercentiles[i] = Double.NaN; + } + } + else + { + EstimatedHistogram partitionSizeHist = new EstimatedHistogram(estimatedPartitionSize); + EstimatedHistogram columnCountHist = new EstimatedHistogram(estimatedColumnCount); - if (columnCountHist.isOverflowed()) - { - System.err.println(String.format("Column counts are larger than %s, unable to calculate percentiles", columnCountHist.getLargestBucketOffset())); - for (int i = 0; i < estimatedColumnCountPercentiles.length; i++) - estimatedColumnCountPercentiles[i] = Double.NaN; - } - else - { - for (int i = 0; i < offsetPercentiles.length; i++) - estimatedColumnCountPercentiles[i] = columnCountHist.percentile(offsetPercentiles[i]); - } + if (partitionSizeHist.isOverflowed()) + { + System.out.println(String.format("Row sizes are larger than %s, unable to calculate percentiles", partitionSizeHist.getLargestBucketOffset())); + for (int i = 0; i < offsetPercentiles.length; i++) + estimatedRowSizePercentiles[i] = Double.NaN; + } + else + { + for (int i = 0; i < offsetPercentiles.length; i++) + estimatedRowSizePercentiles[i] = partitionSizeHist.percentile(offsetPercentiles[i]); + } - // min value - estimatedRowSizePercentiles[5] = partitionSizeHist.min(); - estimatedColumnCountPercentiles[5] = columnCountHist.min(); - // max value - estimatedRowSizePercentiles[6] = partitionSizeHist.max(); - estimatedColumnCountPercentiles[6] = columnCountHist.max(); - } + if (columnCountHist.isOverflowed()) + { + System.out.println(String.format("Column counts are larger than %s, unable to calculate percentiles", columnCountHist.getLargestBucketOffset())); + for (int i = 0; i < estimatedColumnCountPercentiles.length; i++) + estimatedColumnCountPercentiles[i] = Double.NaN; + } + else + { + for (int i = 0; i < offsetPercentiles.length; i++) + estimatedColumnCountPercentiles[i] = columnCountHist.percentile(offsetPercentiles[i]); + } - String[] percentiles = new String[]{"50%", "75%", "95%", "98%", "99%", "Min", "Max"}; - double[] readLatency = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspace, table, "ReadLatency")); - double[] writeLatency = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspace, table, "WriteLatency")); - double[] sstablesPerRead = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxHistogramMBean) probe.getColumnFamilyMetric(keyspace, table, "SSTablesPerReadHistogram")); + // min value + estimatedRowSizePercentiles[5] = partitionSizeHist.min(); + estimatedColumnCountPercentiles[5] = columnCountHist.min(); + // max value + estimatedRowSizePercentiles[6] = partitionSizeHist.max(); + estimatedColumnCountPercentiles[6] = columnCountHist.max(); + } - System.out.println(format("%s/%s histograms", keyspace, table)); - System.out.println(format("%-10s%10s%18s%18s%18s%18s", - "Percentile", "SSTables", "Write Latency", "Read Latency", "Partition Size", "Cell Count")); - System.out.println(format("%-10s%10s%18s%18s%18s%18s", - "", "", "(micros)", "(micros)", "(bytes)", "")); + String[] percentiles = new String[]{"50%", "75%", "95%", "98%", "99%", "Min", "Max"}; + double[] readLatency = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspace, table, "ReadLatency")); + double[] writeLatency = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspace, table, "WriteLatency")); + double[] sstablesPerRead = probe.metricPercentilesAsArray((CassandraMetricsRegistry.JmxHistogramMBean) probe.getColumnFamilyMetric(keyspace, table, "SSTablesPerReadHistogram")); - for (int i = 0; i < percentiles.length; i++) - { - System.out.println(format("%-10s%10.2f%18.2f%18.2f%18.0f%18.0f", - percentiles[i], - sstablesPerRead[i], - writeLatency[i], - readLatency[i], - estimatedRowSizePercentiles[i], - estimatedColumnCountPercentiles[i])); + System.out.println(format("%s/%s histograms", keyspace, table)); + System.out.println(format("%-10s%10s%18s%18s%18s%18s", + "Percentile", "SSTables", "Write Latency", "Read Latency", "Partition Size", "Cell Count")); + System.out.println(format("%-10s%10s%18s%18s%18s%18s", + "", "", "(micros)", "(micros)", "(bytes)", "")); + + for (int i = 0; i < percentiles.length; i++) + { + System.out.println(format("%-10s%10.2f%18.2f%18.2f%18.0f%18.0f", + percentiles[i], + sstablesPerRead[i], + writeLatency[i], + readLatency[i], + estimatedRowSizePercentiles[i], + estimatedColumnCountPercentiles[i])); + } + System.out.println(); + } } - System.out.println(); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
