You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2017/08/14 14:29:36 UTC

[3/6] cassandra git commit: Randomize batchlog endpoint selection with only 1 or 2 racks

Randomize batchlog endpoint selection with only 1 or 2 racks

patch by Daniel Cranford; reviewed by Aleksey Yeschenko for
CASSANDRA-12884


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c2b635ac
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c2b635ac
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c2b635ac

Branch: refs/heads/trunk
Commit: c2b635ac240ae8d9375fd96791a5aba903a94498
Parents: fab3845
Author: dcranford <da...@red-alpha.com>
Authored: Wed Aug 9 10:20:03 2017 -0400
Committer: Aleksey Yeschenko <al...@yeschenko.com>
Committed: Mon Aug 14 15:23:09 2017 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/batchlog/BatchlogManager.java     | 19 ++++++++---
 .../batchlog/BatchlogEndpointFilterTest.java    | 33 ++++++++++++++++++--
 3 files changed, 47 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2b635ac/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 2e9e8ad..358dd04 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 3.0.15
+ * Randomize batchlog endpoint selection with only 1 or 2 racks (CASSANDRA-12884)
  * Fix digest calculation for counter cells (CASSANDRA-13750)
  * Fix ColumnDefinition.cellValueType() for non-frozen collection and change SSTabledump to use type.toJSONString() (CASSANDRA-13573)
  * Skip materialized view addition if the base table doesn't exist (CASSANDRA-13737)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2b635ac/src/java/org/apache/cassandra/batchlog/BatchlogManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/batchlog/BatchlogManager.java b/src/java/org/apache/cassandra/batchlog/BatchlogManager.java
index f5133bb..b614fc5 100644
--- a/src/java/org/apache/cassandra/batchlog/BatchlogManager.java
+++ b/src/java/org/apache/cassandra/batchlog/BatchlogManager.java
@@ -523,9 +523,14 @@ public class BatchlogManager implements BatchlogManagerMBean
 
             if (validated.keySet().size() == 1)
             {
-                // we have only 1 `other` rack
-                Collection<InetAddress> otherRack = Iterables.getOnlyElement(validated.asMap().values());
-                return Lists.newArrayList(Iterables.limit(otherRack, 2));
+                /*
+                 * we have only 1 `other` rack to select replicas from (whether it be the local rack or a single non-local rack)
+                 * pick two random nodes from there; we are guaranteed to have at least two nodes in the single remaining rack
+                 * because of the preceding if block.
+                 */
+                List<InetAddress> otherRack = Lists.newArrayList(validated.values());
+                shuffle(otherRack);
+                return otherRack.subList(0, 2);
             }
 
             // randomize which racks we pick from if more than 2 remaining
@@ -537,7 +542,7 @@ public class BatchlogManager implements BatchlogManagerMBean
             else
             {
                 racks = Lists.newArrayList(validated.keySet());
-                Collections.shuffle((List<String>) racks);
+                shuffle((List<String>) racks);
             }
 
             // grab a random member of up to two racks
@@ -562,5 +567,11 @@ public class BatchlogManager implements BatchlogManagerMBean
         {
             return ThreadLocalRandom.current().nextInt(bound);
         }
+
+        @VisibleForTesting
+        protected void shuffle(List<?> list)
+        {
+            Collections.shuffle(list);
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c2b635ac/test/unit/org/apache/cassandra/batchlog/BatchlogEndpointFilterTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/batchlog/BatchlogEndpointFilterTest.java b/test/unit/org/apache/cassandra/batchlog/BatchlogEndpointFilterTest.java
index 23aeaaa..7db1cfa 100644
--- a/test/unit/org/apache/cassandra/batchlog/BatchlogEndpointFilterTest.java
+++ b/test/unit/org/apache/cassandra/batchlog/BatchlogEndpointFilterTest.java
@@ -20,7 +20,9 @@ package org.apache.cassandra.batchlog;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
+import java.util.List;
 
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.Multimap;
@@ -87,8 +89,28 @@ public class BatchlogEndpointFilterTest
                 .put("1", InetAddress.getByName("111"))
                 .build();
         Collection<InetAddress> result = new TestEndpointFilter(LOCAL, endpoints).filter();
-        // result should contain random two distinct values
-        assertThat(new HashSet<>(result).size(), is(2));
+        // result should be the last two non-local replicas
+        // (Collections.shuffle has been replaced with Collections.reverse for testing)
+        assertThat(result.size(), is(2));
+        assertThat(result, JUnitMatchers.hasItem(InetAddress.getByName("11")));
+        assertThat(result, JUnitMatchers.hasItem(InetAddress.getByName("111")));
+    }
+
+    @Test
+    public void shouldSelectTwoRandomHostsFromSingleRack() throws UnknownHostException
+    {
+        Multimap<String, InetAddress> endpoints = ImmutableMultimap.<String, InetAddress> builder()
+                .put(LOCAL, InetAddress.getByName("1"))
+                .put(LOCAL, InetAddress.getByName("11"))
+                .put(LOCAL, InetAddress.getByName("111"))
+                .put(LOCAL, InetAddress.getByName("1111"))
+                .build();
+        Collection<InetAddress> result = new TestEndpointFilter(LOCAL, endpoints).filter();
+        // result should be the last two non-local replicas
+        // (Collections.shuffle has been replaced with Collections.reverse for testing)
+        assertThat(result.size(), is(2));
+        assertThat(result, JUnitMatchers.hasItem(InetAddress.getByName("111")));
+        assertThat(result, JUnitMatchers.hasItem(InetAddress.getByName("1111")));
     }
 
     private static class TestEndpointFilter extends BatchlogManager.EndpointFilter
@@ -111,5 +133,12 @@ public class BatchlogEndpointFilterTest
             // We don't need random behavior here
             return bound - 1;
         }
+
+        @Override
+        protected void shuffle(List<?> list)
+        {
+            // We don't need random behavior here
+            Collections.reverse(list);
+        }
     }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org