tulip notes
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Star-Lord

希望一天成为大师的学徒
首页
  • 学习笔记

    • 《Vue》
  • 踩坑日记

    • JavaScript
  • MQ
  • Nginx
  • IdentityServer
  • Redis
  • Linux
  • Java
  • SpringBoot
  • SpringCloud
  • MySql
  • docker
  • 算法与设计模式
  • 踩坑与提升
  • Git
  • GitHub技巧
  • Mac
  • 网络
  • 项目构建合集
  • 一些技巧
  • 面试
  • 一些杂货
  • 友情链接
  • 项目发布
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 各种MQ

  • Nginx

  • IdentityServer

  • Redis

    • 初始Redis与安装
    • Redis常用的一些场景
    • Redis中的缓存失效
    • 关于Redis的一些问题
    • Redis的持久化策略
    • Redis从单机到集群等模式
    • Redis和MySql实现数据一致性
    • 通过Redis实现分布式锁
    • Redis的客户端介绍
      • Redis客户端
        • Redis客户端的种类
        • Lettuce
        • 历史变迁
        • 为何不采用Redisson
        • 查看客户端类型
      • 切换客户端
        • 使用Jedis
        • 配置类
        • 使用Redisson
        • 引入依赖
        • 编写配置文件
        • 使用Redisson
  • Linux

  • 中间件
  • Redis
EffectTang
2024-12-12
目录

Redis的客户端介绍

# Redis的客户端介绍

# Redis客户端

首先明确下redis的客户端是什么?

Redis是一个客户端-服务端架构的程序。服务端负责处理数据存储、处理数据的增删改查操作,并确保数据的持久性和安全性。客户端则是与Redis服务端进行通信的应用程序,通过发送命令来操作存储在服务端的数据‌。客户端可以是任何编程语言编写的应用程序,连接到Redis服务端并使用Redis提供的命令来操作数据‌。

通过以上的介绍,似乎redis客户端就只是一个发送执行给服务端的程序。但实际上,它做的不仅仅只有发送数据,而上述的介绍也只是一个简单版。Redis客户端,它除了发送数据,它还做了以下这些:

  • 结果处理:接收并解析来自 Redis 服务器的响应。将结果转换为适合应用程序使用的格式,例如将字符串响应转换为 Java 对象或 Python 字典。
  • 连接管理:建立、维护和关闭与 Redis 服务器的网络连接。某些高级客户端还提供连接池功能,优化多个请求之间的连接复用,提高性能。
  • 事务支持:实现对 Redis 事务的支持,允许开发者将多个命令打包成一个原子操作。
  • 分布式特性:在 Redis 集群模式下,自动发现集群拓扑结构,并智能路由请求到正确的节点。处理节点故障转移和重新配置等情况,保证服务的连续性。

当然,Redis的客户端能做的,远不止这些,这里就不展开介绍了。

我们使用的命令行操作redis就是一个客户端————redis-cli(命令行客户端) 是 Redis 官方提供的命令行客户端,它不仅能够发送命令给 Redis 服务器,还可以进行其它的一些操作。

Another Redis Desktop Manager (ARCM):开源的 Redis GUI 客户端,支持 Windows、Linux 和 MacOS。它也是一个客户端,很好用,推荐。

# Redis客户端的种类

这里介绍在Java语言中,最常用的三种Redis客户端。它们分别是:

  • Jedis:同步、阻塞式的 Redis Java 客户端,广泛应用于各种 Java 应用。
  • Lettuce:默认被 Spring Boot 使用的异步、非阻塞 Redis Java 客户端。
  • Redisson:不仅是一个 Redis 客户端,还是一个分布式对象和服务的实现库,提供了丰富的数据结构和分布式特性。

在springboot项目的开发中,如果我们想使用Redis,通常会在pom.xml文件中引入如下坐标:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
1
2
3
4

那么此时,springboot中默认使用的redis客户端就是Lettuce。

Lettuce一开始就是springboot中默认的redis客户端吗?它有哪些优势,为什么不是其它的比如Redisson?

# Lettuce

Lettuce 并不是一开始就作为 Spring Boot 中默认的 Redis 客户端。在早期版本中,Spring Boot 默认使用的是 Jedis 作为其 Redis 客户端。然而,随着版本的演进和对性能及功能需求的提升,Spring Boot 在较新的版本中切换到了 Lettuce 作为默认的 Redis 客户端。

# 历史变迁

  1. 早期版本(Spring Boot 1.x 和早期的 2.x):
    • 默认使用的 Redis 客户端是 Jedis。
    • Jedis 是一个同步、阻塞式的客户端,适用于简单的 Redis 操作。
  2. 过渡期(Spring Boot 2.x 中期):
    • Spring Boot 开始支持 Lettuce,并允许开发者通过配置选择使用 Jedis 或 Lettuce。
    • 这一时期,开发者可以根据项目需求自行选择适合的客户端。
  3. 现代版本(Spring Boot 2.2 及之后):
    • 自 Spring Boot 2.2 版本开始,默认使用 Lettuce 作为 Redis 客户端。
    • Lettuce 是一个异步、非阻塞的客户端,提供了更好的性能和对 Redis 集群的支持。

之所以选择它,是因为它有以下几个优势:

  • 性能优势:Lettuce 使用 Netty 进行网络通信,支持异步操作,能够更好地处理高并发场景。
  • 集群支持:Lettuce 对 Redis 集群模式的支持更加友好,简化了集群环境下的开发和维护。
  • 连接池管理:Lettuce 提供了更灵活的连接池管理机制,优化了连接复用和资源利用。
  • 哨兵支持:Lettuce 对 Redis Sentinel 的支持也更为完善,提高了系统的高可用性。

当然,如果你仍然希望使用 Jedis 作为 Redis 客户端,也是可以的,下文会说明。

# 为何不采用Redisson

那为什么不使用Redisson来作为默认客户端呢?似乎它的作用更多。还支持分布式相关功能。

设计目标和定位不同

  • Lettuce 和 Jedis:这两个客户端主要专注于提供与 Redis 服务器通信的基本功能,如命令执行、连接管理和事务支持。它们的设计更加轻量级,适合大多数应用场景。
  • Redisson:Redisson 不仅仅是一个简单的 Redis 客户端,它还提供了大量的分布式数据结构和服务(如分布式锁、队列、集合等)。这些高级特性虽然非常有用,但并不是所有应用都需要。

性能考虑

  • Lettuce:作为一个异步、非阻塞的客户端,Lettuce 提供了更好的性能,特别是在高并发场景下。它的设计使得它可以高效地处理大量请求,并且对 Redis 集群的支持也非常好。
  • Redisson:虽然 Redisson 也有很好的性能表现,但由于其内置了许多高级特性和额外的功能,可能会增加一定的复杂性和开销,对于一些只需要基本 Redis 功能的应用来说,可能不是最优选择。

默认适用性

  • 广泛适用性:Lettuce 和 Jedis 作为默认客户端,能够满足大部分应用场景的需求。许多开发者不需要复杂的分布式数据结构或服务,因此这两个客户端足以应对日常开发任务。
  • 特定需求:Redisson 更适合那些需要利用其丰富分布式特性的项目。对于这类项目,开发者可以选择引入 Redisson 作为额外依赖。

以上三点就是不选择Redisson的主要原因,当然可能还有一些其他原因,以上只是个人观点。或许在日后默认客户端会切换成Redisson也说不定。

# 查看客户端类型

那springboot中引入data-redis 坐标后,如何查看它使用的是哪种redis客户端呢?

以下是一些常用的方式:

  • 通过maven查看依赖树

如果你使用的为IDEA,那你在maven窗口中,应该可以找到对应引用jar包。如:你应该会发现 io.lettuce:lettuce-core 或 redis.clients:jedis 存在的情况。默认情况下,你应该能看到 lettuce-core。

  • 查看日志输出

Spring Boot 默认会在启动时打印出大量信息,包括使用的依赖和配置。你可以通过查看应用程序的日志输出来确定使用的 Redis 客户端。通常,在应用程序启动日志中会有关于 Redis 连接的信息,其中会提到是使用了 Lettuce 还是 Jedis。

例如,如果你看到类似以下的日志条目,说明正在使用 Lettuce:

o.s.d.r.c.LettuceConnection : Establishing new connection to Redis using Lettuce...
1

LettuceConnection 表示你使用的redis客户端正是lettuce。

  • 通过代码调试

你可以在应用程序启动时添加一些调试代码或断点,查看实际使用的连接工厂类型:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Component;

@Component
public class RedisClientChecker implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        // 检查 Redis 连接工厂的类型
        if (redisConnectionFactory.getClass().getName().contains("Lettuce")) {
            System.out.println("Using Lettuce as Redis client.");
        } else if (redisConnectionFactory.getClass().getName().contains("Jedis")) {
            System.out.println("Using Jedis as Redis client.");
        } else {
            System.out.println("Unknown Redis client in use.");
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 切换客户端

如果你想在 Spring Boot 项目中使用 Jedis 或 Redisson 作为 Redis 客户端,可以通过以下步骤进行配置。下面是详细的实现方法:

# 使用Jedis

确保你已经添加了 spring-boot-starter-data-redis 依赖,并排除默认的 Lettuce 依赖,然后引入 Jedis 依赖。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <exclusions>
        <exclusion>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
</dependency>
1
2
3
4
5
6
7
8
9
10
11
12
13
14

到此,使用jedis替换lettuce就完成了。在这种情况下,Spring Boot 会自动配置 JedisConnectionFactory 和 RedisTemplate 等组件,无需额外编写配置类。

尽管如此,对于大多数生产环境或更复杂的项目,推荐实现一个 RedisConfig 配置类以获得更多的控制权。这包括但不限于:

  • 自定义连接池设置:例如调整最大活动连接数、空闲连接数等。
  • 自定义序列化策略:为 RedisTemplate 设置特定的键值序列化器。
  • 添加拦截器或其他扩展:例如日志记录、性能监控等。
  • 集成分布式锁或其他高级特性:如果需要使用 Redisson 或其他高级功能。

# 配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public JedisConnectionFactory redisConnectionFactory() {
        // 可以在这里进行更多自定义配置
        return new JedisConnectionFactory();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());

        // 设置序列化器
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new StringRedisSerializer());

        return template;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

扩展一问:

为什么需要设置序列化器?

如果不进行适当的序列化就将数据存储到 Redis 中,确实可能会导致数据乱码或无法正确读取的问题。这是因为 Redis 本质上是一个键值存储系统,它只理解字节流(即二进制数据),而不直接理解高级语言中的复杂数据类型(如 Java 对象、列表、集合等)。因此,当你尝试存储这些复杂的数据结构时,必须确保它们被正确地转换为 Redis 能够理解和存储的格式。

常用的序列化器有哪些?

Spring Data Redis 提供了几种常用的序列化器,可以根据具体需求选择最适合的一种:

  • StringRedisSerializer:用于字符串类型的键和值。它是最简单的序列化器,适合大多数场景。
  • JdkSerializationRedisSerializer:使用 Java 的内置序列化机制。适用于需要存储 Java 对象的情况,但需要注意其性能和安全性问题。
  • JacksonJsonRedisSerializer:基于 Jackson 库,用于 JSON 格式的序列化和反序列化。非常适合 Web 应用程序,因为它可以很好地与 RESTful API 集成。
  • GenericToStringSerializer:可以将任意类型的对象转换为字符串,常用于简单类型的序列化。
  • OxmMarshaler:使用 Spring OXM 模块进行 XML 或 JSON 序列化,适用于特定的 XML 或 JSON 数据格式。

为什么向关系型数据库(如:mysql等)插入数据时不需要显式地进行序列化?

总结下,对于配置类是否实现,可以根据你的需求是否简单。

简单场景:如果你的应用非常简单,且不需要特殊配置,可以依赖 Spring Boot 的自动配置功能,不一定要实现 RedisConfig 配置类。

复杂场景:对于大多数实际项目,特别是那些需要对 Redis 行为进行精细控制的情况,实现 RedisConfig 配置类是推荐的做法,以便更好地管理和优化 Redis 的使用。

# 使用Redisson

确保你的项目中只包含 redisson-spring-boot-starter 依赖,而不要引入 spring-boot-starter-data-redis。

因为Redisson 提供了独立且完整的 API 来与 Redis 进行交互,并且它有自己的 Spring Boot Starter (redisson-spring-boot-starter),可以满足大多数应用场景的需求。同时spring-boot-starter-data-redis 提供的功能和 Redisson 有重叠部分,例如连接管理和数据操作。如果同时引入两者,可能会导致配置上的冗余或冲突。

# 引入依赖

所以使用Redisson只引入一个Redisson-starter就好。

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.23.5</version> <!-- 使用最新版本 -->
</dependency>
1
2
3
4
5

# 编写配置文件

通过 application.properties 或 application.yml 文件进行配置,根据你的 Redis 部署情况选择合适的模式(单服务器、集群、哨兵等)。

以下是单机模式的一个简单示例:

spring:
  redission:
    single-server:
      address: "redis://localhost:6379"
      connection-minimum-idle-size: 10
      connection-pool-size: 64
      database: 0
1
2
3
4
5
6
7

# 使用Redisson

直接注入 RedissonClient 并使用 Redisson 提供的各种 API。

import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    private final RedissonClient redisson;

    @Autowired
    public MyService(RedissonClient redisson) {
        this.redisson = redisson;
    }

    public void performTask() {
        RLock lock = redisson.getLock("myLock");
        try {
            if (lock.tryLock()) {
                // 执行需要锁定的任务
                System.out.println("Lock acquired, performing task...");
            } else {
                System.out.println("Failed to acquire lock.");
            }
        } finally {
            lock.unlock();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

Redisson 提供了许多高级特性,如分布式锁、队列等,直接使用其 API 可以更高效地利用这些功能。

扩展一问:

在springboot项目中,可以同时使用Redisson和lettuce吗?

上次更新: 2025/04/23, 16:23:16
通过Redis实现分布式锁
Linux简介

← 通过Redis实现分布式锁 Linux简介→

最近更新
01
面向切面跟自定义注解的结合
05-22
02
时间跟其他数据的序列化
05-19
03
数据加密与安全
05-17
更多文章>
Theme by Vdoing | Copyright © 2023-2025 EffectTang
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式