赞
踩
仅在同一台服务器测试
安装redis完成之后复制六份
# 创建集群存放redis的文件夹
mkdir redis-cluster
cd ../
cp -r redis/ redis-cluster/redis-9301
cp -r redis/ redis-cluster/redis-9302
cp -r redis/ redis-cluster/redis-9303
cp -r redis/ redis-cluster/redis-9304
cp -r redis/ redis-cluster/redis-9305
cp -r redis/ redis-cluster/redis-9306
cd redis-cluster
# 编写公共redis.conf文件 vim redis.conf # 注释该行使其他电脑可以访问 # bind 127.0.0.1 # 改为yes,使实例后台运行 daemonize yes # 开启集群支持 cluster-enabled yes # 集群节点不可用的最长时间,超过该时间进行从库故障转移 cluster-node-timeout 15000 # 指定为外网IP cluster-announce-ip 59.110.xx.xxx # 设置密码 requirepass 123456
进入复制的每个redis文件夹中修改master 的 redis.conf文件为:
# 拼接公共redis.conf文件
include /usr/local/redis/redis-cluster/redis.conf
pidfile "/var/run/redis_9301.pid"
port 9301
dbfilename "dump9301.rdb"
# 指定节点文件名称
cluster-config-file nodes-9301.conf
再修改slave redis中修改redis.conf文件为:
# 拼接公共redis.conf文件
include /usr/local/redis/redis-cluster/redis.conf
pidfile "/var/run/redis_9304.pid"
port 9304
dbfilename "dump9304.rdb"
# 指定节点文件名称
cluster-config-file nodes-9304.conf
# 设置密码
masterauth 123456
9301、9302、9303为master
9304、9305、9306为slave
启动脚本
#!/bin/bash redis_path="/usr/local/redis/redis-cluster/" cd ${redis_path} ps aux | grep redis | grep cluster | grep -v grep | awk '{print $2}' | xargs kill -9 # ps -ef | grep -v grep | grep redis | awk -F' ' '{print $2}' | xargs kill -9 cluster_num=`ps aux | grep redis | grep cluster | wc -l` if [ "${cluster_num}" -le 0 ] then echo -e "===== Success: Has killed all cluster progress." else echo -e "===== Fail: There still are ${cluster_num} is alive.\n" exit 1 fi rm -rf ${redis_path}redis*/dump* rm -rf ${redis_path}redis*/nodes* data_num=`find ${redis_path} -type f | grep -E "dump*|nodes*" | wc -l` if [ "${data_num}" -le 0 ] then echo -e "===== Success: Has remove all dump.rdb and nodes configure file." else echo -e "===== Fail: There still are files is exist,Use command: \n\tfind ${redis_path} -type f | grep -E \"dump.rbd|nodes*\" \nto search, and then remove them manually.\n" exit 1 fi cd redis-9301/ ./redis-server redis.conf cd ../redis-9302/ ./redis-server redis.conf cd ../redis-9303/ ./redis-server redis.conf cd ../redis-9304/ ./redis-server redis.conf cd ../redis-9305/ ./redis-server redis.conf cd ../redis-9306/ ./redis-server redis.conf
创建集群脚本
#!/bin/bash
# 创建集群
cd /usr/local/redis/redis-5.0.14/src
./redis-cli --cluster create --cluster-replicas 1 59.110.xx.xxx:9301 59.110.xx.xxx:9302 59.110.xx.xxx:9303 59.110.xx.xxx:9304 59.110.xx.xxx:9305 59.110.xx.xxx:9306 -a 123456
–cluster create: 创建集群
–cluster-relicas: 集群副本数。 这里是1,是1主机1从机的模式,如果设置为2(即:2台从机)会失败。因为集群中至少要有3个主机,所以设置2台从机时,至少需要9个节点才可以。
最后的参数中列出全部的redis主机IP地址和端口号。
-a: 后边跟的是redis的密码
# 启动各redis节点 ./restart_redis.sh # 创建集群 [root@hcg redis-cluster]# ./create_cluster.sh Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe. >>> Performing hash slots allocation on 6 nodes... Master[0] -> Slots 0 - 5460 Master[1] -> Slots 5461 - 10922 Master[2] -> Slots 10923 - 16383 Adding replica 59.110.xx.xxx:9305 to 59.110.xx.xxx:9301 Adding replica 59.110.xx.xxx:9306 to 59.110.xx.xxx:9302 Adding replica 59.110.xx.xxx:9304 to 59.110.xx.xxx:9303 >>> Trying to optimize slaves allocation for anti-affinity [WARNING] Some slaves are in the same host as their master M: b78b59b8cadb3e1f77d520a164597777e2bc18f8 59.110.xx.xxx:9301 slots:[0-5460] (5461 slots) master M: dc1cdaa729ebe03c7b9702025426c2b86df70da2 59.110.xx.xxx:9302 slots:[5461-10922] (5462 slots) master M: 651576fcd8fb66e83212351331bfb110b3a3a524 59.110.xx.xxx:9303 slots:[10923-16383] (5461 slots) master S: e7cf094e16c520f2d1faf9ae65f68e97c1fba562 59.110.xx.xxx:9304 replicates dc1cdaa729ebe03c7b9702025426c2b86df70da2 S: 8a61f7e96b7160127921c9f0a9e4e9f65963d71f 59.110.xx.xxx:9305 replicates 651576fcd8fb66e83212351331bfb110b3a3a524 S: 52eed0573d4b9f20f0b61434bebfec05ce8dcac5 59.110.xx.xxx:9306 replicates b78b59b8cadb3e1f77d520a164597777e2bc18f8 Can I set the above configuration? (type 'yes' to accept):
输入yes
Can I set the above configuration? (type 'yes' to accept): yes >>> Nodes configuration updated >>> Assign a different config epoch to each node >>> Sending CLUSTER MEET messages to join the cluster Waiting for the cluster to join . >>> Performing Cluster Check (using node 59.110.xx.xxx:9301) M: b78b59b8cadb3e1f77d520a164597777e2bc18f8 59.110.xx.xxx:9301 slots:[0-5460] (5461 slots) master 1 additional replica(s) S: 52eed0573d4b9f20f0b61434bebfec05ce8dcac5 59.110.xx.xxx:9306 slots: (0 slots) slave replicates b78b59b8cadb3e1f77d520a164597777e2bc18f8 S: 8a61f7e96b7160127921c9f0a9e4e9f65963d71f 59.110.xx.xxx:9305 slots: (0 slots) slave replicates 651576fcd8fb66e83212351331bfb110b3a3a524 M: 651576fcd8fb66e83212351331bfb110b3a3a524 59.110.xx.xxx:9303 slots:[10923-16383] (5461 slots) master 1 additional replica(s) S: e7cf094e16c520f2d1faf9ae65f68e97c1fba562 59.110.xx.xxx:9304 slots: (0 slots) slave replicates dc1cdaa729ebe03c7b9702025426c2b86df70da2 M: dc1cdaa729ebe03c7b9702025426c2b86df70da2 59.110.xx.xxx:9302 slots:[5461-10922] (5462 slots) master 1 additional replica(s) [OK] All nodes agree about slots configuration. >>> Check for open slots... >>> Check slots coverage... [OK] All 16384 slots covered. [root@hcg redis-cluster]#
./redis-cli -p 9301 -a 123456 -c
59.110.xx.xx:9302>
1、-p:集群中任意一个redis服务的端口号
2、-a:redis的密码
3、-c:集群模式
可使用:cluster nodes 命令查看集群状态,查询结果如下:
59.110.xx.xxx:9302> cluster nodes
b78b59b8cadb3e1f77d520a164597777e2bc18f8 59.110.xx.xxx:9301@19301 master - 0 1659782936979 1 connected 0-5460
e7cf094e16c520f2d1faf9ae65f68e97c1fba562 59.110.xx.xxx:9304@19304 slave dc1cdaa729ebe03c7b9702025426c2b86df70da2 0 1659782935977 4 connected
8a61f7e96b7160127921c9f0a9e4e9f65963d71f 59.110.xx.xxx:9305@19305 slave 651576fcd8fb66e83212351331bfb110b3a3a524 0 1659782934976 5 connected
dc1cdaa729ebe03c7b9702025426c2b86df70da2 59.110.xx.xxx:9302@19302 myself,master - 0 1659782935000 2 connected 5461-10922
651576fcd8fb66e83212351331bfb110b3a3a524 59.110.xx.xxx:9303@19303 master - 0 1659782934000 3 connected 10923-16383
52eed0573d4b9f20f0b61434bebfec05ce8dcac5 59.110.xx.xxx:9306@19306 slave b78b59b8cadb3e1f77d520a164597777e2bc18f8 0 1659782936000 6 connected
59.110.xx.xxx:9302>
1、application.yml配置文件:
spring: # redis集群 redis: password: 123456 cluster: nodes: - 59.110.xx.xxx:9301 - 59.110.xx.xxx:9302 - 59.110.xx.xxx:9303 - 59.110.xx.xxx:9304 - 59.110.xx.xxx:9305 - 59.110.xx.xxx:9306 max-redirects: 3 # 连接超时时间 timeout: 60s lettuce: pool: # 连接池中的最小空闲连接 min-idle: 0 # 连接池中的最大空闲连接 max-idle: 8 # 连接池的最大数据库连接数 max-active: 8 # #连接池最大阻塞等待时间(使用负值表示没有限制) max-wait: -1m cluster: refresh: period: 60s adaptive: true
2、配置类:
@Configuration @EnableCaching public class RedisConfig extends CachingConfigurerSupport { @Bean @SuppressWarnings(value = { "unchecked", "rawtypes" }) public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<Object, Object> template = new RedisTemplate<Object, Object>(); template.setConnectionFactory(connectionFactory); FastJson2JsonRedisSerializer serializer = new FastJson2JsonRedisSerializer(Object.class); ObjectMapper mapper = new ObjectMapper(); mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); serializer.setObjectMapper(mapper); // 使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(serializer); // Hash的key也采用StringRedisSerializer的序列化方式 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(serializer); template.afterPropertiesSet(); return template; } @Bean public DefaultRedisScript<Long> limitScript() { DefaultRedisScript<Long> redisScript = new DefaultRedisScript<Long>(); redisScript.setScriptText(limitScriptText()); redisScript.setResultType(Long.class); return redisScript; } @Bean public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){ return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED); } /** * 限流脚本 * @return */ private String limitScriptText() { return "local key = KEYS[1]\n" + "local count = tonumber(ARGV[1])\n" + "local time = tonumber(ARGV[2])\n" + "local current = redis.call('get', key);\n" + "if current and tonumber(current) > count then\n" + " return tonumber(current);\n" + "end\n" + "current = redis.call('incr', key)\n" + "if tonumber(current) == 1 then\n" + " redis.call('expire', key, time)\n" + "end\n" + "return tonumber(current);"; } @Bean public DefaultClientResources lettuceClientResources() { return DefaultClientResources.create(); } @Bean @SuppressWarnings("all") public LettuceConnectionFactory lettuceConnectionFactory(RedisProperties redisProperties, ClientResources clientResources) { ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(30)) //按照周期刷新拓扑 .enableAllAdaptiveRefreshTriggers() //根据事件刷新拓扑 .build(); ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() //redis命令超时时间,超时后才会使用新的拓扑信息重新建立连接 .timeoutOptions(TimeoutOptions.enabled(Duration.ofSeconds(10))) .topologyRefreshOptions(topologyRefreshOptions) .build(); LettuceClientConfiguration clientConfiguration = LettuceClientConfiguration.builder() .clientResources(clientResources) .clientOptions(clusterClientOptions) .build(); RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(redisProperties.getCluster().getNodes()); clusterConfig.setMaxRedirects(redisProperties.getCluster().getMaxRedirects()); clusterConfig.setPassword(RedisPassword.of(redisProperties.getPassword())); return new LettuceConnectionFactory(clusterConfig, clientConfiguration); } }
springboot2.3.0后支持通过配置文件和配置LettuceConnectionFactory中设置自动刷新和周期性刷新,采用三主三从的cluster模式
Q: springboot 启动连接报错,Unable to connect to 127.0.0.1;但是项目配置文件写的是外网ip,是正确的
A:客户端lettuce在初始化集群会loadProperties,读到的远端redis集群信息是127.0.0.1的;
解决方法:创建集群,指定ip
./redis-cli --cluster create --cluster-replicas 1 59.110.xx.xxx:9301 59.110.xx.xxx:9302 59.110.xx.xxx:9303 59.110.xx.xxx:9304 59.110.xx.xxx:9305 59.110.xx.xxx:9306 -a 123456
Q:指定为外网ip创建遇到一个新问题,创建集群,使用外网ip无法创建,Waiting for the cluster to join…
A:暂时先检查一下安全组的出入方向、服务器防火墙,搜索发现,还需要开放集群总线的端口,“Redis端口+10000”,即19301-19306。
Q:本机使用java客户端连接,报Unable to connect to:172.xx.xx.xx ,发现连接的内网ip。
A:redis的配置文件应该指定cluster-announce-ip 为外网ip:59.110.xx.xxx
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。