百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

京东开发日记Spring Boot集成Redis集群(Cluster模式)开发实战

mhr18 2024-11-15 22:12 22 浏览 0 评论

集成jedis


引入依赖

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>2.9.0</version>
</dependency>

配置绑定

新增配置

################################################ 连接池配置
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=100
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=2000
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=500
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0

################################################ redis集群部署配置
#设置key的生存时间,当key过期时,它会被自动删除
spring.redis.cluster.expire-seconds=120
#设置redis集群的节点信息
spring.redis.cluster.nodes=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
#设置命令的执行时间,如果超过这个时间,则报错
spring.redis.cluster.command-timeout=5000

新增对应配置映射类RedisPoolProperties

@Component
@PropertySource("classpath:/redis.properties")
public class RedisPoolProperties {

    private Integer maxActive;
    private Integer maxWait;
    private Integer maxIdle;
    private Integer minIdle;

    public Integer getMaxActive() {
        return maxActive;
    }

    public void setMaxActive(Integer maxActive) {
        this.maxActive = maxActive;
    }

    public Integer getMaxWait() {
        return maxWait;
    }

    public void setMaxWait(Integer maxWait) {
        this.maxWait = maxWait;
    }

    public Integer getMaxIdle() {
        return maxIdle;
    }

    public void setMaxIdle(Integer maxIdle) {
        this.maxIdle = maxIdle;
    }

    public Integer getMinIdle() {
        return minIdle;
    }

    public void setMinIdle(Integer minIdle) {
        this.minIdle = minIdle;
    }

    @Override
    public String toString() {
        return "RedisPoolProperties{" +
                "maxActive=" + maxActive +
                ", maxWait=" + maxWait +
                ", maxIdle=" + maxIdle +
                ", minIdle=" + minIdle +
                '}';
    }
}

注册

拿到集群的相关配置,然后就集群的注册

@Configuration
public class RedisConfig {

    @Autowired
    private RedisClusterProperties redisClusterProperties;

    /* Jedis - 集群、连接池模式 */
    @Bean
    public JedisCluster jedisCluster(){

        /* 切割节点信息 */
        String[] nodes = redisClusterProperties.getNodes().split(",");
        Set<HostAndPort> hostAndPorts = new HashSet<>();
        for (String node : nodes) {
            int index = node.indexOf(":");
            hostAndPorts.add(new HostAndPort(node.substring(0,index),Integer.parseInt(node.substring(index + 1))));
        }

        /* Jedis连接池配置 */
        JedisPoolConfig jedisPoolConfig = getJedisPoolConfig();

        return new JedisCluster(hostAndPorts,redisClusterProperties.getCommandTimeout(),jedisPoolConfig);

    }

    /**
     * 连接池配置
     * @return JedisPoolConfig
     **/
    private JedisPoolConfig getJedisPoolConfig(){

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();

        jedisPoolConfig.setMaxIdle(redisPoolProperties.getMaxIdle());       // 最大空闲连接数, 默认8个
        jedisPoolConfig.setMaxTotal(redisPoolProperties.getMaxActive());    // 最大连接数, 默认8个
        jedisPoolConfig.setMinIdle(redisPoolProperties.getMinIdle());       // 最小空闲连接数, 默认0
        jedisPoolConfig.setMaxWaitMillis(redisPoolProperties.getMaxWait()); // 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
        jedisPoolConfig.setTestOnBorrow(true);                              // 对拿到的connection进行validateObject校验
        return jedisPoolConfig;
    }

}

获取redis客户端

新增一个工具接口IRedisCluster,然后写一个组件对接口进行实现:获取redis客户端实例后,进行redis相关操作的封装

接口

public interface IRedisCluster {

    String set(String key, String value);

    String get(String key);
}

实现IRedisCluster接口

@Service("redisClusterService")
public class RedisClusterService implements IRedisCluster{

    @Autowired
    private JedisCluster jedisCluster;

    @Override
    public String set(String key, String value) {
        return jedisCluster.set(key, value);
    }

    @Override
    public String get(String key) {
        return jedisCluster.get(key);
    }
}

先封装两个最简单的方法,更详细的封装后续再介绍

使用

新增一个RedisController编写简单的服务接口:

@RestController
public class RedisClusterController {

    @Autowired
    @Qualifier("redisClusterService")
    private IRedisCluster redisCluster;

    @PostMapping("/cluster/jedis/{key}")
    public void setDataByJedis(@PathVariable("key") String key){
        System.out.println("set " + key);
        redisCluster.set(key,key + "nice");
    }

    @GetMapping("/cluster/jedis/{key}")
    public void getDataByJedis(@PathVariable("key") String key){
        System.out.println(redisCluster.get(key));
    }

}

验证

用postman分别调用setDatagetData对应服务,控制台打印以下信息:

用redis-cli客户端连接集群中任意一个节点

redis-cli -c -p 7001

得到集群中已经有相关记录:

集成spring-data-redis#


引入依赖

 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
 </dependency>

配置绑定

因为是Spring封装的组件,所以有比较完善的支持,我们直接在``下新增关于集群的配置

# ------------------------------------------------------------ cluster集群模式
# 重连最大数
spring.redis.cluster.max-redirects=3
# 集群主机信息
spring.redis.cluster.nodes=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

# ------------------------------------------------------------ 连接池配置
# lettuce
spring.redis.lettuce.pool.max-active=8
spring.redis.lettuce.pool.max-idle=8
spring.redis.lettuce.pool.max-wait=-1ms
spring.redis.lettuce.pool.min-idle=0

配置spring.redis.lettuce.pool节点会自动你开启连接池需将单机模式的相关配置注释掉,不然虽然能启动,但的操作redis时会报错

注册

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();

        /* 设置value的序列化规则和 key的序列化规则 */
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        redisTemplate.setKeySerializer(stringRedisSerializer);                // key采用String的序列化方式
        redisTemplate.setHashKeySerializer(stringRedisSerializer);            // hash的key也采用String的序列化方式
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer); // value序列化方式采用jackson
        redisTemplate.setConnectionFactory(connectionFactory);                // 默认使用letttuce,如果想使用Jedis,创建JedisConnectionFactory实例作为参数传入

        return redisTemplate;
    }
}

获取redis客户端

同样实现的上述的IRedisCluster接口

@Service("redisClusterTemplateService")
public class RedisClusterTemplateService implements IRedisCluster{

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public String set(String key, String value) {
        redisTemplate.opsForValue().set(key,value);
        return key;
    }

    @Override
    public String get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}

使用

编写对应的setget服务

@RestController
public class RedisClusterController {

    @Autowired
    @Qualifier("redisClusterTemplateService")
    private IRedisCluster redisTemplateCluster;

     @PostMapping("/cluster/{key}")
    public void setData(@PathVariable("key") String key){
        System.out.println("set " + key);
        redisTemplateCluster.set(key,key + " nice");
    }

    @GetMapping("/cluster/{key}")
    public void getData(@PathVariable("key") String key){

        System.out.println(redisTemplateCluster.get(key));
    }
}

验证

用postman分别调用setDatagetData对应服务,控制台打印以下信息:

用redis-cli客户端连接集群中任意一个节点

redis-cli -c -p 7006

得到集群中已经有相关记录:

异常处理


io.lettuce.core.RedisConnectionException: Connection closed prematurely

redis启动配置中默认是有保护模式的,要关闭保护模式

如果觉得本文章对你有帮助,可以转发关注支持一下

相关推荐

说说Redis的单线程架构(redis的单线程模型)

一句话总结Redis采用单线程处理命令请求,避免了多线程的上下文切换和锁竞争,保证原子性操作。其基于内存的高效执行和I/O多路复用模型支撑了高并发性能。网络I/O和持久化操作(如RDB/AOF)由后台...

答记者问之 - Redis 的高效架构与应用模式解析

问:极客程序员你好,请帮我讲一讲redis答:redis主要涉及以下核心,我来一一揭幕Redis的高效架构与应用模式解析Redis是一个开源的内存数据存储系统,因其高性能、丰富的数据结构和易用性...

Redis的5种核心数据结构,及其最经典的“应用场景”

Redis凭什么稳坐缓存界头把交椅?全靠这五个“身怀绝技”的数据结构!在分布式系统的江湖里,Redis就像一位身怀绝技的武林高手,而它的五大核心数据结构正是克敌制胜的五套绝学。今天咱们就来拆解这些独门...

精准定位文件包含漏洞:代码审计中的实战思维

前言最近看到由有分析梦想cms的,然后也去搭建了一个环境看了一看,发现了一个文件包含漏洞的点,很有意思,下面是详细的复现和分析,以后代码审计又多了一中挖掘文件包含漏洞的新思路环境搭建下载https...

ARDM:一款国产跨平台的Redis管理工具

ARDM(AnotherRedisDesktopManager)是一款免费开源的Redis桌面管理客户端,支持Windows、Mac、Linux跨平台。功能特性ARDM提供的主要功能如...

SpringBoot的Web应用开发——Web缓存利器Redis的应用!

 Web缓存利器Redis的应用Redis是目前使用非常广泛的开源的内存数据库,是一个高性能的keyvalue数据库,它支持多种数据结构,常用做缓存、消息代理和配置中心。本节将简单介绍Redis的使...

Windows服务器部署CRMEB开源电商系统,详细教程来了!

安装PHP已经安装过PHP的可以跳过首先安装VC运行库下载地址https://docs.microsoft.com/zh-cn/cpp/windows/latest-supported-vc-redi...

Windows系统下Redis各个安装包介绍与选择指南

简介Redis作为高性能的键值数据库,广泛应用于缓存、消息队列等场景。在Windows系统中部署Redis时,用户可以选择多种安装包以满足不同的需求。本文将详细介绍以下Redis8.0.3版本的安装...

从面试题入手,深度剖析Redis Cluster原理

揭开RedisCluster的神秘面纱**在当今数字化浪潮中,数据量呈爆炸式增长,应用程序对数据存储和处理的要求也日益严苛。Redis作为一款高性能的内存数据库,凭借其出色的读写速度和丰富的数...

给大家推荐些好的c语言代码的网站

C语言,那就来推荐几个吧,部分含有C++:1、TheLinuxKernelArchives(kernel.org)Linux内核源码,仅限于C,但内核庞大,不太适合新手;2、redis(redi...

Redis String 类型的底层实现与性能优化

RedisString是Redis中最基础也是应用最广泛的数据类型,它能存储文本、数字、二进制数据等多种形式的信息。深入理解其底层实现对构建高性能分布式系统至关重要。Redis字符串的底层结...

阿里面试问:Redis 为什么把简单的字符串设计成 SDS?

分享了一道面阿里的redis题,我看了以后觉得挺有意思。题目大致是这样的面试官:了解redis的String数据结构底层实现嘛?铁子:当然知道,是基于SDS实现的面试官:redis是用C语言开发的,那...

编程语言那么多,为何C语言能成为最成功的语言?

编程语言那么多,为何C语言能成为最成功的语言?2025年嵌入式岗位暴增47%,新人却还在问"C语言过时了吗"。真相是连机器人关节驱动都得靠它写,不会指针连芯片手册都看不懂。见过用Pyt...

go-zero 使用 redis 作为 cache 的 2 种姿势

在go-zero框架内,如在rpc的应用service中,其内部已经预置了redis的应用,所以我们只需要在配置中加入相关字段即可,另外,在svcContext声明redisc...

Redis事务深度解析:ACID特性、执行机制与生产实践指南

一、Redis事务的本质与核心机制Redis事务通过MULTI、EXEC、WATCH等命令实现,其本质是将多个命令序列化后一次性执行,而非传统数据库的严格事务模型。核心特点如下:命令队列化:MULT...

取消回复欢迎 发表评论: