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:
Stefan Miklosovic 2023-02-24 14:56:50 +01:00
parent 180f0f0b5b
commit 4841794028
No known key found for this signature in database
GPG Key ID: 32F35CB2F546D93E
17 changed files with 214 additions and 33 deletions

View File

@ -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)

View File

@ -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
---------

View File

@ -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).

View File

@ -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()
{

View File

@ -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();
}

View File

@ -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";

View File

@ -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");

View File

@ -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":

View File

@ -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",

View File

@ -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;
}

View File

@ -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,

View File

@ -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.
*/

View File

@ -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)
{

View File

@ -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);
}

View File

@ -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

View File

@ -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())
{

View File

@ -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");