SpringBoot+Redis-Cluster集群搭建及调优

转载请注明出处

SpringBoot+Redis-Cluster集群搭建及调优

  • 集群配置
  • 服务器配置
  • 具体搭建步骤
    • 安装所必须的一些工具包
    • 安装redis
    • 集群搭建
      • 安装其他redis节点
      • 修改14上面的redis.conf配置文件
      • 复制修改后的配置文件至其他节点并替换
      • 分别启动所有redis节点并验证启动成功
      • 设置防火墙开放指定节点,保证节点间正常通信
      • 使用cli创建整体的redis集群
      • RedisCluster帮助命令
      • 验证集群
      • 关闭集群
    • 集群扩容
  • SpringBoot整合redis-cluster
    • 依赖
    • yml或properties文件
      • yml
      • properties
    • redis集群配置类,配置RedissionClient
    • 测试接口
  • Redis-Cluster集群调优

集群配置

3主3从

服务器配置

六台(14~19)Linux服务器简易版,8G运行内存

具体搭建步骤

安装所必须的一些工具包

如果已经安装过则无需安装
yum install gcc
yum -y install wget
yum -y install vim*

安装redis

在14服务器上进行以下操作

#进入安装目录,下载redis包并安装
cd /usr/local/
wget https://download.redis.io/releases/redis-5.0.8.tar.gz
tar xzf redis-5.0.8.tar.gz
cd redis‐5.0.8
make

#启动并指定配置文件
src/redis‐server redis.conf(使用后台启动,修改redis.conf里的daemonize改为yes)

#验证启动是否成功
ps -ef | grep redis
#进入redis客户端
src/redis-cli -p 6379 (默认6379端口)
#退出客户端
quit

到目前位置,已经成功搭建了一个单击redis,下面介绍如何使其成为集群

集群搭建

安装其他redis节点

在另外5台服务器上(15~19),同样地按以上步骤安装redis

修改14上面的redis.conf配置文件

(1)daemonize yes
(2)port 8001(分别对每个机器的端口号进行设置)
(3)pidfile /var/run/redis_8001.pid
(4)logfile “8001.log”
(5)dir /usr/local/redis-cluster/8001/(指定数据文件存放位置,必须要指定不同的目录位置,不然会丢失数据)
(6)cluster-enabled yes(启动集群模式)
(7)cluster-config-file nodes-8001.conf(集群节点信息文件,这里800x好和port对应上)
(8)cluster-node-timeout 5000
(9)# bind 127.0.0.1(去掉bind绑定访问ip信息)
(10) protected-mode no (关闭保护模式)
(11) appendonly yes
#如果要设置密码需要增加如下配置:
(12) requirepass 123456 (设置redis访问密码)
(13) masterauth 123456 (设置集群节点间访问密码,跟上面一致)

复制修改后的配置文件至其他节点并替换

替换后,将配置文件的端口改为相应节点的端口,使用命令批量替换
:%s/源字符串/目的字符串/g

分别启动所有redis节点并验证启动成功

使用上面安装redis的命令启动即可,不再赘述。

设置防火墙开放指定节点,保证节点间正常通信

如果未开放端口,会出现创建集群命令超时的现象

firewall-cmd --zone=public --add-port=此处填写端口/tcp --permanent
firewall-cmd --reload

使用cli创建整体的redis集群

进入我们第一个搭建的redis节点14,执行如下命令:
注意:cli命令在redis5.0之后才会有(之前是使用meet命令已被淘汰);–cluster-replicas 1代表一个主节点对应一个从节点,也就是三主三从,默认哈希槽平均分配。

/usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster create --cluster-replicas 1 192.168.2.14:8001 192.168.2.15:8002 192.168.2.16:8003 192.168.2.17:8004 192.168.2.18:8005 192.168.2.19:8006

创建成功后会有如下提示
SpringBoot+Redis-Cluster集群搭建及调优_第1张图片

RedisCluster帮助命令

吃透这个命令里面的东西蛮重要,玩转cluster这是第一步

/usr/local/redis-5.0.8/src/redis-cli -a 123456 --cluster help

验证集群

cluster info(查看集群信息)、cluster nodes(查看节点列表)
在这里插入图片描述
./redis-cli -c -h -p(连接任意一个客户端即连接集群,‐a访问服务端密码,‐c表示集群模式,指定ip地址和端口号)
如果不加-c,倒是也可以连上,但如果连节点1并执行set操作,此时算出来的哈希槽命中了节点二,就会报错
如/usr/local/redis-5.0.8/src/redis-cli -a 123456 -h 192.168.2.101 -p 8001 -c
使用程序或可视化工具进行数据操作

关闭集群

/usr/local/redis-5.0.8/src/redis-cli -a 123456 -c -h 192.168.2.102 -p 8002 shutdown

集群扩容

新增一对主从节点,其中主节点要先加入,加入后通过cluster nodes命令复制其ID备用

/usr/local/redis-5.0.8/src/redis-cli --cluster add-node 新增主节点IP:端口 原任意一节点IP:端口

/usr/local/redis-5.0.8/src/redis-cli --cluster add-node 新增从节点IP:端口 原任意一节点IP:端口 --cluster-slave --cluster-master-id 主节点ID

分配哈希槽

/usr/local/redis-5.0.8/src/redis-cli --cluster reshard 原任意一节点IP:端口 
How many slots do you want to move(from 1 to 16384) 此处填写希望分配的哈希槽数
What is the reciving node ID 此处填写新加入的主节点ID
Please enter all the source node IDs.
Type 'all' to use all tho nodes as sourco nodos for the hash slots.
Type 'done' once you entered all the source nodes IDs .
Source node #1:此处写all,就是从别的节点平均取出哈希槽分配给新节点,也可以写节点ID来限制只有哪些节点分配哈希槽给新节点。
例如:
//平均分
Source node #1:all
//只从节点1分哈希槽出去
Source node #1:节点1的ID
//从节点1和节点2平均分哈希槽出去
Source node #1:节点1的ID
Source node #2:节点2的ID

注意:
新分配的哈希槽不一定是连续的
槽位迁移了,数据也会被迁移到新的节点上

如果其中一对主从节点挂掉了,整个集群将不可用,更改一条配置可将其变为可用,但这样就会存在丢失数据的风险:

//改为no是可用
cluster-replica-no-coverage no

SpringBoot整合redis-cluster

依赖



    org.springframework.boot
    spring-boot-starter-data-redis



    org.apache.commons
    commons-pool2

yml或properties文件

两种配置文件二选一即可,推荐yml,因为优雅并且社区文档多,现在很少人用properties了

yml

spring:
  redis:
    password: 123456  #密码
    lettuce:  #lettuce连接池配置
      pool:
        max-active: 8
        max-idle: 8
        min-idle: 0
        max-wait: 1000
      shutdown-timeout: 100
    cluster:  #集群配置
      nodes:
        - 192.168.2.14:8001
        - 192.168.2.15:8002
        - 192.168.2.16:8003
        - 192.168.2.17:8004
        - 192.168.2.18:8005
        - 192.168.2.19:8006
      max-redirects: 3

properties

spring.redis.password=123456
spring.redis.lettuce.pool.max-active=1000
spring.redis.lettuce.pool.min-idle=10
spring.redis.lettuce.pool.max-idle=50
spring.redis.lettuce.pool.max-wait=1000
spring.redis.timeout=3000
# springboot2.3 以后加上下面配置可自动刷新拓扑,某节点挂掉后,会有新的主从关系,如果不配置,调用接口时程序会报错
spring.redis.lettuce.cluster.refresh.adaptive=true
spring.redis.lettuce.cluster.refresh.period=5000
# spring.redis.sentinel.master=mymaster
# spring.redis.sentinel.nodes=192.168.2.14:26379,192.168.2.15:26380,192.168.2.16:26381
spring.redis.cluster.nodes=192.168.2.14:8001,192.168.2.15:8002,192.168.2.16:8003,192.168.2.17:8004,192.168.2.18:8005,192.168.2.19:8006

redis集群配置类,配置RedissionClient

package com.nwd.pressuretestutil.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.lang.reflect.Method;

/**
 * @ClassName RedisConfig
 * @Description TODO
 * @Author n
 * @Version 1.0
 */
@Configuration
public class RedisConfig extends CachingConfigurerSupport {

    /**
     * 自定义缓存key的生成策略。默认的生成策略是看不懂的(乱码内容) 通过Spring 的依赖注入特性进行自定义的配置注入并且此类是一个配置类可以更多程度的自定义配置
     *
     * @return
     */
    @Bean
    @Override
    public KeyGenerator keyGenerator() {
        return new KeyGenerator() {
            @Override
            public Object generate(Object target, Method method, Object... params) {
                StringBuilder sb = new StringBuilder();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for (Object obj : params) {
                    sb.append(obj.toString());
                }
                return sb.toString();
            }
        };
    }

    /**
     * 缓存配置管理器
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory factory) {
        //以锁写入的方式创建RedisCacheWriter对象
        RedisCacheWriter writer = RedisCacheWriter.lockingRedisCacheWriter(factory);
        //创建默认缓存配置对象
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();
        RedisCacheManager cacheManager = new RedisCacheManager(writer, config);
        return cacheManager;
    }

    /**
     * redissionClient配置
     */
 @Bean
    public RedissonClient redissonClient(){
        Config config = new Config();
        if (redisProperties.getCluster() != null) {
            //集群模式配置
            List nodes = redisProperties.getCluster().getNodes();
            List clusterNodes = new ArrayList<>();
            for (int i = 0; i < nodes.size(); i++) {
                clusterNodes.add("redis://" + nodes.get(i));
            }
            ClusterServersConfig clusterServersConfig = config.useClusterServers()
                    .addNodeAddress(clusterNodes.toArray(new String[clusterNodes.size()]));
            if (!StringUtils.isEmpty(redisProperties.getPassword())) {
                clusterServersConfig.setPassword(redisProperties.getPassword());
            }
        } else {
            //单节点配置
            String address = "redis://" + redisProperties.getHost() + ":" + redisProperties.getPort();
            SingleServerConfig serverConfig = config.useSingleServer();
            serverConfig.setAddress(address);
            if (!StringUtils.isEmpty(redisProperties.getPassword())) {
                serverConfig.setPassword(redisProperties.getPassword());
            }
            serverConfig.setDatabase(redisProperties.getDatabase());
        }
        //看门狗的锁续期时间,默认30000ms,这里配置成15000ms
        config.setLockWatchdogTimeout(15000);
        return Redisson.create(config);
    }
    
    @Bean
    public RedisTemplate redisTemplate(LettuceConnectionFactory factory){
        RedisTemplate template = new RedisTemplate <>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // 在使用注解@Bean返回RedisTemplate的时候,同时配置hashKey与hashValue的序列化方式。
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
}

测试接口

/**
     * 测试redis集群连接
     * */
    @GetMapping("/saveRedisCluster")
    public String saveRedisCluster() {
        try{
            Object x = new Object();
            redisTemplate.opsForValue().set("1","123");
        }catch (Exception e){
            e.printStackTrace();
            return "err";
        }
        return "ok";
    }

Redis-Cluster集群调优

附上几个我认为不错的链接:
配置文件详细解读
调优干货

后续还会更新宕机反演、水平拓展节点等

你可能感兴趣的:(后端,Java,实用工具,redis,spring,boot,linux)