Bootstrap

Redis

目录

一、Redis基础知识

数据持久化

高可用性和扩展性

性能优化

应用场景

二、Redis的Java常用客户端

Jedis

lettuce

Redisson

三、Redis实战

Jedis

1.添加依赖

2.基本使用例子

3.使用连接池优化性能

spring-boot-starter-data-redis

1. 添加依赖

2.配置文件设置

3.使用 RedisTemplate 或 Repository

使用 RedisTemplate

使用 Repository

4.测试配置

Redisson

1.添加依赖

2.配置文件设置

3.使用 Redisson

4.测试配置


一、Redis基础知识

Redis 是一个开源的、使用 ANSI C 语言编写的、基于内存的数据结构存储系统,它可以用作数据库、缓存和消息中间件 。Redis 支持多种数据结构,如字符串(Strings)、哈希(Hashes)、列表(Lists)、集合(Sets)和有序集合(Sorted Sets),这些数据类型都支持 push/pop、add/remove 及取交集并集和差集及更丰富的操作,并且这些操作都是原子性的。

数据持久化

Redis 提供了两种主要的持久化方式:RDB(Redis DataBase)和 AOF(Append Only File)。

RDB 是一种快照机制,它会按照指定的时间间隔将内存中的数据集以快照的形式保存到硬盘上。而 AOF 则是记录服务器接收到的每个写操作,在服务器启动时通过重新执行这些命令来重建原始数据集。

高可用性和扩展性

为了提高系统的高可用性和可扩展性,Redis 提供了主从复制和 Redis Sentinel(哨兵)服务。主从复制允许数据在多个 Redis 实例之间进行同步,而 Redis Sentinel 则提供了自动故障转移功能,确保当主节点出现故障时,可以自动切换到备用节点继续提供服务。

性能优化

Redis 的高性能得益于其单线程模型、高效的网络通信协议以及异步非阻塞 I/O 模型。此外,Redis 还支持一些高级特性,例如事务处理、Lua 脚本编写、管道操作等,进一步增强了其灵活性和性能。

应用场景

由于 Redis 的高性能和灵活的数据结构,它被广泛应用于各种场景中,包括但不限于:

  • 计数器:可以对 String 进行自增自减运算,从而实现计数器功能。

  • 缓存:利用内存中的快速读写能力,作为应用的缓存层来加速数据访问速度。

  • 排行榜:通过 Sorted Sets 的 score 字段来实现基于分数的排名系统。

  • 会话存储:可用于存储用户的会话信息,尤其是在分布式环境中统一管理用户状态。

  • 实时分析:可用于统计网站流量、用户行为等实时数据。

二、Redis的Java常用客户端

Redis 官方推荐的Java 客户端 Jedis、lettuce 和 Redisson

Jedis

优点:

API比较全面

缺点:

使用阻塞的 I/O(方法调用都是同步的,程序流需要等到 sockets 处理完 I/O 才能执行,不支持异步)

Jedis 客户端实例不是线程安全的(多线程使用一个Jedis连接),所以需要通过连接池来使用Jedis(每个线程使用独自的Jedis连接)

lettuce

在spring boot2之后,redis连接默认就采用了lettuce(spring-boot-starter-data-redis)

优点:

线程安全的 Redis 客户端,支持异步模式

lettuce 底层基于 Netty,支持高级的 Redis 特性,比如哨兵,集群,管道,自动重新连接和Redis数据模型。

缺点:

API比较复杂

Redisson

Redisson 提供了使用Redis 的最简单和最便捷的方法,还提供了许多分布式服务(分布式锁,分布式集合,延迟队列等)

优点:

Redisson基于Netty框架的事件驱动的通信层,其方法调用是异步的

Redisson的API是线程安全的,所以可以操作单个Redisson连接来完成各种操作

缺点:

Redisson 对字符串的操作支持比较差

三、Redis实战

Jedis

1.添加依赖

首先,在你的 pom.xml 文件中添加 Jedis 的 Maven 依赖:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.2.3</version> <!-- 确保选择适合你项目的版本 -->
</dependency>

2.基本使用例子

下面是一个简单的例子,演示了如何使用 Jedis 执行基本的 Redis 操作:

import redis.clients.jedis.Jedis;

public class JedisExample {

    public static void main(String[] args) {
        // 创建一个 Jedis 实例并连接到本地 Redis 服务器
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            // 测试连接
            String pingResponse = jedis.ping();
            System.out.println("Ping response: " + pingResponse);

            // 设置一个字符串值
            jedis.set("foo", "bar");
            System.out.println("Set 'foo' to 'bar'");

            // 获取字符串值
            String value = jedis.get("foo");
            System.out.println("Value of 'foo': " + value);

            // 设置一个带有过期时间的键
            jedis.setex("expireKey", 10, "will expire in 10 seconds");
            System.out.println("Set 'expireKey' with an expiration time of 10 seconds");

            // 检查键是否存在
            Boolean exists = jedis.exists("expireKey");
            System.out.println("Does 'expireKey' exist? " + exists);

            // 删除键
            jedis.del("foo");
            System.out.println("Deleted 'foo'");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.使用连接池优化性能

为了提高性能,特别是在高并发环境下,建议使用 Jedis 连接池。以下是使用连接池的例子:

import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Jedis;

public class JedisPoolExample {

    private static JedisPool pool;

    public static void main(String[] args) {
        // 初始化连接池配置
        JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(10); // 最大连接数
        poolConfig.setMaxIdle(5); // 最大空闲连接数
        poolConfig.setMinIdle(1); // 最小空闲连接数

        // 创建连接池实例
        pool = new JedisPool(poolConfig, "localhost", 6379);

        // 从连接池中获取资源
        try (Jedis jedis = pool.getResource()) {
            // 执行一些操作
            jedis.set("poolKey", "value from pool");
            System.out.println("Value of 'poolKey': " + jedis.get("poolKey"));
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭连接池
            if (pool != null) {
                pool.close();
            }
        }
    }
}

spring-boot-starter-data-redis

1. 添加依赖

首先,在你的 pom.xml 文件中添加 spring-boot-starter-data-redis 的依赖:

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

如果你需要连接到 Redis Sentinel 或者 Redis Cluster,还需要额外的依赖或配置。

2.配置文件设置

application.propertiesapplication.yml 中配置 Redis 连接信息:

对于 application.properties:

spring.redis.host=localhost
spring.redis.port=6379
# 如果有密码
# spring.redis.password=yourpassword

对于 application.yml:

spring:
  redis:
    host: localhost
    port: 6379
    # 如果有密码
    # password: yourpassword

3.使用 RedisTemplate 或 Repository

Spring Data Redis 提供了两种主要方式与 Redis 进行交互:RedisTemplateReactiveRedisTemplate(适用于响应式编程),以及基于注解的 repository 支持。

使用 RedisTemplate

你可以直接注入 RedisTemplate 来操作 Redis 数据:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    public Object getValue(String key) {
        return redisTemplate.opsForValue().get(key);
    }
}
使用 Repository

如果你有特定的数据结构,并且希望通过接口的方式来操作它们,可以创建一个继承自 ReactiveRedisRepositoryCrudRepository 的接口:

import org.springframework.data.keyvalue.annotation.KeySpace;
import org.springframework.data.repository.CrudRepository;

@KeySpace("users")
public interface UserRepository extends CrudRepository<User, String> {
}

注意,你需要为实体类定义 @KeySpace 注解来指定键空间。

4.测试配置

确保 Redis 服务正在运行,然后通过编写单元测试或简单的控制台应用程序来验证是否能正确读写数据到 Redis。

Redisson

1.添加依赖

首先,在你的 pom.xml 文件中添加 Redisson 的 Maven 依赖:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-spring-boot-starter</artifactId>
    <version>3.21.0</version> <!-- 确保选择适合你项目的版本 -->
</dependency>

2.配置文件设置

application.ymlapplication.properties 中配置 Redisson 连接信息。

对于 application.yml:

spring:
  redis:
    redisson:
      config: |
        singleServerConfig:
          address: "redis://127.0.0.1:6379"
          # 如果有密码
          # password: "yourpassword"

对于 application.properties:

spring.redis.redisson.config=singleServerConfig\:\n  address\:"redis://127.0.0.1:6379"\n  # 如果有密码\n  # password\: "yourpassword"

注意:根据你的 Redis 集群配置(单机、主从、哨兵或集群),你需要调整上述配置。例如,对于 Redis Sentinel,你可以这样配置:

spring:
  redis:
    redisson:
      config: |
        sentinelServersConfig:
          masterName: "mymaster"
          sentinels:
            - "127.0.0.1:26379"
            - "127.0.0.1:26380"
            - "127.0.0.1:26381"
          # 如果有密码
          # password: "yourpassword"

3.使用 Redisson

Redisson 提供了丰富的 API 来处理各种分布式数据结构和服务。这里是一个简单的例子,展示如何使用 Redisson 来获取和设置值:

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

@Service
public class RedissonService {

    @Autowired
    private RedissonClient redissonClient;

    public void setValue(String key, String value) {
        RBucket<String> bucket = redissonClient.getBucket(key);
        bucket.set(value);
    }

    public String getValue(String key) {
        RBucket<String> bucket = redissonClient.getBucket(key);
        return bucket.get();
    }
}

4.测试配置

确保 Redis 服务正在运行,然后编写一些单元测试来验证 Redisson 是否能正确连接并操作 Redis 数据库。例如:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class RedissonTest {

    @Autowired
    private RedissonService redissonService;

    @Test
    public void testSetAndGet() {
        redissonService.setValue("testKey", "Hello Redisson");
        String value = redissonService.getValue("testKey");
        System.out.println(value); // 应输出 Hello Redisson
    }
}

;