一、在本机建立6个单REDIS节点,并以集群方式运行。
cluster-enabled yes
# Every cluster node has a cluster configuration file. This file is not
# intended to be edited by hand. It is created and updated by Redis nodes.
# Every Redis Cluster node requires a different cluster configuration file.
# Make sure that instances running in the same system do not have
# overlapping cluster configuration file names.
#
cluster-config-file nodes-7001.conf
# Cluster node timeout is the amount of milliseconds a node must be unreachable
# for it to be considered in failure state.
# Most other internal time limits are multiple of the node timeout.
#
cluster-node-timeout 5000
二、创建REDIS集群命令。
./redis-cli --cluster create --cluster-replicas 1 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 127.0.0.1:7006
查看集群状态,可以看到变成了三主三从,每个主节点进行均匀共16384个SLOT槽分配,每次设置KEY时,都对KEY进行CRC16再对16384取模得到SLOTID,然后根据SLOTID映射表找到节点。
从上面可以看到,对不同的KEY进行设置,会自动根据上面的CRC16(KEY)->SLOT->NODE算法分配到相应的节点,
cluster slots 查看槽分配情况。
cluster keyslot 1524877_747965222,查看KEY对应的SLOT
三、redission连接集群方式
application.properties
#集群 redisson.clusterName=mymaster redisson.schema=redis:// redisson.clusterAddresses=redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003,redis://127.0.0.1:7004,redis://127.0.0.1:7005,redis://127.0.0.1:7006 redisson.password=
集群初始化操作
package com.tpw.summaryday.config;
/**
* @Author
* @date 2020-11-14 21:38
*/
@Order(value = 4001)
@ConditionalOnProperty("redisson.password")
@Configuration
@EnableConfigurationProperties({RedissonProperties.class})
public class RedissonAutoConfiguration {
public RedissonAutoConfiguration() {
System.out.println("==========================redis 初始化成功=======================");
}
@Autowired
private RedissonProperties redissonProperties;
/**
* 哨兵模式自动装配
* @return
*/
@Bean(name = "redissonClient")
@ConditionalOnProperty(name="redisson.clusterName")
RedissonClient redissonCluster() {
Config config = new Config();
config.setCodec(new FastJsonCodec());
ClusterServersConfig serverConfig = config.useClusterServers().addNodeAddress(redissonProperties.getClusterAddresses())
.setMasterConnectionPoolSize(redissonProperties.getMasterConnectionPoolSize())
.setSlaveConnectionPoolSize(redissonProperties.getSlaveConnectionPoolSize())
.setTimeout(redissonProperties.getTimeout())
.setReadMode(ReadMode.SLAVE);
if(!StrUtil.isEmpty(redissonProperties.getPassword())) {
serverConfig.setPassword(redissonProperties.getPassword());
}
return Redisson.create(config);
}
}
配置文件映射对象。
@Data
@Configuration
@ConfigurationProperties(prefix = "redisson")
public class RedissonProperties {
private int timeout = 3000;
private String address;
private String password;
private int database = 0;
private int connectionPoolSize = 64;
private int connectionMinimumIdleSize=10;
private int slaveConnectionPoolSize = 250;
private int masterConnectionPoolSize = 250;
private String[] sentinelAddresses;
private String masterName;
private String[] clusterAddresses;
private String clusterName;
}
集群操作跟普通操作完全一样。我们这里做了一个批量插入的过程。
public void saveTradeNoToRedis(List<UserTradeno> tradenos){
// RBatch rBatch = redissonClient.createBatch();
// String keyName = "syncTradeUidSet";
// List<RFuture> rFutureList = new ArrayList<>();
// tradenos.stream().forEach(t->{
// String mapKey = t.getUid() + "_" + t.getTradeNo();
// RFuture goodsNameFuture = rBatch.getBucket(keyName + ":" + mapKey ).setAsync(1);
// rFutureList.add(goodsNameFuture);
// });
//
// RFuture<BatchResult<?>> resultRFuture = rBatch.executeAsync();
// rFutureList.stream().forEach(x->{
// try {
// x.await();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// });
String keyName = "AkbTradeUidSet";
List<RFuture> rFutureList = new ArrayList<>();
tradenos.stream().forEach(t->{
String mapKey = t.getUid() + "_" + t.getTradeNo();
RBucket rBucket = redissonClient.getBucket(/*keyName + ":" + */mapKey);
rBucket.set(System.currentTimeMillis());
});
log.debug(" tt execute end.");
}
查看数据
为什么三台节点都会有数据,是因为他们为集群,客户端工具作了数据全量获取。
我们这次一共插入了1000个节点,然后看下三个节点分别的数据存储情况。
使用dbsize
看到三台节点数据还是分配比较均匀。
四、节点扩容。
增加7007,7008节点,一主一从。
redis-cli --cluster add-node 127.0.0.1:7007 127.0.0.1:7001
新增节点成功,还没有分配槽位,不可用。
重新REHASH分配。注意,要在MASTER节点下执行。
./redis-cli --cluster reshard 127.0.0.1:7001 --cluster-from 8619a43b3ba81b862b8ef0b26d6148ae382ee41c --cluster-to b36b5c17815ac8de246033d06fdcc3fad3a0d0af --cluster-slots 100
REHASH前
看到分配了100个给新节点。
再次REHASH从全部节点迁出500个SLOT到新节点
./redis-cli --cluster reshard 127.0.0.1:7001 --cluster-from all --cluster-to b36b5c17815ac8de246033d06fdcc3fad3a0d0af --cluster-slots 500
我们再次插入1000条数据,看到4个节点,每个变成630个。
五、增加从节点
注意,增加从节点,要在为主节点分配槽位和生成数据之前进行,否则会加入不成功,说不能为非空的主节点加入从节点。
./redis-cli --cluster add-node 127.0.0.1:7008 127.0.0.1:7001
进入redis-cli命令。设置为7007ID的副本。
cluster replicate b36b5c17815ac8de246033d06fdcc3fad3a0d0af
看到已经变成副本了。
./redis-cli --cluster info 127.0.0.1:7001,查看整个集群的KEY数量。
六、重平衡节点数据
./redis-cli --cluster rebalance 127.0.0.1:7001
七、测试主从
把7007关闭
看到7008自动变为主节点。
再启动7007,发现7007变为从节点。