Skip to content

Commit dc89b8c

Browse files
committed
Extend nodetool tablestats for dictionary memory usage
patch by Stefan Miklosovic; reviewed by Yifan Cai for CASSANDRA-20940
1 parent e621d8a commit dc89b8c

File tree

16 files changed

+94
-1
lines changed

16 files changed

+94
-1
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
5.1
2+
* Extend nodetool tablestats for dictionary memory usage (CASSANDRA-20940)
23
* Introduce separate GCInspector thresholds for concurrent GC events (CASSANDRA-20980)
34
* Reduce contention in MemtableAllocator.allocate (CASSANDRA-20226)
45
* Add export, list, import sub-commands for nodetool compressiondictionary (CASSANDRA-20941)

src/java/org/apache/cassandra/db/compression/CompressionDictionary.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,15 @@ public interface CompressionDictionary extends AutoCloseable
5656
*/
5757
int checksum();
5858

59+
/**
60+
* Get memory occupied of this dictionary as a whole.
61+
* Use for metrics exposing used memory in total. The value
62+
* return by this method is a best-effort estimation.
63+
*
64+
* @return memory occuppied by this compression dictionary, in bytes
65+
*/
66+
int estimatedOccupiedMemoryBytes();
67+
5968
/**
6069
* Get the kind of the compression algorithm
6170
*

src/java/org/apache/cassandra/db/compression/CompressionDictionaryCache.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.apache.cassandra.db.compression;
2020

2121
import java.time.Duration;
22+
import java.util.concurrent.atomic.AtomicInteger;
2223
import java.util.concurrent.atomic.AtomicReference;
2324
import javax.annotation.Nullable;
2425

@@ -112,6 +113,14 @@ public void add(@Nullable CompressionDictionary compressionDictionary)
112113
}
113114
}
114115

116+
@Override
117+
public long cachedDictionariesMemoryUsed()
118+
{
119+
AtomicInteger value = new AtomicInteger();
120+
cache.asMap().forEach((key, dict) -> value.addAndGet(dict.estimatedOccupiedMemoryBytes()));
121+
return value.get();
122+
}
123+
115124
@Override
116125
public synchronized void close()
117126
{

src/java/org/apache/cassandra/db/compression/CompressionDictionaryManager.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ public void add(@Nullable CompressionDictionary compressionDictionary)
192192
cache.add(compressionDictionary);
193193
}
194194

195+
@Override
196+
public long cachedDictionariesMemoryUsed()
197+
{
198+
return cache.cachedDictionariesMemoryUsed();
199+
}
200+
195201
@Override
196202
public void onNewDictionaryTrained(CompressionDictionary.DictId dictionaryId)
197203
{

src/java/org/apache/cassandra/db/compression/ICompressionDictionaryCache.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,11 @@ public interface ICompressionDictionaryCache extends AutoCloseable
5353
* @param compressionDictionary the compression dictionary to cache, may be null
5454
*/
5555
void add(@Nullable CompressionDictionary compressionDictionary);
56+
57+
/**
58+
* Gives number of bytes cached compression dictionaries occupy in this cache.
59+
*
60+
* @return number of bytes cached dictionaries occupy
61+
*/
62+
long cachedDictionariesMemoryUsed();
5663
}

src/java/org/apache/cassandra/db/compression/ZstdCompressionDictionary.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public int checksum()
8686
return checksum;
8787
}
8888

89+
@Override
90+
public int estimatedOccupiedMemoryBytes()
91+
{
92+
int occupied = rawDictionary.length;
93+
occupied += dictDecompress != null ? rawDictionary.length : 0;
94+
occupied += zstdDictCompressPerLevel.size() * rawDictionary.length;
95+
96+
return occupied;
97+
}
98+
8999
@Override
90100
public boolean equals(Object o)
91101
{

src/java/org/apache/cassandra/metrics/TableMetrics.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
import org.apache.cassandra.config.DatabaseDescriptor;
4646
import org.apache.cassandra.db.ColumnFamilyStore;
4747
import org.apache.cassandra.db.Keyspace;
48+
import org.apache.cassandra.db.compression.CompressionDictionaryManager;
4849
import org.apache.cassandra.db.lifecycle.SSTableSet;
4950
import org.apache.cassandra.db.lifecycle.View;
5051
import org.apache.cassandra.db.memtable.Memtable;
@@ -154,6 +155,8 @@ public class TableMetrics
154155
public final Gauge<Long> maxPartitionSize;
155156
/** Size of the smallest compacted partition */
156157
public final Gauge<Long> meanPartitionSize;
158+
/** Memory usage of cached compression dictionaries */
159+
public final Gauge<Long> compressionDictionariesMemoryUsed;
157160
/** Off heap memory used by compression meta data*/
158161
public final Gauge<Long> compressionMetadataOffHeapMemoryUsed;
159162
/** Tombstones scanned in queries on this CF */
@@ -771,6 +774,19 @@ public Long getValue()
771774
return count > 0 ? sum / count : 0;
772775
}
773776
});
777+
compressionDictionariesMemoryUsed = createTableGauge("CompressionDictionariesMemoryUsed", new Gauge<Long>()
778+
{
779+
@Override
780+
public Long getValue()
781+
{
782+
CompressionDictionaryManager compressionDictionaryManager = cfs.compressionDictionaryManager();
783+
if (compressionDictionaryManager != null)
784+
return compressionDictionaryManager.cachedDictionariesMemoryUsed();
785+
else
786+
return 0L;
787+
}
788+
});
789+
774790
compressionMetadataOffHeapMemoryUsed = createTableGauge("CompressionMetadataOffHeapMemoryUsed", new Gauge<Long>()
775791
{
776792
public Long getValue()

src/java/org/apache/cassandra/tools/NodeProbe.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,6 +2088,7 @@ else if (!Strings.isNullOrEmpty(ks))
20882088
case "BloomFilterFalseRatio":
20892089
case "BloomFilterOffHeapMemoryUsed":
20902090
case "IndexSummaryOffHeapMemoryUsed":
2091+
case "CompressionDictionariesMemoryUsed":
20912092
case "CompressionMetadataOffHeapMemoryUsed":
20922093
case "CompressionRatio":
20932094
case "EstimatedColumnCountHistogram":

src/java/org/apache/cassandra/tools/nodetool/TableStats.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public class TableStats extends AbstractCommand
5858
+ "average_tombstones_per_slice_last_five_minutes, bloom_filter_false_positives, "
5959
+ "bloom_filter_false_ratio, bloom_filter_off_heap_memory_used, bloom_filter_space_used, "
6060
+ "compacted_partition_maximum_bytes, compacted_partition_mean_bytes, "
61-
+ "compacted_partition_minimum_bytes, compression_metadata_off_heap_memory_used, "
61+
+ "compacted_partition_minimum_bytes, compression_dictionaries_memory_used, compression_metadata_off_heap_memory_used, "
6262
+ "full_name, index_summary_off_heap_memory_used, local_read_count, "
6363
+ "local_read_latency_ms, local_write_latency_ms, "
6464
+ "maximum_live_cells_per_slice_last_five_minutes, "

src/java/org/apache/cassandra/tools/nodetool/stats/StatsTable.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public class StatsTable
5757
public String bloomFilterOffHeapMemoryUsed;
5858
public boolean indexSummaryOffHeapUsed = false;
5959
public String indexSummaryOffHeapMemoryUsed;
60+
public boolean compressionDictionariesUsed = false;
61+
public String compressionDictionariesMemoryUsed;
6062
public boolean compressionMetadataOffHeapUsed = false;
6163
public String compressionMetadataOffHeapMemoryUsed;
6264
public long compactedPartitionMinimumBytes;

0 commit comments

Comments
 (0)