Beispiel #1
0
        public void TokenAwarePolicyRoundRobinsOnLocalReplicas()
        {
            var hostList = new List <Host>
            {
                //5 local nodes and 4 remote
                TestHelper.CreateHost("0.0.0.1", "dc1"),
                TestHelper.CreateHost("0.0.0.2", "dc1"),
                TestHelper.CreateHost("0.0.0.3", "dc2"),
                TestHelper.CreateHost("0.0.0.4", "dc2"),
                TestHelper.CreateHost("0.0.0.5", "dc1"),
                TestHelper.CreateHost("0.0.0.6", "dc1"),
                TestHelper.CreateHost("0.0.0.7", "dc2"),
                TestHelper.CreateHost("0.0.0.8", "dc2"),
                TestHelper.CreateHost("0.0.0.9", "dc1")
            };
            var clusterMock = new Mock <ICluster>(MockBehavior.Strict);

            clusterMock
            .Setup(c => c.AllHosts())
            .Returns(hostList)
            .Verifiable();
            clusterMock
            .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>()))
            .Returns <string, byte[]>((keyspace, key) =>
            {
                var i = key[0];
                return(hostList.Where(h =>
                {
                    //The host at with address == k and the next one
                    var address = TestHelper.GetLastAddressByte(h);
                    return address == i || address == i + 1;
                }).ToList());
            })
            .Verifiable();

            var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2));

            policy.Initialize(clusterMock.Object);

            var firstHosts = new ConcurrentBag <Host>();
            var k          = new RoutingKey {
                RawRoutingKey = new byte[] { 1 }
            };
            // key for host :::1 and :::2
            const int times  = 10000;
            Action    action = () =>
            {
                var h = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).First();
                firstHosts.Add(h);
            };

            TestHelper.ParallelInvoke(action, times);
            Assert.AreEqual(times, firstHosts.Count);
            double queryPlansWithHost1AsFirst = firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 1);
            double queryPlansWithHost2AsFirst = firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 2);

            Assert.AreEqual(times, queryPlansWithHost1AsFirst + queryPlansWithHost2AsFirst);
            // Around half will to one and half to the other
            Assert.That(queryPlansWithHost1AsFirst / times, Is.GreaterThan(0.45).And.LessThan(0.55));
            Assert.That(queryPlansWithHost2AsFirst / times, Is.GreaterThan(0.45).And.LessThan(0.55));
            clusterMock.Verify();
        }
Beispiel #2
0
        public void TokenMap_NetworkTopologyStrategy_With_Keyspace_Test()
        {
            var hosts = new List <Host>
            {
                { TestHelper.CreateHost("192.168.0.0", "dc1", "rack1", new HashSet <string> {
                        "0"
                    }) },
                { TestHelper.CreateHost("192.168.0.1", "dc1", "rack1", new HashSet <string> {
                        "100"
                    }) },
                { TestHelper.CreateHost("192.168.0.2", "dc1", "rack1", new HashSet <string> {
                        "200"
                    }) },
                { TestHelper.CreateHost("192.168.0.100", "dc2", "rack1", new HashSet <string> {
                        "1"
                    }) },
                { TestHelper.CreateHost("192.168.0.101", "dc2", "rack1", new HashSet <string> {
                        "101"
                    }) },
                { TestHelper.CreateHost("192.168.0.102", "dc2", "rack1", new HashSet <string> {
                        "201"
                    }) }
            };
            const string strategy  = ReplicationStrategies.NetworkTopologyStrategy;
            var          keyspaces = new List <KeyspaceMetadata>
            {
                //network strategy with rf 2 per dc
                new KeyspaceMetadata(null, "ks1", true, strategy, new Dictionary <string, int> {
                    { "dc1", 2 }, { "dc2", 2 }
                }),
                //Testing simple (even it is not supposed to be)
                new KeyspaceMetadata(null, "ks2", true, ReplicationStrategies.SimpleStrategy, new Dictionary <string, int> {
                    { "replication_factor", 3 }
                }),
                //network strategy with rf 3 dc1 and 1 dc2
                new KeyspaceMetadata(null, "ks3", true, strategy, new Dictionary <string, int> {
                    { "dc1", 3 }, { "dc2", 1 }, { "dc3", 5 }
                }),
                //network strategy with rf 4 dc1
                new KeyspaceMetadata(null, "ks4", true, strategy, new Dictionary <string, int> {
                    { "dc1", 5 }
                })
            };
            var tokenMap = TokenMap.Build("Murmur3Partitioner", hosts, keyspaces);
            //KS1
            //the primary replica and the next
            var replicas = tokenMap.GetReplicas("ks1", new M3PToken(0));

            Assert.AreEqual("0,100,1,101", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));
            //The next replica should be the first
            replicas = tokenMap.GetReplicas("ks1", new M3PToken(200));
            Assert.AreEqual("2,102,0,100", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));
            //The closest replica and the next
            replicas = tokenMap.GetReplicas("ks1", new M3PToken(190));
            Assert.AreEqual("2,102,0,100", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));

            //KS2
            //Simple strategy: 3 tokens no matter which dc
            replicas = tokenMap.GetReplicas("ks2", new M3PToken(5000));
            Assert.AreEqual("0,100,1", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));

            //KS3
            replicas = tokenMap.GetReplicas("ks3", new M3PToken(0));
            Assert.AreEqual("0,100,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));
            replicas = tokenMap.GetReplicas("ks3", new M3PToken(201));
            Assert.AreEqual("102,0,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));

            //KS4
            replicas = tokenMap.GetReplicas("ks4", new M3PToken(0));
            Assert.AreEqual("0,1,2", String.Join(",", replicas.Select(TestHelper.GetLastAddressByte)));
        }
Beispiel #3
0
        public void TokenAwarePolicyReturnsLocalReplicasFirst()
        {
            var hostList = new List <Host>
            {
                //5 local nodes and 4 remote
                TestHelper.CreateHost("0.0.0.1", "dc1"),
                TestHelper.CreateHost("0.0.0.2", "dc1"),
                TestHelper.CreateHost("0.0.0.3", "dc2"),
                TestHelper.CreateHost("0.0.0.4", "dc2"),
                TestHelper.CreateHost("0.0.0.5", "dc1"),
                TestHelper.CreateHost("0.0.0.6", "dc1"),
                TestHelper.CreateHost("0.0.0.7", "dc2"),
                TestHelper.CreateHost("0.0.0.8", "dc2"),
                TestHelper.CreateHost("0.0.0.9", "dc1")
            };
            var n           = 2;
            var clusterMock = new Mock <ICluster>();

            clusterMock
            .Setup(c => c.AllHosts())
            .Returns(hostList)
            .Verifiable();
            clusterMock
            .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>()))
            .Returns <string, byte[]>((keyspace, key) =>
            {
                var i = key[0];
                return(hostList.Where(h =>
                {
                    //The host at with address == k || address == k + n
                    var address = TestHelper.GetLastAddressByte(h);
                    return address == i || address == i + n;
                }).ToList());
            })
            .Verifiable();

            var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2));

            policy.Initialize(clusterMock.Object);

            //key for host :::1 and :::3
            var k = new RoutingKey {
                RawRoutingKey = new byte[] { 1 }
            };
            var hosts = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).ToList();

            //5 local hosts + 2 remote hosts
            Assert.AreEqual(7, hosts.Count);
            //local replica first
            Assert.AreEqual(1, TestHelper.GetLastAddressByte(hosts[0]));
            clusterMock.Verify();

            //key for host :::2 and :::5
            k = new RoutingKey {
                RawRoutingKey = new byte[] { 2 }
            };
            n     = 3;
            hosts = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).ToList();
            Assert.AreEqual(7, hosts.Count);
            //local replicas first
            CollectionAssert.AreEquivalent(new[] { 2, 5 }, hosts.Take(2).Select(TestHelper.GetLastAddressByte));
            //next should be local nodes
            Assert.AreEqual("dc1", hosts[2].Datacenter);
            Assert.AreEqual("dc1", hosts[3].Datacenter);
            Assert.AreEqual("dc1", hosts[4].Datacenter);
            clusterMock.Verify();
        }
Beispiel #4
0
        public void DCAwareRoundRobinPolicyWithNodesChanging()
        {
            var hostList = new ConcurrentBag <Host>
            {
                TestHelper.CreateHost("0.0.0.1", "dc1"),
                TestHelper.CreateHost("0.0.0.2", "dc2"),
                TestHelper.CreateHost("0.0.0.3", "dc1"),
                TestHelper.CreateHost("0.0.0.4", "dc2"),
                TestHelper.CreateHost("0.0.0.5", "dc1"),
                TestHelper.CreateHost("0.0.0.6", "dc2"),
                TestHelper.CreateHost("0.0.0.7", "dc1"),
                TestHelper.CreateHost("0.0.0.8", "dc2"),
                TestHelper.CreateHost("0.0.0.9", "dc1"),
                TestHelper.CreateHost("0.0.0.10", "dc2")
            };
            const string localDc = "dc1";
            //to remove the host 3
            var hostToRemove = hostList.First(h => TestHelper.GetLastAddressByte(h) == 3);
            var clusterMock  = new Mock <ICluster>();

            clusterMock
            .Setup(c => c.AllHosts())
            .Returns(() =>
            {
                return(hostList.ToList());
            });
            //Initialize the balancing policy
            var policy = new DCAwareRoundRobinPolicy(localDc, 1);

            policy.Initialize(clusterMock.Object);

            var    hostYielded = new ConcurrentBag <IEnumerable <Host> >();
            Action action      = () => hostYielded.Add(policy.NewQueryPlan(null, null).ToList());

            //Invoke without nodes changing
            TestHelper.ParallelInvoke(action, 100);
            Assert.True(hostYielded.Any(hl => hl.Any(h => h == hostToRemove)));

            var actionList = new List <Action>(Enumerable.Repeat <Action>(action, 1000));


            actionList.Insert(200, () =>
            {
                var host = TestHelper.CreateHost("0.0.0.11", "dc1");
                //raise event and then add
                clusterMock.Raise(c => c.HostAdded += null, host);
                hostList.Add(host);
            });
            actionList.Insert(400, () =>
            {
                var host = TestHelper.CreateHost("0.0.0.12", "dc1");
                //first add and then raise event
                hostList.Add(host);
                clusterMock.Raise(c => c.HostAdded += null, host);
            });

            actionList.Insert(400, () =>
            {
                var host = hostToRemove;
                hostList = new ConcurrentBag <Host>(hostList.Where(h => h != hostToRemove));
                clusterMock.Raise(c => c.HostRemoved += null, host);
            });

            //Invoke it with nodes being modified
            TestHelper.ParallelInvoke(actionList);
            //Clear the host yielded so far
            hostYielded = new ConcurrentBag <IEnumerable <Host> >();
            //Invoke it a some of times more in parallel
            TestHelper.ParallelInvoke(action, 100);
            //The removed node should not be returned
            Assert.False(hostList.Any(h => h == hostToRemove));
            Assert.False(hostYielded.Any(hl => hl.Any(h => h == hostToRemove)));
        }
Beispiel #5
0
        public void DCAwareRoundRobinPolicyTestInParallel()
        {
            var hostList = new List <Host>
            {
                TestHelper.CreateHost("0.0.0.1", "dc1"),
                TestHelper.CreateHost("0.0.0.2", "dc2"),
                TestHelper.CreateHost("0.0.0.3", "dc1"),
                TestHelper.CreateHost("0.0.0.4", "dc2"),
                TestHelper.CreateHost("0.0.0.5", "dc1"),
                TestHelper.CreateHost("0.0.0.6", "dc2"),
                TestHelper.CreateHost("0.0.0.7", "dc1"),
                TestHelper.CreateHost("0.0.0.8", "dc2"),
                TestHelper.CreateHost("0.0.0.9", "dc1"),
                TestHelper.CreateHost("0.0.0.10", "dc2")
            };
            var          localHostsLength = hostList.Count(h => h.Datacenter == "dc1");
            const string localDc          = "dc1";

            var clusterMock = new Mock <ICluster>();

            clusterMock
            .Setup(c => c.AllHosts())
            .Returns(hostList);

            //Initialize the balancing policy
            var policy = new DCAwareRoundRobinPolicy(localDc, 1);

            policy.Initialize(clusterMock.Object);

            var    allHosts   = new ConcurrentBag <Host>();
            var    firstHosts = new ConcurrentBag <Host>();
            Action action     = () =>
            {
                var hosts = policy.NewQueryPlan(null, null).ToList();
                //Check that the value is not repeated
                Assert.AreEqual(0, hosts.GroupBy(x => x)
                                .Where(g => g.Count() > 1)
                                .Select(y => y.Key)
                                .Count());
                firstHosts.Add(hosts[0]);
                //Add to the general list
                foreach (var h in hosts)
                {
                    allHosts.Add(h);
                }
            };

            var       actions = new List <Action>();
            const int times   = 100;

            for (var i = 0; i < times; i++)
            {
                actions.Add(action);
            }
            TestHelper.ParallelInvoke(actions);

            //Check that the first nodes where different
            foreach (var h in hostList)
            {
                if (h.Datacenter == localDc)
                {
                    Assert.AreEqual(times / localHostsLength, firstHosts.Count(hc => hc == h));
                }
                else
                {
                    Assert.AreEqual(0, firstHosts.Count(hc => hc == h));
                }
            }
            clusterMock.Verify();
        }
Beispiel #6
0
        public void Build_Should_OnlyCallOncePerReplicationConfiguration_When_MultipleKeyspacesWithSameReplicationOptions()
        {
            var hosts = new List <Host>
            {
                { TestHelper.CreateHost("192.168.0.0", "dc1", "rack", new HashSet <string> {
                        "0"
                    }) },
                { TestHelper.CreateHost("192.168.0.1", "dc1", "rack", new HashSet <string> {
                        "10"
                    }) },
                { TestHelper.CreateHost("192.168.0.2", "dc1", "rack", new HashSet <string> {
                        "20"
                    }) },
                { TestHelper.CreateHost("192.168.0.3", "dc2", "rack", new HashSet <string> {
                        "30"
                    }) },
                { TestHelper.CreateHost("192.168.0.4", "dc2", "rack", new HashSet <string> {
                        "40"
                    }) }
            };

            var factory   = new ProxyReplicationStrategyFactory();
            var keyspaces = new List <KeyspaceMetadata>
            {
                // unique configurations
                TokenTests.CreateSimpleKeyspace("ks1", 2, factory),
                TokenTests.CreateSimpleKeyspace("ks2", 10, factory),
                TokenTests.CreateSimpleKeyspace("ks3", 5, factory),
                TokenTests.CreateNetworkTopologyKeyspace("ks4", new Dictionary <string, int> {
                    { "dc1", 2 }, { "dc2", 2 }
                }, factory),
                TokenTests.CreateNetworkTopologyKeyspace("ks5", new Dictionary <string, int> {
                    { "dc1", 1 }, { "dc2", 2 }
                }, factory),
                TokenTests.CreateNetworkTopologyKeyspace("ks6", new Dictionary <string, int> {
                    { "dc1", 1 }
                }, factory),

                // duplicate configurations
                TokenTests.CreateNetworkTopologyKeyspace("ks7", new Dictionary <string, int> {
                    { "dc1", 2 }, { "dc2", 2 }
                }, factory),
                TokenTests.CreateNetworkTopologyKeyspace("ks8", new Dictionary <string, int> {
                    { "dc1", 1 }
                }, factory),
                TokenTests.CreateNetworkTopologyKeyspace("ks9", new Dictionary <string, int> {
                    { "dc1", 1 }, { "dc2", 2 }
                }, factory),
                TokenTests.CreateSimpleKeyspace("ks10", 10, factory),
                TokenTests.CreateSimpleKeyspace("ks11", 2, factory)
            };
            var tokenMap = TokenMap.Build("Murmur3Partitioner", hosts, keyspaces);

            var proxyStrategies = keyspaces.Select(k => (ProxyReplicationStrategy)k.Strategy).ToList();

            Assert.AreEqual(6, proxyStrategies.Count(strategy => strategy.Calls > 0));

            AssertOnlyOneStrategyIsCalled(proxyStrategies, 0, 10);
            AssertOnlyOneStrategyIsCalled(proxyStrategies, 1, 9);
            AssertOnlyOneStrategyIsCalled(proxyStrategies, 2);
            AssertOnlyOneStrategyIsCalled(proxyStrategies, 3, 6);
            AssertOnlyOneStrategyIsCalled(proxyStrategies, 4, 8);
            AssertOnlyOneStrategyIsCalled(proxyStrategies, 5, 7);
        }
        public void TokenAwarePolicyRoundRobinsOnLocalReplicas()
        {
            var hostList = new List <Host>
            {
                //5 local nodes and 4 remote
                TestHelper.CreateHost("0.0.0.1", "dc1"),
                TestHelper.CreateHost("0.0.0.2", "dc1"),
                TestHelper.CreateHost("0.0.0.3", "dc2"),
                TestHelper.CreateHost("0.0.0.4", "dc2"),
                TestHelper.CreateHost("0.0.0.5", "dc1"),
                TestHelper.CreateHost("0.0.0.6", "dc1"),
                TestHelper.CreateHost("0.0.0.7", "dc2"),
                TestHelper.CreateHost("0.0.0.8", "dc2"),
                TestHelper.CreateHost("0.0.0.9", "dc1")
            };
            var clusterMock = new Mock <ICluster>(MockBehavior.Strict);

            clusterMock
            .Setup(c => c.AllHosts())
            .Returns(hostList)
            .Verifiable();
            clusterMock
            .Setup(c => c.GetReplicas(It.IsAny <string>(), It.IsAny <byte[]>()))
            .Returns <string, byte[]>((keyspace, key) =>
            {
                var i = key[0];
                return(hostList.Where(h =>
                {
                    //The host at with address == k and the next one
                    var address = TestHelper.GetLastAddressByte(h);
                    return address == i || address == i + 1;
                }).ToList());
            })
            .Verifiable();

            var policy = new TokenAwarePolicy(new DCAwareRoundRobinPolicy("dc1", 2));

            policy.Initialize(clusterMock.Object);

            var firstHosts = new ConcurrentBag <Host>();
            var k          = new RoutingKey {
                RawRoutingKey = new byte[] { 1 }
            };
            //key for host :::1 and :::2
            var       actions = new List <Action>();
            const int times   = 100;

            for (var i = 0; i < times; i++)
            {
                actions.Add(() =>
                {
                    var h = policy.NewQueryPlan(null, new SimpleStatement().SetRoutingKey(k)).First();
                    firstHosts.Add(h);
                });
            }


            var parallelOptions = new ParallelOptions();

            parallelOptions.TaskScheduler          = new ThreadPerTaskScheduler();
            parallelOptions.MaxDegreeOfParallelism = 1000;

            Parallel.Invoke(parallelOptions, actions.ToArray());
            Assert.AreEqual(times, firstHosts.Count);
            //Half the times
            Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 1));
            Assert.AreEqual(times / 2, firstHosts.Count(h => TestHelper.GetLastAddressByte(h) == 2));

            clusterMock.Verify();
        }