mirror of https://github.com/apache/cassandra
Add MaxSSTableSize and MaxSSTableDuration metrics and propagate them together with local read/write ratio to tablestats
patch by Stefan Miklosovic; reviewed by Brandon Williams and Brad Schoening for CASSANDRA-18283
This commit is contained in:
parent
180f0f0b5b
commit
4841794028
|
|
@ -1,4 +1,5 @@
|
|||
5.0
|
||||
* Add MaxSSTableSize and MaxSSTableDuration metrics and propagate them together with local read/write ratio to tablestats (CASSANDRA-18283)
|
||||
* Add more logging around CompactionManager operations (CASSANDRA-18268)
|
||||
* Reduce memory allocations of calls to ByteBufer.duplicate() made in org.apache.cassandra.transport.CBUtil#writeValue (CASSANDRA-18212)
|
||||
* CEP-17: SSTable API (CASSANDRA-17056)
|
||||
|
|
|
|||
5
NEWS.txt
5
NEWS.txt
|
|
@ -126,7 +126,10 @@ New features
|
|||
normally require it, except `system_views.system_logs`.
|
||||
- More accurate skipping of sstables in read path due to better handling of min/max clustering and lower bound;
|
||||
SSTable format has been bumped to 'nc' because there are new fields in stats metadata\
|
||||
- SSTal
|
||||
- Added MaxSSTableSize and MaxSSTableDuration metrics to TableMetrics. The former returns the size of the biggest
|
||||
SSTable of a table or 0 when there is not any SSTable. The latter returns the maximum duration, computed as
|
||||
`maxTimestamp - minTimestamp`, effectively non-zero for SSTables produced by TimeWindowCompactionStrategy.
|
||||
- Added local read/write ratio to tablestats.
|
||||
|
||||
Upgrading
|
||||
---------
|
||||
|
|
|
|||
|
|
@ -144,6 +144,13 @@ this table (in bytes).
|
|||
|TotalDiskSpaceUsed |Counter |Total disk space used by SSTables
|
||||
belonging to this table, including obsolete ones waiting to be GC'd.
|
||||
|
||||
|MaxSSTableSize |Gauge<Long> |Maximum size of SSTable of this table -
|
||||
the physical size on disk of all components for such SSTable in bytes. Equals to
|
||||
zero if there is not any SSTable on disk.
|
||||
|
||||
|MaxSSTableDuration |Gauge<Long> |Maximum duration in milliseconds of an SSTable for this table,
|
||||
computed as `maxTimestamp - minTimestamp`. Equals to zero if min or max timestamp is `Long.MAX_VALUE`.
|
||||
|
||||
|MinPartitionSize |Gauge<Long> |Size of the smallest compacted partition
|
||||
(in bytes).
|
||||
|
||||
|
|
|
|||
|
|
@ -3435,6 +3435,18 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean, Memtable.Owner
|
|||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxSSTableSize()
|
||||
{
|
||||
return metric.maxSSTableSize.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getMaxSSTableDuration()
|
||||
{
|
||||
return metric.maxSSTableDuration.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Long> getTopSizePartitions()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -299,4 +299,23 @@ public interface ColumnFamilyStoreMBean
|
|||
public Long getTopSizePartitionsLastUpdate();
|
||||
public Map<String, Long> getTopTombstonePartitions();
|
||||
public Long getTopTombstonePartitionsLastUpdate();
|
||||
|
||||
/**
|
||||
* Returns the size of the biggest SSTable of this table.
|
||||
*
|
||||
* @return (physical) size of the biggest SSTable of this table on disk or 0 if no SSTable is present
|
||||
*/
|
||||
public long getMaxSSTableSize();
|
||||
|
||||
/**
|
||||
* Returns the longest duration of an SSTable, in milliseconds, of this table,
|
||||
* computed as {@code maxTimestamp - minTimestamp}.
|
||||
*
|
||||
* It returns 0 if there are no SSTables or if {@code maxTimestamp} or {@code minTimestamp} is
|
||||
* equal to {@code Long.MAX_VALUE}. Effectively non-zero for tables on {@code TimeWindowCompactionStrategy}.
|
||||
*
|
||||
* @return the biggest {@code maxTimestamp - minTimestamp} among all SSTables of this table
|
||||
* or 0 if no SSTable is present
|
||||
*/
|
||||
public long getMaxSSTableDuration();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,11 +39,11 @@ public final class TimeWindowCompactionStrategyOptions
|
|||
protected static final int DEFAULT_EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS = 60 * 10;
|
||||
protected static final Boolean DEFAULT_UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION = false;
|
||||
|
||||
protected static final String TIMESTAMP_RESOLUTION_KEY = "timestamp_resolution";
|
||||
protected static final String COMPACTION_WINDOW_UNIT_KEY = "compaction_window_unit";
|
||||
protected static final String COMPACTION_WINDOW_SIZE_KEY = "compaction_window_size";
|
||||
protected static final String EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY = "expired_sstable_check_frequency_seconds";
|
||||
protected static final String UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_KEY = "unsafe_aggressive_sstable_expiration";
|
||||
public static final String TIMESTAMP_RESOLUTION_KEY = "timestamp_resolution";
|
||||
public static final String COMPACTION_WINDOW_UNIT_KEY = "compaction_window_unit";
|
||||
public static final String COMPACTION_WINDOW_SIZE_KEY = "compaction_window_size";
|
||||
public static final String EXPIRED_SSTABLE_CHECK_FREQUENCY_SECONDS_KEY = "expired_sstable_check_frequency_seconds";
|
||||
public static final String UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_KEY = "unsafe_aggressive_sstable_expiration";
|
||||
|
||||
static final String UNSAFE_AGGRESSIVE_SSTABLE_EXPIRATION_PROPERTY = Config.PROPERTY_PREFIX + "allow_unsafe_aggressive_sstable_expiration";
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,10 @@ public class TableMetrics
|
|||
public final Gauge<Integer> liveSSTableCount;
|
||||
/** Number of SSTables with old version on disk for this CF */
|
||||
public final Gauge<Integer> oldVersionSSTableCount;
|
||||
/** Maximum duration of an SSTable for this table, computed as maxTimestamp - minTimestamp*/
|
||||
public final Gauge<Long> maxSSTableDuration;
|
||||
/** Maximum size of SSTable of this table - the physical size on disk of all components for such SSTable in bytes*/
|
||||
public final Gauge<Long> maxSSTableSize;
|
||||
/** Disk space used by SSTables belonging to this table */
|
||||
public final Counter liveDiskSpaceUsed;
|
||||
/** Uncompressed/logical disk space used by SSTables belonging to this table */
|
||||
|
|
@ -633,6 +637,35 @@ public class TableMetrics
|
|||
return count;
|
||||
}
|
||||
});
|
||||
maxSSTableDuration = createTableGauge("MaxSSTableDuration", new Gauge<Long>()
|
||||
{
|
||||
@Override
|
||||
public Long getValue()
|
||||
{
|
||||
return cfs.getTracker()
|
||||
.getView()
|
||||
.liveSSTables()
|
||||
.stream()
|
||||
.filter(sstable -> sstable.getMinTimestamp() != Long.MAX_VALUE && sstable.getMaxTimestamp() != Long.MAX_VALUE)
|
||||
.map(ssTableReader -> ssTableReader.getMaxTimestamp() - ssTableReader.getMinTimestamp())
|
||||
.max(Long::compare)
|
||||
.orElse(0L);
|
||||
}
|
||||
});
|
||||
maxSSTableSize = createTableGauge("MaxSSTableSize", new Gauge<Long>()
|
||||
{
|
||||
@Override
|
||||
public Long getValue()
|
||||
{
|
||||
return cfs.getTracker()
|
||||
.getView()
|
||||
.liveSSTables()
|
||||
.stream()
|
||||
.map(SSTableReader::bytesOnDisk)
|
||||
.max(Long::compare)
|
||||
.orElse(0L);
|
||||
}
|
||||
});
|
||||
liveDiskSpaceUsed = createTableCounter("LiveDiskSpaceUsed");
|
||||
uncompressedLiveDiskSpaceUsed = createTableCounter("UncompressedLiveDiskSpaceUsed");
|
||||
totalDiskSpaceUsed = createTableCounter("TotalDiskSpaceUsed");
|
||||
|
|
|
|||
|
|
@ -1802,6 +1802,8 @@ public class NodeProbe implements AutoCloseable
|
|||
case "EstimatedPartitionCount":
|
||||
case "KeyCacheHitRate":
|
||||
case "LiveSSTableCount":
|
||||
case "MaxSSTableDuration":
|
||||
case "MaxSSTableSize":
|
||||
case "OldVersionSSTableCount":
|
||||
case "MaxPartitionSize":
|
||||
case "MeanPartitionSize":
|
||||
|
|
|
|||
|
|
@ -60,7 +60,8 @@ public class TableStats extends NodeToolCmd
|
|||
+ "memtable_off_heap_memory_used, memtable_switch_count, number_of_partitions_estimate, "
|
||||
+ "off_heap_memory_used_total, pending_flushes, percent_repaired, read_latency, reads, "
|
||||
+ "space_used_by_snapshots_total, space_used_live, space_used_total, "
|
||||
+ "sstable_compression_ratio, sstable_count, table_name, write_latency, writes)")
|
||||
+ "sstable_compression_ratio, sstable_count, table_name, write_latency, writes, " +
|
||||
"max_sstable_size, local_read_write_ratio, twcs_max_duration)")
|
||||
private String sortKey = "";
|
||||
|
||||
@Option(title = "top",
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ public class StatsTable
|
|||
public boolean isLeveledSstable = false;
|
||||
public Object sstableCount;
|
||||
public Object oldSSTableCount;
|
||||
public Long maxSSTableSize;
|
||||
public String spaceUsedLive;
|
||||
public String spaceUsedTotal;
|
||||
public String spaceUsedBySnapshotsTotal;
|
||||
|
|
@ -78,4 +79,7 @@ public class StatsTable
|
|||
public Map<String, Long> topTombstonePartitions;
|
||||
public String topSizePartitionsLastUpdate;
|
||||
public String topTombstonePartitionsLastUpdate;
|
||||
public double localReadWriteRatio;
|
||||
public Long twcsDurationInMillis;
|
||||
public String twcs;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,7 +65,8 @@ public class StatsTableComparator implements Comparator<StatsTable>
|
|||
"pending_flushes", "percent_repaired", "read_latency", "reads",
|
||||
"space_used_by_snapshots_total", "space_used_live",
|
||||
"space_used_total", "sstable_compression_ratio", "sstable_count",
|
||||
"table_name", "write_latency", "writes" };
|
||||
"table_name", "write_latency", "writes", "max_sstable_size",
|
||||
"local_read_write_ratio", "twcs_max_duration"};
|
||||
|
||||
public StatsTableComparator(String sortKey, boolean humanReadable)
|
||||
{
|
||||
|
|
@ -229,6 +230,10 @@ public class StatsTableComparator implements Comparator<StatsTable>
|
|||
{
|
||||
result = compareDoubles(stx.localWriteLatencyMs, sty.localWriteLatencyMs);
|
||||
}
|
||||
else if (sortKey.equals("local_read_write_ratio"))
|
||||
{
|
||||
result = compareDoubles(stx.localReadWriteRatio, sty.localReadWriteRatio);
|
||||
}
|
||||
else if (sortKey.equals("maximum_live_cells_per_slice_last_five_minutes"))
|
||||
{
|
||||
result = sign * Long.valueOf(stx.maximumLiveCellsPerSliceLastFiveMinutes)
|
||||
|
|
@ -295,6 +300,21 @@ public class StatsTableComparator implements Comparator<StatsTable>
|
|||
{
|
||||
result = compareDoubles(stx.percentRepaired, sty.percentRepaired);
|
||||
}
|
||||
else if (sortKey.equals("max_sstable_size"))
|
||||
{
|
||||
result = sign * stx.maxSSTableSize.compareTo(sty.maxSSTableSize);
|
||||
}
|
||||
else if (sortKey.equals("twcs_max_duration"))
|
||||
{
|
||||
if (stx.twcsDurationInMillis != null && sty.twcsDurationInMillis == null)
|
||||
return sign;
|
||||
else if (stx.twcsDurationInMillis == null && sty.twcsDurationInMillis != null)
|
||||
return sign * -1;
|
||||
else if (stx.twcsDurationInMillis == null)
|
||||
return 0;
|
||||
else
|
||||
result = sign * stx.twcsDurationInMillis.compareTo(sty.twcsDurationInMillis);
|
||||
}
|
||||
else if (sortKey.equals("space_used_by_snapshots_total"))
|
||||
{
|
||||
result = compareFileSizes(stx.spaceUsedBySnapshotsTotal,
|
||||
|
|
|
|||
|
|
@ -25,7 +25,12 @@ import java.util.*;
|
|||
import com.google.common.collect.ArrayListMultimap;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
|
||||
import org.apache.commons.lang3.time.DurationFormatUtils;
|
||||
|
||||
import org.apache.cassandra.db.*;
|
||||
import org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy;
|
||||
import org.apache.cassandra.db.compaction.TimeWindowCompactionStrategyOptions;
|
||||
import org.apache.cassandra.io.util.*;
|
||||
import org.apache.cassandra.metrics.*;
|
||||
import org.apache.cassandra.tools.*;
|
||||
|
|
@ -33,7 +38,7 @@ import org.apache.cassandra.tools.*;
|
|||
public class TableStatsHolder implements StatsHolder
|
||||
{
|
||||
public final List<StatsKeyspace> keyspaces;
|
||||
public final int numberOfTables;
|
||||
public int numberOfTables = 0;
|
||||
public final boolean humanReadable;
|
||||
public final String sortKey;
|
||||
public final int top;
|
||||
|
|
@ -48,14 +53,7 @@ public class TableStatsHolder implements StatsHolder
|
|||
this.locationCheck = locationCheck;
|
||||
|
||||
if (!this.isTestTableStatsHolder())
|
||||
{
|
||||
this.numberOfTables = probe.getNumberOfTables();
|
||||
this.initializeKeyspaces(probe, ignore, tableNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.numberOfTables = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -121,6 +119,8 @@ public class TableStatsHolder implements StatsHolder
|
|||
Map<String, Object> mpTable = new HashMap<>();
|
||||
mpTable.put("sstables_in_each_level", table.sstablesInEachLevel);
|
||||
mpTable.put("sstable_bytes_in_each_level", table.sstableBytesInEachLevel);
|
||||
mpTable.put("max_sstable_size", table.maxSSTableSize);
|
||||
mpTable.put("twcs", table.twcs);
|
||||
mpTable.put("space_used_live", table.spaceUsedLive);
|
||||
mpTable.put("space_used_total", table.spaceUsedTotal);
|
||||
mpTable.put("space_used_by_snapshots_total", table.spaceUsedBySnapshotsTotal);
|
||||
|
|
@ -137,6 +137,7 @@ public class TableStatsHolder implements StatsHolder
|
|||
mpTable.put("local_read_latency_ms", String.format("%01.3f", table.localReadLatencyMs));
|
||||
mpTable.put("local_write_count", table.localWriteCount);
|
||||
mpTable.put("local_write_latency_ms", String.format("%01.3f", table.localWriteLatencyMs));
|
||||
mpTable.put("local_read_write_ratio", String.format("%01.5f", table.localReadWriteRatio));
|
||||
mpTable.put("pending_flushes", table.pendingFlushes);
|
||||
mpTable.put("percent_repaired", table.percentRepaired);
|
||||
mpTable.put("bytes_repaired", table.bytesRepaired);
|
||||
|
|
@ -203,6 +204,8 @@ public class TableStatsHolder implements StatsHolder
|
|||
}
|
||||
}
|
||||
|
||||
numberOfTables = selectedTableMbeans.size();
|
||||
|
||||
// make sure all specified keyspace and tables exist
|
||||
filter.verifyKeyspaces(probe.getKeyspaces());
|
||||
filter.verifyTables();
|
||||
|
|
@ -225,6 +228,8 @@ public class TableStatsHolder implements StatsHolder
|
|||
statsTable.isIndex = tableName.contains(".");
|
||||
statsTable.sstableCount = probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveSSTableCount");
|
||||
statsTable.oldSSTableCount = probe.getColumnFamilyMetric(keyspaceName, tableName, "OldVersionSSTableCount");
|
||||
Long sstableSize = (Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MaxSSTableSize");
|
||||
statsTable.maxSSTableSize = sstableSize == null ? 0 : sstableSize;
|
||||
|
||||
int[] leveledSStables = table.getSSTableCountPerLevel();
|
||||
if (leveledSStables != null)
|
||||
|
|
@ -289,6 +294,9 @@ public class TableStatsHolder implements StatsHolder
|
|||
statsTable.spaceUsedLive = format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "LiveDiskSpaceUsed"), humanReadable);
|
||||
statsTable.spaceUsedTotal = format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "TotalDiskSpaceUsed"), humanReadable);
|
||||
statsTable.spaceUsedBySnapshotsTotal = format((Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "SnapshotsSize"), humanReadable);
|
||||
|
||||
maybeAddTWCSWindowWithMaxDuration(statsTable, probe, keyspaceName, tableName);
|
||||
|
||||
if (offHeapSize != null)
|
||||
{
|
||||
statsTable.offHeapUsed = true;
|
||||
|
|
@ -329,6 +337,9 @@ public class TableStatsHolder implements StatsHolder
|
|||
|
||||
double localWriteLatency = ((CassandraMetricsRegistry.JmxTimerMBean) probe.getColumnFamilyMetric(keyspaceName, tableName, "WriteLatency")).getMean() / 1000;
|
||||
double localWLatency = localWriteLatency > 0 ? localWriteLatency : Double.NaN;
|
||||
|
||||
statsTable.localReadWriteRatio = statsTable.localWriteCount > 0 ? statsTable.localReadCount / (double) statsTable.localWriteCount : 0;
|
||||
|
||||
statsTable.localWriteLatencyMs = localWLatency;
|
||||
statsTable.pendingFlushes = probe.getColumnFamilyMetric(keyspaceName, tableName, "PendingFlushes");
|
||||
|
||||
|
|
@ -378,6 +389,27 @@ public class TableStatsHolder implements StatsHolder
|
|||
}
|
||||
}
|
||||
|
||||
private void maybeAddTWCSWindowWithMaxDuration(StatsTable statsTable, NodeProbe probe, String keyspaceName, String tableName)
|
||||
{
|
||||
Map<String, String> compactionParameters = probe.getCfsProxy(statsTable.keyspaceName, statsTable.tableName)
|
||||
.getCompactionParameters();
|
||||
|
||||
if (compactionParameters == null)
|
||||
return;
|
||||
|
||||
String compactor = compactionParameters.get("class");
|
||||
|
||||
if (compactor == null || !compactor.endsWith(TimeWindowCompactionStrategy.class.getSimpleName()))
|
||||
return;
|
||||
|
||||
String unit = compactionParameters.get(TimeWindowCompactionStrategyOptions.COMPACTION_WINDOW_UNIT_KEY);
|
||||
String size = compactionParameters.get(TimeWindowCompactionStrategyOptions.COMPACTION_WINDOW_SIZE_KEY);
|
||||
|
||||
statsTable.twcsDurationInMillis = (Long) probe.getColumnFamilyMetric(keyspaceName, tableName, "MaxSSTableDuration");
|
||||
String maxDuration = millisToDuration(statsTable.twcsDurationInMillis);
|
||||
statsTable.twcs = String.format("%s %s, max duration: %s", size, unit, maxDuration);
|
||||
}
|
||||
|
||||
private String format(long bytes, boolean humanReadable)
|
||||
{
|
||||
return humanReadable ? FileUtils.stringifyFileSize(bytes) : Long.toString(bytes);
|
||||
|
|
@ -399,6 +431,11 @@ public class TableStatsHolder implements StatsHolder
|
|||
return df.format(new Date(millis));
|
||||
}
|
||||
|
||||
private String millisToDuration(long millis)
|
||||
{
|
||||
return DurationFormatUtils.formatDurationWords(millis / 1000, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort and filter this TableStatHolder's tables as specified by its sortKey and top attributes.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -50,6 +50,9 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
@Override
|
||||
public void print(TableStatsHolder data, PrintStream out)
|
||||
{
|
||||
if (data.numberOfTables == 0)
|
||||
return;
|
||||
|
||||
out.println("Total number of tables: " + data.numberOfTables);
|
||||
out.println("----------------");
|
||||
|
||||
|
|
@ -57,7 +60,7 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
for (StatsKeyspace keyspace : keyspaces)
|
||||
{
|
||||
// print each keyspace's information
|
||||
out.println("Keyspace : " + keyspace.name);
|
||||
out.println("Keyspace: " + keyspace.name);
|
||||
out.println("\tRead Count: " + keyspace.readCount);
|
||||
out.println("\tRead Latency: " + keyspace.readLatency() + " ms");
|
||||
out.println("\tWrite Count: " + keyspace.writeCount);
|
||||
|
|
@ -66,6 +69,9 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
|
||||
// print each table's information
|
||||
List<StatsTable> tables = keyspace.tables;
|
||||
if (tables.size() == 0)
|
||||
continue;
|
||||
|
||||
for (StatsTable table : tables)
|
||||
{
|
||||
printStatsTable(table, table.tableName, "\t\t", out);
|
||||
|
|
@ -79,6 +85,9 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
out.println(indent + "Table" + (table.isIndex ? " (index): " : ": ") + tableDisplayName);
|
||||
out.println(indent + "SSTable count: " + table.sstableCount);
|
||||
out.println(indent + "Old SSTable count: " + table.oldSSTableCount);
|
||||
out.println(indent + "Max SSTable size: " + FBUtilities.prettyPrintMemory(table.maxSSTableSize));
|
||||
if (table.twcs != null)
|
||||
out.println(indent + "SSTables Time Window: " + table.twcs);
|
||||
if (table.isLeveledSstable)
|
||||
{
|
||||
out.println(indent + "SSTables in each level: [" + String.join(", ",
|
||||
|
|
@ -93,7 +102,7 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
|
||||
if (table.offHeapUsed)
|
||||
out.println(indent + "Off heap memory used (total): " + table.offHeapMemoryUsedTotal);
|
||||
out.println(indent + "SSTable Compression Ratio: " + table.sstableCompressionRatio);
|
||||
out.printf(indent + "SSTable Compression Ratio: %01.5f%n", table.sstableCompressionRatio);
|
||||
out.println(indent + "Number of partitions (estimate): " + table.numberOfPartitionsEstimate);
|
||||
out.println(indent + "Memtable cell count: " + table.memtableCellCount);
|
||||
out.println(indent + "Memtable data size: " + table.memtableDataSize);
|
||||
|
|
@ -105,6 +114,9 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
out.printf(indent + "Local read latency: %01.3f ms%n", table.localReadLatencyMs);
|
||||
out.println(indent + "Local write count: " + table.localWriteCount);
|
||||
out.printf(indent + "Local write latency: %01.3f ms%n", table.localWriteLatencyMs);
|
||||
|
||||
out.printf(indent + "Local read/write ratio: %01.5f%n", table.localReadWriteRatio);
|
||||
|
||||
out.println(indent + "Pending flushes: " + table.pendingFlushes);
|
||||
out.println(indent + "Percent repaired: " + table.percentRepaired);
|
||||
|
||||
|
|
@ -164,6 +176,10 @@ public class TableStatsPrinter<T extends StatsHolder>
|
|||
public void print(TableStatsHolder data, PrintStream out)
|
||||
{
|
||||
List<StatsTable> tables = data.getSortedFilteredTables();
|
||||
|
||||
if (tables.size() == 0)
|
||||
return;
|
||||
|
||||
String totalTablesSummary = String.format("Total number of tables: %d", data.numberOfTables);
|
||||
if (data.top > 0)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -108,7 +108,8 @@ public class TableStatsTest extends CQLTester
|
|||
" off_heap_memory_used_total, pending_flushes, percent_repaired,\n" +
|
||||
" read_latency, reads, space_used_by_snapshots_total, space_used_live,\n" +
|
||||
" space_used_total, sstable_compression_ratio, sstable_count,\n" +
|
||||
" table_name, write_latency, writes)\n" +
|
||||
" table_name, write_latency, writes, max_sstable_size,\n" +
|
||||
" local_read_write_ratio, twcs_max_duration)\n" +
|
||||
"\n" +
|
||||
" -t <top>, --top <top>\n" +
|
||||
" Show only the top K tables for the sort key (specify the number K of\n" +
|
||||
|
|
@ -134,12 +135,12 @@ public class TableStatsTest extends CQLTester
|
|||
{
|
||||
ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("tablestats");
|
||||
tool.assertOnCleanExit();
|
||||
assertThat(tool.getStdout()).contains("Keyspace : system_schema");
|
||||
assertThat(tool.getStdout()).contains("Keyspace: system_schema");
|
||||
assertThat(StringUtils.countMatches(tool.getStdout(), "Table:")).isGreaterThan(1);
|
||||
|
||||
tool = ToolRunner.invokeNodetool("tablestats", "system_distributed");
|
||||
tool.assertOnCleanExit();
|
||||
assertThat(tool.getStdout()).contains("Keyspace : system_distributed");
|
||||
assertThat(tool.getStdout()).contains("Keyspace: system_distributed");
|
||||
assertThat(tool.getStdout()).doesNotContain("Keyspace : system_schema");
|
||||
assertThat(StringUtils.countMatches(tool.getStdout(), "Table:")).isGreaterThan(1);
|
||||
}
|
||||
|
|
@ -149,7 +150,7 @@ public class TableStatsTest extends CQLTester
|
|||
{
|
||||
ToolRunner.ToolResult tool = ToolRunner.invokeNodetool("tablestats", "-i", "system_schema.aggregates");
|
||||
tool.assertOnCleanExit();
|
||||
assertThat(tool.getStdout()).contains("Keyspace : system_schema");
|
||||
assertThat(tool.getStdout()).contains("Keyspace: system_schema");
|
||||
assertThat(tool.getStdout()).doesNotContain("Table: system_schema.aggregates");
|
||||
assertThat(StringUtils.countMatches(tool.getStdout(), "Table:")).isGreaterThan(1);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -212,6 +212,11 @@ public class StatsTableComparatorTest extends TableStatsTestBase
|
|||
"table1 > table3 > table5 > table2 > table4 > table6",
|
||||
humanReadable,
|
||||
ascending);
|
||||
runCompareTest(testTables,
|
||||
"twcs_max_duration",
|
||||
"table2 > table4 > table1 > table3 > table6 > table5",
|
||||
humanReadable,
|
||||
ascending);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -35,10 +35,11 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 60000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 0\n" +
|
||||
"\tSpace used (total): 9001\n" +
|
||||
"\tSpace used by snapshots (total): 1111\n" +
|
||||
"\tSSTable Compression Ratio: 0.68\n" +
|
||||
"\tSSTable Compression Ratio: 0.68000\n" +
|
||||
"\tNumber of partitions (estimate): 111111\n" +
|
||||
"\tMemtable cell count: 111\n" +
|
||||
"\tMemtable data size: 0\n" +
|
||||
|
|
@ -47,6 +48,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: 2.000 ms\n" +
|
||||
"\tLocal write count: 5\n" +
|
||||
"\tLocal write latency: 0.050 ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 11111\n" +
|
||||
"\tPercent repaired: 100.0\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -70,11 +72,12 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 3000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 22\n" +
|
||||
"\tSpace used (total): 1024\n" +
|
||||
"\tSpace used by snapshots (total): 222\n" +
|
||||
"\tOff heap memory used (total): 314159367\n" +
|
||||
"\tSSTable Compression Ratio: 0.68\n" +
|
||||
"\tSSTable Compression Ratio: 0.68000\n" +
|
||||
"\tNumber of partitions (estimate): 22222\n" +
|
||||
"\tMemtable cell count: 22\n" +
|
||||
"\tMemtable data size: 900\n" +
|
||||
|
|
@ -84,6 +87,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: 3.000 ms\n" +
|
||||
"\tLocal write count: 4\n" +
|
||||
"\tLocal write latency: 0.000 ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 222222\n" +
|
||||
"\tPercent repaired: 99.9\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -110,10 +114,11 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 50000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 0\n" +
|
||||
"\tSpace used (total): 512\n" +
|
||||
"\tSpace used by snapshots (total): 0\n" +
|
||||
"\tSSTable Compression Ratio: 0.32\n" +
|
||||
"\tSSTable Compression Ratio: 0.32000\n" +
|
||||
"\tNumber of partitions (estimate): 3333\n" +
|
||||
"\tMemtable cell count: 333333\n" +
|
||||
"\tMemtable data size: 1999\n" +
|
||||
|
|
@ -122,6 +127,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: 4.000 ms\n" +
|
||||
"\tLocal write count: 3\n" +
|
||||
"\tLocal write latency: NaN ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 333\n" +
|
||||
"\tPercent repaired: 99.8\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -145,11 +151,12 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 2000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 4444\n" +
|
||||
"\tSpace used (total): 256\n" +
|
||||
"\tSpace used by snapshots (total): 44\n" +
|
||||
"\tOff heap memory used (total): 441213818\n" +
|
||||
"\tSSTable Compression Ratio: 0.95\n" +
|
||||
"\tSSTable Compression Ratio: 0.95000\n" +
|
||||
"\tNumber of partitions (estimate): 444\n" +
|
||||
"\tMemtable cell count: 4\n" +
|
||||
"\tMemtable data size: 3000\n" +
|
||||
|
|
@ -159,6 +166,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: NaN ms\n" +
|
||||
"\tLocal write count: 2\n" +
|
||||
"\tLocal write latency: 2.000 ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 4444\n" +
|
||||
"\tPercent repaired: 50.0\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -185,10 +193,11 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 40000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 55555\n" +
|
||||
"\tSpace used (total): 64\n" +
|
||||
"\tSpace used by snapshots (total): 55555\n" +
|
||||
"\tSSTable Compression Ratio: 0.99\n" +
|
||||
"\tSSTable Compression Ratio: 0.99000\n" +
|
||||
"\tNumber of partitions (estimate): 55\n" +
|
||||
"\tMemtable cell count: 55555\n" +
|
||||
"\tMemtable data size: 20000\n" +
|
||||
|
|
@ -197,6 +206,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: 0.000 ms\n" +
|
||||
"\tLocal write count: 1\n" +
|
||||
"\tLocal write latency: 1.000 ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 5\n" +
|
||||
"\tPercent repaired: 93.0\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -220,11 +230,12 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tTable: %s\n" +
|
||||
"\tSSTable count: 1000\n" +
|
||||
"\tOld SSTable count: 0\n" +
|
||||
"\tMax SSTable size: 0.000KiB\n" +
|
||||
"\tSpace used (live): 666666\n" +
|
||||
"\tSpace used (total): 0\n" +
|
||||
"\tSpace used by snapshots (total): 0\n" +
|
||||
"\tOff heap memory used (total): 162470810\n" +
|
||||
"\tSSTable Compression Ratio: 0.68\n" +
|
||||
"\tSSTable Compression Ratio: 0.68000\n" +
|
||||
"\tNumber of partitions (estimate): 6\n" +
|
||||
"\tMemtable cell count: 6666\n" +
|
||||
"\tMemtable data size: 1000000\n" +
|
||||
|
|
@ -234,6 +245,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
"\tLocal read latency: 1.000 ms\n" +
|
||||
"\tLocal write count: 0\n" +
|
||||
"\tLocal write latency: 0.500 ms\n" +
|
||||
"\tLocal read/write ratio: 0.00000\n" +
|
||||
"\tPending flushes: 66\n" +
|
||||
"\tPercent repaired: 0.0\n" +
|
||||
"\tBytes repaired: 0.000KiB\n" +
|
||||
|
|
@ -262,9 +274,9 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
* without leaking test implementation into the TableStatsHolder implementation.
|
||||
*/
|
||||
public static final String expectedDefaultPrinterOutput =
|
||||
"Total number of tables: 0\n" +
|
||||
"Total number of tables: 6\n" +
|
||||
"----------------\n" +
|
||||
"Keyspace : keyspace1\n" +
|
||||
"Keyspace: keyspace1\n" +
|
||||
"\tRead Count: 3\n" +
|
||||
"\tRead Latency: 0.0 ms\n" +
|
||||
"\tWrite Count: 12\n" +
|
||||
|
|
@ -274,7 +286,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
String.format(duplicateTabs(expectedDefaultTable2Output), "table2") +
|
||||
String.format(duplicateTabs(expectedDefaultTable3Output), "table3") +
|
||||
"----------------\n" +
|
||||
"Keyspace : keyspace2\n" +
|
||||
"Keyspace: keyspace2\n" +
|
||||
"\tRead Count: 7\n" +
|
||||
"\tRead Latency: 0.0 ms\n" +
|
||||
"\tWrite Count: 3\n" +
|
||||
|
|
@ -283,7 +295,7 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
String.format(duplicateTabs(expectedDefaultTable4Output), "table4") +
|
||||
String.format(duplicateTabs(expectedDefaultTable5Output), "table5") +
|
||||
"----------------\n" +
|
||||
"Keyspace : keyspace3\n" +
|
||||
"Keyspace: keyspace3\n" +
|
||||
"\tRead Count: 5\n" +
|
||||
"\tRead Latency: 0.0 ms\n" +
|
||||
"\tWrite Count: 0\n" +
|
||||
|
|
@ -340,7 +352,8 @@ public class TableStatsPrinterTest extends TableStatsTestBase
|
|||
@Test
|
||||
public void testDefaultPrinter() throws Exception
|
||||
{
|
||||
StatsHolder holder = new TestTableStatsHolder(testKeyspaces, "", 0);
|
||||
TestTableStatsHolder holder = new TestTableStatsHolder(testKeyspaces, "", 0);
|
||||
holder.numberOfTables = testKeyspaces.stream().map(ks -> ks.tables.size()).mapToInt(Integer::intValue).sum();
|
||||
StatsPrinter<StatsHolder> printer = TableStatsPrinter.from("", false);
|
||||
try (ByteArrayOutputStream byteStream = new ByteArrayOutputStream())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public class TableStatsTestBase
|
|||
template.oldSSTableCount = 0L;
|
||||
template.spaceUsedLive = "0";
|
||||
template.spaceUsedTotal = "0";
|
||||
template.maxSSTableSize = 0L;
|
||||
template.spaceUsedBySnapshotsTotal = "0";
|
||||
template.percentRepaired = 1.0D;
|
||||
template.bytesRepaired = 0L;
|
||||
|
|
@ -99,6 +100,8 @@ public class TableStatsTestBase
|
|||
template.averageTombstonesPerSliceLastFiveMinutes = Double.NaN;
|
||||
template.maximumTombstonesPerSliceLastFiveMinutes = 0L;
|
||||
template.droppedMutations = "0";
|
||||
template.twcs = null;
|
||||
template.twcsDurationInMillis = 0L;
|
||||
return template;
|
||||
}
|
||||
|
||||
|
|
@ -337,6 +340,10 @@ public class TableStatsTestBase
|
|||
table2.memtableOffHeapMemoryUsed = "314159265";
|
||||
table4.memtableOffHeapMemoryUsed = "141421356";
|
||||
table6.memtableOffHeapMemoryUsed = "161803398";
|
||||
// twcs max duration: 2 > 4 > 1 = 3 = 6 = 5
|
||||
table2.twcsDurationInMillis = 2000L;
|
||||
table4.twcsDurationInMillis = 1000L;
|
||||
table5.twcsDurationInMillis = null;
|
||||
// create test keyspaces from templates
|
||||
testKeyspaces = new ArrayList<>();
|
||||
StatsKeyspace keyspace1 = createStatsKeyspaceTemplate("keyspace1");
|
||||
|
|
|
|||
Loading…
Reference in New Issue