Search in sources :

Example 1 with DLSocketAddress

use of com.twitter.distributedlog.service.DLSocketAddress in project distributedlog by twitter.

the class TestConsistentHashRoutingService method testPerformServerSetChangeOnServerSet.

@Test(timeout = 60000)
public void testPerformServerSetChangeOnServerSet() throws Exception {
    TestServerSetWatcher serverSetWatcher = new TestServerSetWatcher();
    ConsistentHashRoutingService routingService = new ConsistentHashRoutingService(serverSetWatcher, 997, Integer.MAX_VALUE, NullStatsReceiver.get());
    int basePort = 3180;
    int numHosts = 4;
    Set<DLSocketAddress> addresses1 = Sets.newConcurrentHashSet();
    Set<DLSocketAddress> addresses2 = Sets.newConcurrentHashSet();
    Set<DLSocketAddress> addresses3 = Sets.newConcurrentHashSet();
    // fill up the addresses1
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + i);
        DLSocketAddress dsa = new DLSocketAddress(i, inetAddress);
        addresses1.add(dsa);
    }
    // fill up the addresses2 - overlap with addresses1
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + numHosts + i);
        DLSocketAddress dsa = new DLSocketAddress(i + 2, inetAddress);
        addresses2.add(dsa);
    }
    // fill up the addresses3 - not overlap with addresses2
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + 10 + i);
        DLSocketAddress dsa = new DLSocketAddress(i, inetAddress);
        addresses3.add(dsa);
    }
    final List<SocketAddress> leftAddresses = Lists.newArrayList();
    final List<SocketAddress> joinAddresses = Lists.newArrayList();
    RoutingService.RoutingListener routingListener = new RoutingService.RoutingListener() {

        @Override
        public void onServerLeft(SocketAddress address) {
            synchronized (leftAddresses) {
                leftAddresses.add(address);
                leftAddresses.notifyAll();
            }
        }

        @Override
        public void onServerJoin(SocketAddress address) {
            synchronized (joinAddresses) {
                joinAddresses.add(address);
                joinAddresses.notifyAll();
            }
        }
    };
    routingService.registerListener(routingListener);
    serverSetWatcher.notifyChanges(ImmutableSet.copyOf(addresses1));
    routingService.startService();
    synchronized (joinAddresses) {
        while (joinAddresses.size() < numHosts) {
            joinAddresses.wait();
        }
    }
    // validate 4 nodes joined
    synchronized (joinAddresses) {
        assertEquals(numHosts, joinAddresses.size());
    }
    synchronized (leftAddresses) {
        assertEquals(0, leftAddresses.size());
    }
    assertEquals(numHosts, routingService.shardId2Address.size());
    assertEquals(numHosts, routingService.address2ShardId.size());
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + i);
        assertTrue(routingService.address2ShardId.containsKey(inetAddress));
        int shardId = routingService.address2ShardId.get(inetAddress);
        assertEquals(i, shardId);
        SocketAddress sa = routingService.shardId2Address.get(shardId);
        assertNotNull(sa);
        assertEquals(inetAddress, sa);
    }
    // update addresses2 - 2 new hosts joined, 2 old hosts left
    serverSetWatcher.notifyChanges(ImmutableSet.copyOf(addresses2));
    synchronized (joinAddresses) {
        while (joinAddresses.size() < numHosts + 2) {
            joinAddresses.wait();
        }
    }
    synchronized (leftAddresses) {
        while (leftAddresses.size() < 2) {
            leftAddresses.wait();
        }
    }
    assertEquals(numHosts + 2, routingService.shardId2Address.size());
    assertEquals(numHosts + 2, routingService.address2ShardId.size());
    // first 2 shards should not leave
    for (int i = 0; i < 2; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + i);
        assertTrue(routingService.address2ShardId.containsKey(inetAddress));
        int shardId = routingService.address2ShardId.get(inetAddress);
        assertEquals(i, shardId);
        SocketAddress sa = routingService.shardId2Address.get(shardId);
        assertNotNull(sa);
        assertEquals(inetAddress, sa);
    }
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + numHosts + i);
        assertTrue(routingService.address2ShardId.containsKey(inetAddress));
        int shardId = routingService.address2ShardId.get(inetAddress);
        assertEquals(i + 2, shardId);
        SocketAddress sa = routingService.shardId2Address.get(shardId);
        assertNotNull(sa);
        assertEquals(inetAddress, sa);
    }
    // update addresses3
    serverSetWatcher.notifyChanges(ImmutableSet.copyOf(addresses3));
    synchronized (joinAddresses) {
        while (joinAddresses.size() < numHosts + 2 + numHosts) {
            joinAddresses.wait();
        }
    }
    synchronized (leftAddresses) {
        while (leftAddresses.size() < 2 + numHosts) {
            leftAddresses.wait();
        }
    }
    assertEquals(numHosts + 2, routingService.shardId2Address.size());
    assertEquals(numHosts + 2, routingService.address2ShardId.size());
    // first 4 shards should leave
    for (int i = 0; i < numHosts; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + 10 + i);
        assertTrue(routingService.address2ShardId.containsKey(inetAddress));
        int shardId = routingService.address2ShardId.get(inetAddress);
        assertEquals(i, shardId);
        SocketAddress sa = routingService.shardId2Address.get(shardId);
        assertNotNull(sa);
        assertEquals(inetAddress, sa);
    }
    // the other 2 shards should be still there
    for (int i = 0; i < 2; i++) {
        InetSocketAddress inetAddress = new InetSocketAddress("127.0.0.1", basePort + numHosts + 2 + i);
        assertTrue(routingService.address2ShardId.containsKey(inetAddress));
        int shardId = routingService.address2ShardId.get(inetAddress);
        assertEquals(numHosts + i, shardId);
        SocketAddress sa = routingService.shardId2Address.get(shardId);
        assertNotNull(sa);
        assertEquals(inetAddress, sa);
    }
}
Also used : DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) InetSocketAddress(java.net.InetSocketAddress) DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) SocketAddress(java.net.SocketAddress) InetSocketAddress(java.net.InetSocketAddress) Test(org.junit.Test)

Example 2 with DLSocketAddress

use of com.twitter.distributedlog.service.DLSocketAddress in project distributedlog by twitter.

the class ConsistentHashRoutingService method performServerSetChange.

@Override
protected synchronized void performServerSetChange(ImmutableSet<DLSocketAddress> serviceInstances) {
    Set<SocketAddress> joinedList = new HashSet<SocketAddress>();
    Set<SocketAddress> removedList = new HashSet<SocketAddress>();
    Map<Integer, SocketAddress> newMap = new HashMap<Integer, SocketAddress>();
    synchronized (shardId2Address) {
        for (DLSocketAddress serviceInstance : serviceInstances) {
            if (serviceInstance.getShard() >= 0) {
                newMap.put(serviceInstance.getShard(), serviceInstance.getSocketAddress());
            } else {
                Integer shard = address2ShardId.get(serviceInstance.getSocketAddress());
                if (null == shard) {
                    // Assign a random negative shardId
                    int shardId;
                    do {
                        shardId = Math.min(-1, (int) (Math.random() * Integer.MIN_VALUE));
                    } while (null != shardId2Address.get(shardId));
                    shard = shardId;
                }
                newMap.put(shard, serviceInstance.getSocketAddress());
            }
        }
    }
    Map<Integer, SocketAddress> left;
    synchronized (shardId2Address) {
        MapDifference<Integer, SocketAddress> difference = Maps.difference(shardId2Address, newMap);
        left = difference.entriesOnlyOnLeft();
        for (Map.Entry<Integer, SocketAddress> shardEntry : left.entrySet()) {
            int shard = shardEntry.getKey();
            if (shard >= 0) {
                SocketAddress host = shardId2Address.get(shard);
                if (null != host) {
                    // we don't remove those hosts that just disappered on serverset proactively,
                    // since it might be just because serverset become flaky
                    // address2ShardId.remove(host);
                    // circle.remove(shard, host);
                    logger.info("Shard {} ({}) left temporarily.", shard, host);
                }
            } else {
                // shard id is negative - they are resolved from finagle name, which instances don't have shard id
                // in this case, if they are removed from serverset, we removed them directly
                SocketAddress host = shardEntry.getValue();
                if (null != host) {
                    removeHostInternal(host, Optional.<Throwable>absent());
                    removedList.add(host);
                }
            }
        }
        // we need to find if any shards are replacing old shards
        for (Map.Entry<Integer, SocketAddress> shard : newMap.entrySet()) {
            SocketAddress oldHost = shardId2Address.get(shard.getKey());
            SocketAddress newHost = shard.getValue();
            if (!newHost.equals(oldHost)) {
                join(shard.getKey(), newHost, removedList);
                joinedList.add(newHost);
            }
        }
    }
    for (SocketAddress addr : removedList) {
        for (RoutingListener listener : listeners) {
            listener.onServerLeft(addr);
        }
    }
    for (SocketAddress addr : joinedList) {
        for (RoutingListener listener : listeners) {
            listener.onServerJoin(addr);
        }
    }
}
Also used : AtomicInteger(java.util.concurrent.atomic.AtomicInteger) DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) HashMap(java.util.HashMap) SocketAddress(java.net.SocketAddress) DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) SortedMap(java.util.SortedMap) HashSet(java.util.HashSet)

Example 3 with DLSocketAddress

use of com.twitter.distributedlog.service.DLSocketAddress in project distributedlog by twitter.

the class ServerSetRoutingService method performServerSetChange.

protected synchronized void performServerSetChange(ImmutableSet<DLSocketAddress> serverSet) {
    Set<SocketAddress> newSet = new HashSet<SocketAddress>();
    for (DLSocketAddress serviceInstance : serverSet) {
        newSet.add(serviceInstance.getSocketAddress());
    }
    Set<SocketAddress> removed;
    Set<SocketAddress> added;
    synchronized (hostSet) {
        removed = Sets.difference(hostSet, newSet).immutableCopy();
        added = Sets.difference(newSet, hostSet).immutableCopy();
        for (SocketAddress node : removed) {
            if (hostSet.remove(node)) {
                logger.info("Node {} left.", node);
            }
        }
        for (SocketAddress node : added) {
            if (hostSet.add(node)) {
                logger.info("Node {} joined.", node);
            }
        }
    }
    for (SocketAddress addr : removed) {
        for (RoutingListener listener : listeners) {
            listener.onServerLeft(addr);
        }
    }
    for (SocketAddress addr : added) {
        for (RoutingListener listener : listeners) {
            listener.onServerJoin(addr);
        }
    }
    synchronized (hostSet) {
        hostList = new ArrayList<SocketAddress>(hostSet);
        Collections.sort(hostList, HostComparator.instance);
        logger.info("Host list becomes : {}.", hostList);
    }
}
Also used : DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) DLSocketAddress(com.twitter.distributedlog.service.DLSocketAddress) SocketAddress(java.net.SocketAddress) HashSet(java.util.HashSet)

Aggregations

DLSocketAddress (com.twitter.distributedlog.service.DLSocketAddress)3 SocketAddress (java.net.SocketAddress)3 HashSet (java.util.HashSet)2 InetSocketAddress (java.net.InetSocketAddress)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 SortedMap (java.util.SortedMap)1 TreeMap (java.util.TreeMap)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 Test (org.junit.Test)1