mirror of https://github.com/apache/cassandra
Merge branch 'cassandra-4.0' into cassandra-4.1
This commit is contained in:
commit
02f38208b1
|
|
@ -6,6 +6,7 @@
|
|||
* Reduce info logging from automatic paxos repair (CASSANDRA-19445)
|
||||
* Support legacy plain_text_auth section in credentials file removed unintentionally (CASSANDRA-19498)
|
||||
Merged from 4.0:
|
||||
* Fix latency reported by ideal consistency level monitoring (CASSANDRA-19651)
|
||||
* Use default commitlog settings in test YAMLs (CASSANDRA-19830)
|
||||
* Do not spam log with SSLExceptions (CASSANDRA-18839)
|
||||
* Fix schema.cql created by a snapshot after dropping more than one column (CASSANDRA-19747)
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ public abstract class AbstractWriteResponseHandler<T> implements RequestCallback
|
|||
}
|
||||
}
|
||||
|
||||
public final void expired()
|
||||
protected final void logFailureOrTimeoutToIdealCLDelegate()
|
||||
{
|
||||
//Tracking ideal CL was not configured
|
||||
if (idealCLDelegate == null)
|
||||
|
|
@ -209,6 +209,11 @@ public abstract class AbstractWriteResponseHandler<T> implements RequestCallback
|
|||
}
|
||||
}
|
||||
|
||||
public final void expired()
|
||||
{
|
||||
logFailureOrTimeoutToIdealCLDelegate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum number of endpoints that must respond.
|
||||
*/
|
||||
|
|
@ -259,9 +264,13 @@ public abstract class AbstractWriteResponseHandler<T> implements RequestCallback
|
|||
{
|
||||
//The ideal CL should only count as a strike if the requested CL was achieved.
|
||||
//If the requested CL is not achieved it's fine for the ideal CL to also not be achieved.
|
||||
if (idealCLDelegate != null)
|
||||
if (idealCLDelegate != null && blockFor() + failures <= candidateReplicaCount())
|
||||
{
|
||||
idealCLDelegate.requestedCLAchieved = true;
|
||||
if (idealCLDelegate == this)
|
||||
{
|
||||
replicaPlan.keyspace().metric.idealCLWriteLatency.addNano(nanoTime() - requestTime.startedAtNanos());
|
||||
}
|
||||
}
|
||||
|
||||
condition.signalAll();
|
||||
|
|
@ -280,6 +289,8 @@ public abstract class AbstractWriteResponseHandler<T> implements RequestCallback
|
|||
|
||||
failureReasonByEndpoint.put(from, failureReason);
|
||||
|
||||
logFailureOrTimeoutToIdealCLDelegate();
|
||||
|
||||
if (blockFor() + n > candidateReplicaCount())
|
||||
signal();
|
||||
|
||||
|
|
@ -309,10 +320,6 @@ public abstract class AbstractWriteResponseHandler<T> implements RequestCallback
|
|||
{
|
||||
replicaPlan.keyspace().metric.writeFailedIdealCL.inc();
|
||||
}
|
||||
else
|
||||
{
|
||||
replicaPlan.keyspace().metric.idealCLWriteLatency.addNano(nanoTime() - requestTime.startedAtNanos());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import com.google.common.base.Predicates;
|
||||
import org.apache.cassandra.dht.Murmur3Partitioner;
|
||||
import org.apache.cassandra.exceptions.RequestFailureReason;
|
||||
import org.apache.cassandra.locator.EndpointsForToken;
|
||||
import org.apache.cassandra.locator.ReplicaPlans;
|
||||
import org.junit.Before;
|
||||
|
|
@ -153,17 +154,23 @@ public class WriteResponseHandlerTest
|
|||
//dc1
|
||||
awr.onResponse(createDummyMessage(0));
|
||||
awr.onResponse(createDummyMessage(1));
|
||||
|
||||
// there are not enough responses for ideal EACH_QUORUM yet
|
||||
assertEquals(startingCount, ks.metric.idealCLWriteLatency.latency.getCount());
|
||||
|
||||
//dc2
|
||||
awr.onResponse(createDummyMessage(4));
|
||||
awr.onResponse(createDummyMessage(5));
|
||||
|
||||
// there are enough responses for ideal EACH_QUORUM, we should not wait for all responses
|
||||
assertTrue( TimeUnit.DAYS.toMicros(1) < ks.metric.idealCLWriteLatency.totalLatency.getCount());
|
||||
assertEquals(startingCount + 1, ks.metric.idealCLWriteLatency.latency.getCount());
|
||||
|
||||
//Don't need the others
|
||||
awr.expired();
|
||||
awr.expired();
|
||||
|
||||
assertEquals(0, ks.metric.writeFailedIdealCL.getCount());
|
||||
assertTrue( TimeUnit.DAYS.toMicros(1) < ks.metric.idealCLWriteLatency.totalLatency.getCount());
|
||||
assertEquals(startingCount + 1, ks.metric.idealCLWriteLatency.latency.getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -235,6 +242,30 @@ public class WriteResponseHandlerTest
|
|||
assertEquals(0, ks.metric.idealCLWriteLatency.totalLatency.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedIdealCLIncrementsStatForExplicitOnFailure()
|
||||
{
|
||||
AbstractWriteResponseHandler awr = createWriteResponseHandler(ConsistencyLevel.LOCAL_QUORUM, ConsistencyLevel.EACH_QUORUM);
|
||||
|
||||
long startingCountForWriteFailedIdealCL = ks.metric.writeFailedIdealCL.getCount();
|
||||
long startingCountForIdealCLWriteLatency = ks.metric.idealCLWriteLatency.totalLatency.getCount();
|
||||
|
||||
|
||||
//Succeed in local DC
|
||||
awr.onResponse(createDummyMessage(0));
|
||||
awr.onResponse(createDummyMessage(1));
|
||||
awr.onResponse(createDummyMessage(2));
|
||||
|
||||
|
||||
//Fail in remote DC
|
||||
awr.onFailure(targets.get(3).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onFailure(targets.get(4).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onResponse(createDummyMessage(5));
|
||||
|
||||
assertEquals(startingCountForWriteFailedIdealCL + 1, ks.metric.writeFailedIdealCL.getCount());
|
||||
assertEquals(startingCountForIdealCLWriteLatency, ks.metric.idealCLWriteLatency.totalLatency.getCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that failing to achieve ideal CL doesn't increase the failure counter when not meeting CL
|
||||
* @throws Throwable
|
||||
|
|
@ -260,6 +291,30 @@ public class WriteResponseHandlerTest
|
|||
assertEquals(startingCount, ks.metric.writeFailedIdealCL.getCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failedIdealCLDoesNotIncrementsStatOnExplicitQueryFailure()
|
||||
{
|
||||
AbstractWriteResponseHandler awr = createWriteResponseHandler(ConsistencyLevel.LOCAL_QUORUM, ConsistencyLevel.EACH_QUORUM);
|
||||
|
||||
long startingCountForWriteFailedIdealCL = ks.metric.writeFailedIdealCL.getCount();
|
||||
long startingCountForIdealCLWriteLatency = ks.metric.idealCLWriteLatency.totalLatency.getCount();
|
||||
|
||||
|
||||
//Fail in local DC
|
||||
awr.onFailure(targets.get(0).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onFailure(targets.get(1).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onResponse(createDummyMessage(2));
|
||||
|
||||
|
||||
//Fail in remote DC
|
||||
awr.onFailure(targets.get(3).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onFailure(targets.get(4).endpoint(), RequestFailureReason.TIMEOUT);
|
||||
awr.onResponse(createDummyMessage(5));
|
||||
|
||||
assertEquals(startingCountForWriteFailedIdealCL, ks.metric.writeFailedIdealCL.getCount());
|
||||
assertEquals(startingCountForIdealCLWriteLatency, ks.metric.idealCLWriteLatency.totalLatency.getCount());
|
||||
}
|
||||
|
||||
|
||||
private static AbstractWriteResponseHandler createWriteResponseHandler(ConsistencyLevel cl, ConsistencyLevel ideal)
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue