Search in sources :

Example 1 with ClusterNodeInfo

use of org.redisson.cluster.ClusterNodeInfo in project redisson by redisson.

the class RedissonBatchTest method testSlotMigrationInCluster.

@ParameterizedTest
@MethodSource("data")
public void testSlotMigrationInCluster(BatchOptions batchOptions) throws Exception {
    RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master3 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot3 = new RedisRunner().randomPort().randomDir().nosave();
    ClusterRunner clusterRunner = new ClusterRunner().addNode(master1, slot1).addNode(master2, slot2).addNode(master3, slot3);
    ClusterRunner.ClusterProcesses process = clusterRunner.run();
    Config config = new Config();
    config.useClusterServers().setScanInterval(1000).setSubscriptionMode(SubscriptionMode.MASTER).addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort());
    RedissonClient redisson = Redisson.create(config);
    RedisClientConfig cfg = new RedisClientConfig();
    cfg.setAddress(process.getNodes().iterator().next().getRedisServerAddressAndPort());
    RedisClient c = RedisClient.create(cfg);
    RedisConnection cc = c.connect();
    List<ClusterNodeInfo> mastersList = cc.sync(RedisCommands.CLUSTER_NODES);
    mastersList = mastersList.stream().filter(i -> i.containsFlag(ClusterNodeInfo.Flag.MASTER)).collect(Collectors.toList());
    c.shutdown();
    ClusterNodeInfo destination = mastersList.stream().filter(i -> i.getSlotRanges().iterator().next().getStartSlot() != 10922).findAny().get();
    ClusterNodeInfo source = mastersList.stream().filter(i -> i.getSlotRanges().iterator().next().getStartSlot() == 10922).findAny().get();
    RedisClientConfig sourceCfg = new RedisClientConfig();
    sourceCfg.setAddress(source.getAddress());
    RedisClient sourceClient = RedisClient.create(sourceCfg);
    RedisConnection sourceConnection = sourceClient.connect();
    RedisClientConfig destinationCfg = new RedisClientConfig();
    destinationCfg.setAddress(destination.getAddress());
    RedisClient destinationClient = RedisClient.create(destinationCfg);
    RedisConnection destinationConnection = destinationClient.connect();
    String lockName = "test{kaO}";
    RBatch batch = redisson.createBatch(batchOptions);
    List<RFuture<Boolean>> futures = new ArrayList<>();
    for (int i = 0; i < 5; i++) {
        RFuture<Boolean> f = batch.getMap(lockName).fastPutAsync("" + i, i);
        futures.add(f);
    }
    destinationConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "IMPORTING", source.getNodeId());
    sourceConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "MIGRATING", destination.getNodeId());
    List<String> keys = sourceConnection.sync(RedisCommands.CLUSTER_GETKEYSINSLOT, source.getSlotRanges().iterator().next().getStartSlot(), 100);
    List<Object> params = new ArrayList<Object>();
    params.add(destination.getAddress().getHost());
    params.add(destination.getAddress().getPort());
    params.add("");
    params.add(0);
    params.add(2000);
    params.add("KEYS");
    params.addAll(keys);
    sourceConnection.async(RedisCommands.MIGRATE, params.toArray());
    for (ClusterNodeInfo node : mastersList) {
        RedisClientConfig cc1 = new RedisClientConfig();
        cc1.setAddress(node.getAddress());
        RedisClient ccc = RedisClient.create(cc1);
        RedisConnection connection = ccc.connect();
        connection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "NODE", destination.getNodeId());
        ccc.shutdownAsync();
    }
    Thread.sleep(2000);
    batch.execute();
    futures.forEach(f -> {
        try {
            f.toCompletableFuture().get(1, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            org.junit.jupiter.api.Assertions.fail(e);
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    });
    sourceClient.shutdown();
    destinationClient.shutdown();
    redisson.shutdown();
    process.shutdown();
}
Also used : ClusterProcesses(org.redisson.ClusterRunner.ClusterProcesses) Config(org.redisson.config.Config) RandomString(net.bytebuddy.utility.RandomString) ClusterNodeInfo(org.redisson.cluster.ClusterNodeInfo) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) MethodSource(org.junit.jupiter.params.provider.MethodSource)

Example 2 with ClusterNodeInfo

use of org.redisson.cluster.ClusterNodeInfo in project redisson by redisson.

the class RedissonTopicTest method testSlotMigrationInCluster.

@Test
public void testSlotMigrationInCluster() throws Exception {
    RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master3 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot3 = new RedisRunner().randomPort().randomDir().nosave();
    ClusterRunner clusterRunner = new ClusterRunner().addNode(master1, slot1).addNode(master2, slot2).addNode(master3, slot3);
    ClusterProcesses process = clusterRunner.run();
    Config config = new Config();
    config.useClusterServers().setScanInterval(1000).setSubscriptionMode(SubscriptionMode.MASTER).addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort());
    RedissonClient redisson = Redisson.create(config);
    RedisClientConfig cfg = new RedisClientConfig();
    cfg.setAddress(process.getNodes().iterator().next().getRedisServerAddressAndPort());
    RedisClient c = RedisClient.create(cfg);
    RedisConnection cc = c.connect();
    List<ClusterNodeInfo> mastersList = cc.sync(RedisCommands.CLUSTER_NODES);
    mastersList = mastersList.stream().filter(i -> i.containsFlag(ClusterNodeInfo.Flag.MASTER)).collect(Collectors.toList());
    c.shutdown();
    ClusterNodeInfo destination = mastersList.stream().filter(i -> i.getSlotRanges().iterator().next().getStartSlot() != 10922).findAny().get();
    ClusterNodeInfo source = mastersList.stream().filter(i -> i.getSlotRanges().iterator().next().getStartSlot() == 10922).findAny().get();
    RedisClientConfig sourceCfg = new RedisClientConfig();
    sourceCfg.setAddress(source.getAddress());
    RedisClient sourceClient = RedisClient.create(sourceCfg);
    RedisConnection sourceConnection = sourceClient.connect();
    RedisClientConfig destinationCfg = new RedisClientConfig();
    destinationCfg.setAddress(destination.getAddress());
    RedisClient destinationClient = RedisClient.create(destinationCfg);
    RedisConnection destinationConnection = destinationClient.connect();
    AtomicReference<String> reference = new AtomicReference();
    String channelName = "test{kaO}";
    RTopic topic = redisson.getTopic(channelName);
    topic.addListener(String.class, (ch, m) -> {
        reference.set(m);
    });
    List<String> destList = destinationConnection.sync(RedisCommands.PUBSUB_CHANNELS);
    assertThat(destList).isEmpty();
    List<String> sourceList = sourceConnection.sync(RedisCommands.PUBSUB_CHANNELS);
    assertThat(sourceList).containsOnly(channelName);
    destinationConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "IMPORTING", source.getNodeId());
    sourceConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "MIGRATING", destination.getNodeId());
    List<String> keys = sourceConnection.sync(RedisCommands.CLUSTER_GETKEYSINSLOT, source.getSlotRanges().iterator().next().getStartSlot(), 100);
    List<Object> params = new ArrayList<Object>();
    params.add(destination.getAddress().getHost());
    params.add(destination.getAddress().getPort());
    params.add("");
    params.add(0);
    params.add(2000);
    params.add("KEYS");
    params.addAll(keys);
    sourceConnection.async(RedisCommands.MIGRATE, params.toArray());
    for (ClusterNodeInfo node : mastersList) {
        RedisClientConfig cc1 = new RedisClientConfig();
        cc1.setAddress(node.getAddress());
        RedisClient ccc = RedisClient.create(cc1);
        RedisConnection connection = ccc.connect();
        connection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "NODE", destination.getNodeId());
        ccc.shutdownAsync();
    }
    Thread.sleep(2000);
    topic.publish("mymessage");
    Awaitility.waitAtMost(Duration.ofSeconds(1)).until(() -> reference.get().equals("mymessage"));
    List<String> destList2 = destinationConnection.sync(RedisCommands.PUBSUB_CHANNELS);
    assertThat(destList2).containsOnly(channelName);
    List<String> sourceList2 = sourceConnection.sync(RedisCommands.PUBSUB_CHANNELS);
    assertThat(sourceList2).isEmpty();
    sourceClient.shutdown();
    destinationClient.shutdown();
    redisson.shutdown();
    process.shutdown();
}
Also used : Config(org.redisson.config.Config) RedisClientConfig(org.redisson.client.RedisClientConfig) AtomicReference(java.util.concurrent.atomic.AtomicReference) ClusterNodeInfo(org.redisson.cluster.ClusterNodeInfo) RedisClient(org.redisson.client.RedisClient) ClusterProcesses(org.redisson.ClusterRunner.ClusterProcesses) RedisClientConfig(org.redisson.client.RedisClientConfig) RedisConnection(org.redisson.client.RedisConnection)

Example 3 with ClusterNodeInfo

use of org.redisson.cluster.ClusterNodeInfo in project redisson by redisson.

the class RedissonTest method testMovedRedirectInCluster.

@Test
public void testMovedRedirectInCluster() throws Exception {
    RedisRunner master1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner master3 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot1 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot2 = new RedisRunner().randomPort().randomDir().nosave();
    RedisRunner slot3 = new RedisRunner().randomPort().randomDir().nosave();
    ClusterRunner clusterRunner = new ClusterRunner().addNode(master1, slot1).addNode(master2, slot2).addNode(master3, slot3);
    ClusterProcesses process = clusterRunner.run();
    Config config = new Config();
    config.useClusterServers().setScanInterval(100000).setLoadBalancer(new RandomLoadBalancer()).addNodeAddress(process.getNodes().stream().findAny().get().getRedisServerAddressAndPort());
    RedissonClient redisson = Redisson.create(config);
    RedisClientConfig cfg = new RedisClientConfig();
    cfg.setAddress(process.getNodes().iterator().next().getRedisServerAddressAndPort());
    RedisClient c = RedisClient.create(cfg);
    RedisConnection cc = c.connect();
    List<ClusterNodeInfo> cn = cc.sync(RedisCommands.CLUSTER_NODES);
    c.shutdownAsync();
    cn = cn.stream().filter(i -> i.containsFlag(Flag.MASTER)).collect(Collectors.toList());
    Iterator<ClusterNodeInfo> nodesIter = cn.iterator();
    ClusterNodeInfo source = nodesIter.next();
    ClusterNodeInfo destination = nodesIter.next();
    RedisClientConfig sourceCfg = new RedisClientConfig();
    sourceCfg.setAddress(source.getAddress());
    RedisClient sourceClient = RedisClient.create(sourceCfg);
    RedisConnection sourceConnection = sourceClient.connect();
    RedisClientConfig destinationCfg = new RedisClientConfig();
    destinationCfg.setAddress(destination.getAddress());
    RedisClient destinationClient = RedisClient.create(destinationCfg);
    RedisConnection destinationConnection = destinationClient.connect();
    String key = null;
    int slot = 0;
    for (int i = 0; i < 100000; i++) {
        key = "" + i;
        slot = CRC16.crc16(key.getBytes()) % MasterSlaveConnectionManager.MAX_SLOT;
        if (source.getSlotRanges().iterator().next().getStartSlot() == slot) {
            break;
        }
    }
    redisson.getBucket(key).set("123");
    destinationConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "IMPORTING", source.getNodeId());
    sourceConnection.sync(RedisCommands.CLUSTER_SETSLOT, source.getSlotRanges().iterator().next().getStartSlot(), "MIGRATING", destination.getNodeId());
    List<String> keys = sourceConnection.sync(RedisCommands.CLUSTER_GETKEYSINSLOT, source.getSlotRanges().iterator().next().getStartSlot(), 100);
    List<Object> params = new ArrayList<Object>();
    params.add(destination.getAddress().getHost());
    params.add(destination.getAddress().getPort());
    params.add("");
    params.add(0);
    params.add(2000);
    params.add("KEYS");
    params.addAll(keys);
    sourceConnection.async(RedisCommands.MIGRATE, params.toArray());
    for (ClusterNodeInfo node : cn) {
        RedisClientConfig cc1 = new RedisClientConfig();
        cc1.setAddress(node.getAddress());
        RedisClient ccc = RedisClient.create(cc1);
        RedisConnection connection = ccc.connect();
        connection.sync(RedisCommands.CLUSTER_SETSLOT, slot, "NODE", destination.getNodeId());
        ccc.shutdownAsync();
    }
    redisson.getBucket(key).set("123");
    redisson.getBucket(key).get();
    sourceClient.shutdown();
    destinationClient.shutdown();
    redisson.shutdown();
    process.shutdown();
}
Also used : Config(org.redisson.config.Config) RandomString(net.bytebuddy.utility.RandomString) ClusterNodeInfo(org.redisson.cluster.ClusterNodeInfo) ClusterProcesses(org.redisson.ClusterRunner.ClusterProcesses) RandomLoadBalancer(org.redisson.connection.balancer.RandomLoadBalancer) Test(org.junit.jupiter.api.Test)

Example 4 with ClusterNodeInfo

use of org.redisson.cluster.ClusterNodeInfo in project redisson by redisson.

the class ClusterNodesDecoder method decode.

@Override
public List<ClusterNodeInfo> decode(ByteBuf buf, State state) throws IOException {
    String response = buf.toString(CharsetUtil.UTF_8);
    List<ClusterNodeInfo> nodes = new ArrayList<>();
    for (String nodeInfo : response.split("\n")) {
        ClusterNodeInfo node = new ClusterNodeInfo(nodeInfo);
        String[] params = nodeInfo.split(" ");
        String nodeId = params[0];
        node.setNodeId(nodeId);
        String flags = params[2];
        for (String flag : flags.split(",")) {
            for (Flag nodeInfoFlag : ClusterNodeInfo.Flag.values()) {
                if (nodeInfoFlag.getValue().equalsIgnoreCase(flag)) {
                    node.addFlag(nodeInfoFlag);
                    break;
                }
            }
        }
        if (!node.containsFlag(Flag.NOADDR)) {
            String protocol = "redis://";
            if (ssl) {
                protocol = "rediss://";
            }
            String addr = params[1].split("@")[0];
            String name = addr.substring(0, addr.lastIndexOf(":"));
            if (name.isEmpty()) {
                // skip nodes with empty address
                continue;
            }
            String uri = protocol + addr;
            node.setAddress(uri);
        }
        String slaveOf = params[3];
        if (!"-".equals(slaveOf)) {
            node.setSlaveOf(slaveOf);
        }
        if (params.length > 8) {
            for (int i = 0; i < params.length - 8; i++) {
                String slots = params[i + 8];
                if (slots.contains("-<-") || slots.contains("->-")) {
                    continue;
                }
                String[] parts = slots.split("-");
                if (parts.length == 1) {
                    node.addSlotRange(new ClusterSlotRange(Integer.valueOf(parts[0]), Integer.valueOf(parts[0])));
                } else if (parts.length == 2) {
                    node.addSlotRange(new ClusterSlotRange(Integer.valueOf(parts[0]), Integer.valueOf(parts[1])));
                }
            }
        }
        nodes.add(node);
    }
    return nodes;
}
Also used : ArrayList(java.util.ArrayList) ClusterNodeInfo(org.redisson.cluster.ClusterNodeInfo) Flag(org.redisson.cluster.ClusterNodeInfo.Flag) ClusterSlotRange(org.redisson.cluster.ClusterSlotRange)

Example 5 with ClusterNodeInfo

use of org.redisson.cluster.ClusterNodeInfo in project redisson by redisson.

the class ClusterNodesDecoderTest method test.

@Test
public void test() throws IOException {
    ClusterNodesDecoder decoder = new ClusterNodesDecoder(false);
    ByteBuf buf = Unpooled.buffer();
    String info = "7af253f8c20a3b3fbd481801bd361ec6643c6f0b 192.168.234.129:7001@17001 master - 0 1478865073260 8 connected 5461-10922\n" + "a0d6a300f9f3b139c89cf45b75dbb7e4a01bb6b5 192.168.234.131:7005@17005 slave 5b00efb410f14ba5bb0a153c057e431d9ee4562e 0 1478865072251 5 connected\n" + "454b8aaab7d8687822923da37a91fc0eecbe7a88 192.168.234.130:7002@17002 slave 7af253f8c20a3b3fbd481801bd361ec6643c6f0b 0 1478865072755 8 connected\n" + "5b00efb410f14ba5bb0a153c057e431d9ee4562e 192.168.234.131:7004@17004 master - 0 1478865071746 5 connected 10923-16383\n" + "14edcdebea55853533a24d5cdc560ecc06ec5295 192.168.234.130:7003@17003 myself,master - 0 0 7 connected 0-5460\n" + "58d9f7c6d801aeebaf0e04e1aacb991e7e0ca8ff 192.168.234.129:7000@17000 slave 14edcdebea55853533a24d5cdc560ecc06ec5295 0 1478865071241 7 connected\n";
    byte[] src = info.getBytes();
    buf.writeBytes(src);
    List<ClusterNodeInfo> nodes = decoder.decode(buf, null);
    ClusterNodeInfo node = nodes.get(0);
    Assertions.assertEquals("192.168.234.129", node.getAddress().getHost());
    Assertions.assertEquals(7001, node.getAddress().getPort());
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) ClusterNodeInfo(org.redisson.cluster.ClusterNodeInfo) Test(org.junit.jupiter.api.Test)

Aggregations

ClusterNodeInfo (org.redisson.cluster.ClusterNodeInfo)5 ClusterProcesses (org.redisson.ClusterRunner.ClusterProcesses)3 Config (org.redisson.config.Config)3 RandomString (net.bytebuddy.utility.RandomString)2 Test (org.junit.jupiter.api.Test)2 ByteBuf (io.netty.buffer.ByteBuf)1 ArrayList (java.util.ArrayList)1 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)1 AtomicReference (java.util.concurrent.atomic.AtomicReference)1 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)1 MethodSource (org.junit.jupiter.params.provider.MethodSource)1 RedisClient (org.redisson.client.RedisClient)1 RedisClientConfig (org.redisson.client.RedisClientConfig)1 RedisConnection (org.redisson.client.RedisConnection)1 Flag (org.redisson.cluster.ClusterNodeInfo.Flag)1 ClusterSlotRange (org.redisson.cluster.ClusterSlotRange)1 RandomLoadBalancer (org.redisson.connection.balancer.RandomLoadBalancer)1