You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2014/02/25 17:45:16 UTC
[3/6] git commit: Compare scores of full replica ordering in DES.
Patch by Tyler Hobbs, reviewed by brandonwilliams for CASSANDRA-6883
Compare scores of full replica ordering in DES.
Patch by Tyler Hobbs, reviewed by brandonwilliams for CASSANDRA-6883
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/d21c0c93
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/d21c0c93
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/d21c0c93
Branch: refs/heads/trunk
Commit: d21c0c932c7d962feb958159578cf2cfb471a648
Parents: cd2c438
Author: Brandon Williams <br...@apache.org>
Authored: Tue Feb 25 10:40:58 2014 -0600
Committer: Brandon Williams <br...@apache.org>
Committed: Tue Feb 25 10:42:02 2014 -0600
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../locator/DynamicEndpointSnitch.java | 25 +++--
.../locator/DynamicEndpointSnitchTest.java | 108 ++++++++-----------
3 files changed, 61 insertions(+), 73 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d21c0c93/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index f3a854c..ee138ce 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.0.6
+ * Compare scores of full replica ordering in DES (CASSANDRA-6883)
* fix CME in SessionInfo updateProgress affecting netstats (CASSANDRA-6577)
* Allow repairing between specific replicas (CASSANDRA-6440)
* Allow per-dc enabling of hints (CASSANDRA-6157)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d21c0c93/src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java b/src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java
index e9d55d4..00c3618 100644
--- a/src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java
+++ b/src/java/org/apache/cassandra/locator/DynamicEndpointSnitch.java
@@ -156,16 +156,27 @@ public class DynamicEndpointSnitch extends AbstractEndpointSnitch implements ILa
{
if (addresses.size() < 2)
return;
+
subsnitch.sortByProximity(address, addresses);
- Double first = scores.get(addresses.get(0));
- if (first == null)
- return;
- for (InetAddress addr : addresses)
+ ArrayList<Double> subsnitchOrderedScores = new ArrayList<>(addresses.size());
+ for (InetAddress inet : addresses)
{
- Double next = scores.get(addr);
- if (next == null)
+ Double score = scores.get(inet);
+ if (score == null)
return;
- if ((first - next) / first > BADNESS_THRESHOLD)
+ subsnitchOrderedScores.add(score);
+ }
+
+ // Sort the scores and then compare them (positionally) to the scores in the subsnitch order.
+ // If any of the subsnitch-ordered scores exceed the optimal/sorted score by BADNESS_THRESHOLD, use
+ // the score-sorted ordering instead of the subsnitch ordering.
+ ArrayList<Double> sortedScores = new ArrayList<>(subsnitchOrderedScores);
+ Collections.sort(sortedScores);
+
+ Iterator<Double> sortedScoreIterator = sortedScores.iterator();
+ for (Double subsnitchScore : subsnitchOrderedScores)
+ {
+ if (subsnitchScore > (sortedScoreIterator.next() * (1.0 + BADNESS_THRESHOLD)))
{
sortByProximityWithScore(address, addresses);
return;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/d21c0c93/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java b/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java
index dca87a2..e23bcfa 100644
--- a/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java
+++ b/test/unit/org/apache/cassandra/locator/DynamicEndpointSnitchTest.java
@@ -21,7 +21,8 @@ package org.apache.cassandra.locator;
import java.io.IOException;
import java.net.InetAddress;
-import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.service.StorageService;
@@ -29,89 +30,64 @@ import org.junit.Test;
import org.apache.cassandra.utils.FBUtilities;
+import static org.junit.Assert.assertEquals;
+
public class DynamicEndpointSnitchTest
{
+
+ private static void setScores(DynamicEndpointSnitch dsnitch, int rounds, List<InetAddress> hosts, Integer... scores) throws InterruptedException
+ {
+ for (int round = 0; round < rounds; round++)
+ {
+ for (int i = 0; i < hosts.size(); i++)
+ dsnitch.receiveTiming(hosts.get(i), scores[i]);
+ }
+ Thread.sleep(150);
+ }
+
@Test
public void testSnitch() throws InterruptedException, IOException, ConfigurationException
{
// do this because SS needs to be initialized before DES can work properly.
StorageService.instance.initClient(0);
- int sleeptime = 150;
SimpleSnitch ss = new SimpleSnitch();
DynamicEndpointSnitch dsnitch = new DynamicEndpointSnitch(ss, String.valueOf(ss.hashCode()));
InetAddress self = FBUtilities.getBroadcastAddress();
- ArrayList<InetAddress> order = new ArrayList<InetAddress>();
- InetAddress host1 = InetAddress.getByName("127.0.0.4");
- InetAddress host2 = InetAddress.getByName("127.0.0.2");
- InetAddress host3 = InetAddress.getByName("127.0.0.3");
+ InetAddress host1 = InetAddress.getByName("127.0.0.2");
+ InetAddress host2 = InetAddress.getByName("127.0.0.3");
+ InetAddress host3 = InetAddress.getByName("127.0.0.4");
+ List<InetAddress> hosts = Arrays.asList(host1, host2, host3);
// first, make all hosts equal
- for (int i = 0; i < 5; i++)
- {
- dsnitch.receiveTiming(host1, 1L);
- dsnitch.receiveTiming(host2, 1L);
- dsnitch.receiveTiming(host3, 1L);
- }
-
- Thread.sleep(sleeptime);
-
- order.add(host1);
- order.add(host2);
- order.add(host3);
- assert dsnitch.getSortedListByProximity(self, order).equals(order);
+ setScores(dsnitch, 1, hosts, 10, 10, 10);
+ List<InetAddress> order = Arrays.asList(host1, host2, host3);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
// make host1 a little worse
- dsnitch.receiveTiming(host1, 2L);
- dsnitch.receiveTiming(host2, 1L);
- dsnitch.receiveTiming(host3, 1L);
- Thread.sleep(sleeptime);
-
- order.clear();
- order.add(host2);
- order.add(host3);
- order.add(host1);
- assert dsnitch.getSortedListByProximity(self, order).equals(order);
+ setScores(dsnitch, 1, hosts, 20, 10, 10);
+ order = Arrays.asList(host2, host3, host1);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
// make host2 as bad as host1
- dsnitch.receiveTiming(host2, 2L);
- dsnitch.receiveTiming(host1, 1L);
- dsnitch.receiveTiming(host3, 1L);
- Thread.sleep(sleeptime);
-
- order.clear();
- order.add(host3);
- order.add(host1);
- order.add(host2);
- assert dsnitch.getSortedListByProximity(self, order).equals(order);
+ setScores(dsnitch, 2, hosts, 15, 20, 10);
+ order = Arrays.asList(host3, host1, host2);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
// make host3 the worst
- for (int i = 0; i < 2; i++)
- {
- dsnitch.receiveTiming(host1, 1L);
- dsnitch.receiveTiming(host2, 1L);
- dsnitch.receiveTiming(host3, 2L);
- }
- Thread.sleep(sleeptime);
-
- order.clear();
- order.add(host1);
- order.add(host2);
- order.add(host3);
- assert dsnitch.getSortedListByProximity(self, order).equals(order);
+ setScores(dsnitch, 3, hosts, 10, 10, 30);
+ order = Arrays.asList(host1, host2, host3);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
// make host3 equal to the others
- for (int i = 0; i < 2; i++)
- {
- dsnitch.receiveTiming(host1, 1L);
- dsnitch.receiveTiming(host2, 1L);
- dsnitch.receiveTiming(host3, 1L);
- }
- Thread.sleep(sleeptime);
-
- order.clear();
- order.add(host1);
- order.add(host2);
- order.add(host3);
- assert dsnitch.getSortedListByProximity(self, order).equals(order);
+ setScores(dsnitch, 5, hosts, 10, 10, 10);
+ order = Arrays.asList(host1, host2, host3);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
+
+ /// Tests CASSANDRA-6683 improvements
+ // make the scores differ enough from the ideal order that we sort by score; under the old
+ // dynamic snitch behavior (where we only compared neighbors), these wouldn't get sorted
+ setScores(dsnitch, 20, hosts, 10, 70, 20);
+ order = Arrays.asList(host1, host3, host2);
+ assertEquals(order, dsnitch.getSortedListByProximity(self, Arrays.asList(host1, host2, host3)));
}
-}
+}
\ No newline at end of file