diff --git a/src/java/org/apache/cassandra/metrics/ReadRepairMetrics.java b/src/java/org/apache/cassandra/metrics/ReadRepairMetrics.java new file mode 100644 index 0000000000..3f48fee8ec --- /dev/null +++ b/src/java/org/apache/cassandra/metrics/ReadRepairMetrics.java @@ -0,0 +1,25 @@ +package org.apache.cassandra.metrics; + +import java.util.concurrent.TimeUnit; + +import com.yammer.metrics.Metrics; +import com.yammer.metrics.core.Counter; +import com.yammer.metrics.core.Gauge; +import com.yammer.metrics.core.Meter; +import com.yammer.metrics.core.MetricName; +import com.yammer.metrics.util.RatioGauge; + +/** + * Metrics related to Read Repair. + */ +public class ReadRepairMetrics { + public static final String GROUP_NAME = "org.apache.cassandra.metrics"; + public static final String TYPE_NAME = "ReadRepair"; + + public static final Meter repairedBlocking = + Metrics.newMeter(new MetricName(GROUP_NAME, TYPE_NAME, "RepairedBlocking"), "RepairedBlocking", TimeUnit.SECONDS); + public static final Meter repairedBackground = + Metrics.newMeter(new MetricName(GROUP_NAME, TYPE_NAME, "RepairedBackground"), "RepairedBackground", TimeUnit.SECONDS); + public static final Meter attempted = + Metrics.newMeter(new MetricName(GROUP_NAME, TYPE_NAME, "Attempted"), "Attempted", TimeUnit.SECONDS); +} diff --git a/src/java/org/apache/cassandra/service/AbstractReadExecutor.java b/src/java/org/apache/cassandra/service/AbstractReadExecutor.java index 1c7c6f9ac4..f944507817 100644 --- a/src/java/org/apache/cassandra/service/AbstractReadExecutor.java +++ b/src/java/org/apache/cassandra/service/AbstractReadExecutor.java @@ -25,6 +25,7 @@ import org.apache.cassandra.concurrent.Stage; import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.Schema; +import org.apache.cassandra.config.ReadRepairDecision; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.ConsistencyLevel; import org.apache.cassandra.db.ReadCommand; @@ -33,6 +34,7 @@ import org.apache.cassandra.db.Row; import org.apache.cassandra.db.Table; import org.apache.cassandra.exceptions.ReadTimeoutException; import org.apache.cassandra.exceptions.UnavailableException; +import org.apache.cassandra.metrics.ReadRepairMetrics; import org.apache.cassandra.net.MessageOut; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.service.StorageProxy.LocalReadRunnable; @@ -125,7 +127,14 @@ public abstract class AbstractReadExecutor Table table = Table.open(command.table); List allReplicas = StorageProxy.getLiveSortedEndpoints(table, command.key); CFMetaData metaData = Schema.instance.getCFMetaData(command.table, command.cfName); - List queryTargets = consistency_level.filterForQuery(table, allReplicas, metaData.newReadRepairDecision()); + + ReadRepairDecision rrDecision = metaData.newReadRepairDecision(); + + if (rrDecision != ReadRepairDecision.NONE) { + ReadRepairMetrics.attempted.mark(); + } + + List queryTargets = consistency_level.filterForQuery(table, allReplicas, rrDecision); if (StorageService.instance.isClientMode()) { diff --git a/src/java/org/apache/cassandra/service/ReadCallback.java b/src/java/org/apache/cassandra/service/ReadCallback.java index 79e15b17dc..fe7f4d78a4 100644 --- a/src/java/org/apache/cassandra/service/ReadCallback.java +++ b/src/java/org/apache/cassandra/service/ReadCallback.java @@ -34,6 +34,7 @@ import org.apache.cassandra.db.ReadCommand; import org.apache.cassandra.db.Table; import org.apache.cassandra.exceptions.ReadTimeoutException; import org.apache.cassandra.exceptions.UnavailableException; +import org.apache.cassandra.metrics.ReadRepairMetrics; import org.apache.cassandra.net.IAsyncCallback; import org.apache.cassandra.net.MessageIn; import org.apache.cassandra.net.MessageOut; @@ -181,7 +182,9 @@ public class ReadCallback implements IAsyncCallback repairHandler = exec.handler.withNewResolver(resolver); @@ -1931,4 +1935,17 @@ public class StorageProxy implements StorageProxyMBean public Long getTruncateRpcTimeout() { return DatabaseDescriptor.getTruncateRpcTimeout(); } public void setTruncateRpcTimeout(Long timeoutInMillis) { DatabaseDescriptor.setTruncateRpcTimeout(timeoutInMillis); } public void reloadTriggerClass() { TriggerExecutor.instance.reloadClasses(); } + + + public long getReadRepairAttempted() { + return ReadRepairMetrics.attempted.count(); + } + + public long getReadRepairRepairedBlocking() { + return ReadRepairMetrics.repairedBlocking.count(); + } + + public long getReadRepairRepairedBackground() { + return ReadRepairMetrics.repairedBackground.count(); + } } diff --git a/src/java/org/apache/cassandra/service/StorageProxyMBean.java b/src/java/org/apache/cassandra/service/StorageProxyMBean.java index f482fc7945..05b9c7821a 100644 --- a/src/java/org/apache/cassandra/service/StorageProxyMBean.java +++ b/src/java/org/apache/cassandra/service/StorageProxyMBean.java @@ -90,4 +90,8 @@ public interface StorageProxyMBean public void setTruncateRpcTimeout(Long timeoutInMillis); public void reloadTriggerClass(); + + public long getReadRepairAttempted(); + public long getReadRepairRepairedBlocking(); + public long getReadRepairRepairedBackground(); } diff --git a/src/java/org/apache/cassandra/tools/NodeCmd.java b/src/java/org/apache/cassandra/tools/NodeCmd.java index ca81857639..9f524fcb83 100644 --- a/src/java/org/apache/cassandra/tools/NodeCmd.java +++ b/src/java/org/apache/cassandra/tools/NodeCmd.java @@ -665,6 +665,8 @@ public class NodeCmd outs.printf(" Error retrieving file data for %s%n", host); } } + + outs.printf("Read Repair Statistics:%nAttempted: %d%nMismatch (Blocking): %d%nMismatch (Background): %d%n", probe.getReadRepairAttempted(), probe.getReadRepairRepairedBlocking(), probe.getReadRepairRepairedBackground()); MessagingServiceMBean ms = probe.msProxy; outs.printf("%-25s", "Pool Name"); diff --git a/src/java/org/apache/cassandra/tools/NodeProbe.java b/src/java/org/apache/cassandra/tools/NodeProbe.java index 31df3b9157..af94d1436d 100644 --- a/src/java/org/apache/cassandra/tools/NodeProbe.java +++ b/src/java/org/apache/cassandra/tools/NodeProbe.java @@ -828,6 +828,21 @@ public class NodeProbe { return failed; } + + public long getReadRepairAttempted() + { + return spProxy.getReadRepairAttempted(); + } + + public long getReadRepairRepairedBlocking() + { + return spProxy.getReadRepairRepairedBlocking(); + } + + public long getReadRepairRepairedBackground() + { + return spProxy.getReadRepairRepairedBackground(); + } } class ColumnFamilyStoreMBeanIterator implements Iterator>