redis的学习

redis的学习

致敬作者:

在这里插入图片描述

1.Redis概述:

Redis是一个开源的内存数据结构存储系统,也被称为键值存储系统。它支持多种数据结构,如字符串、哈希表、列表、集合、有序集合等,并提供了丰富的操作命令,可以对这些数据结构进行快速的读写操作。Redis具有高性能、高可用性和可扩展性的特点,常用于缓存、消息队列、实时统计等场景。

  1. 特点:
    • 基于内存: Redis 数据存储在内存中,因此具有非常高的读写性能。
    • 持久化: Redis 支持多种持久化方式,可以将数据保存到磁盘中,以防止数据丢失。
    • 数据结构丰富: Redis 支持丰富的数据结构,如字符串、哈希、列表、集合、有序集合等,使得它不仅仅是一个简单的键值对存储系统,还能支持更复杂的数据操作。
    • 分布式: Redis 支持主从复制和集群模式,可以实现数据的自动分片和负载均衡,以提高系统的容量和可用性。
  2. 主要用途:
    • 缓存: 作为高性能的缓存系统,用于存储频繁访问的数据,加速应用程序的读取速度。
    • 会话存储: 用于存储用户会话相关的数据,如用户登录状态、购物车信息等。
    • 消息队列: 可以通过 Redis 的发布订阅功能实现简单的消息队列系统,用于解耦应用程序的组件。
    • 计数器/排行榜: Redis 的原子递增和有序集合功能,可以用于实现计数器和排行榜等功能。
  3. 数据持久化:
    • Redis 提供了两种持久化方式:快照(RDB)和追加式文件(AOF)。
    • RDB 持久化会定期将内存中的数据保存到磁盘上,适合用于备份和恢复。
    • AOF 持久化会记录每条写命令,在服务器重启时重新执行这些命令来恢复数据。
  4. 高可用和集群:
    • Redis 支持主从复制,一个主节点可以拥有多个从节点,实现数据的备份和读写分离。
    • Redis 集群模式可以将数据分片存储在多个节点上,以提高系统的容量和可用性。
  5. 语言支持:
    • Redis 客户端支持多种编程语言,如 Java、Python、Node.js 等,可以轻松与各种应用程序集成。

2.Redis数据结构:

  1. 字符串(String)

    • 字符串是 Redis 中最基本的数据类型,它可以存储任意类型的数据,如数字、文本、二进制数据等。

    • 用法示例:

      SET key value      # 设置键值对
      GET key            # 获取键对应的值
      INCR key           # 将键对应的值递增 1
      
  2. 哈希(Hash)

    • 哈希是一种 key-value 结构,其中 key 是一个字符串,value 是一个键值对集合。

    • 用法示例:

      HSET key field value    # 设置哈希表中的字段值
      HGET key field         # 获取哈希表中指定字段的值
      HGETALL key            # 获取哈希表中所有字段和值
      
  3. 列表(List)

    • 列表是一组按顺序排列的字符串元素,可以在列表头或列表尾添加或删除元素。

    • 用法示例:

      LPUSH key value1 value2  # 在列表头添加元素
      RPUSH key value1 value2  # 在列表尾添加元素
      LPOP key                 # 删除并获取列表头元素
      RPOP key                 # 删除并获取列表尾元素
      
  4. 集合(Set)

    • 集合是一组无序、不重复的字符串元素,支持求交、并、差等操作。

    • 用法示例:

      SADD key member1 member2  # 向集合中添加元素
      SREM key member1          # 从集合中删除元素
      SMEMBERS key              # 获取集合中所有元素
      
  5. 有序集合(Sorted Set)

    • 有序集合是一组有序的字符串元素,每个元素都关联着一个分数,可以按照分数进行排序。

    • 用法示例:

      ZADD key score1 member1  # 向有序集合中添加元素
      ZRANGE key start end     # 获取有序集合中指定范围内的元素
      ZREVRANGE key start end  # 获取有序集合中指定范围内的元素(倒序)
      

3.Redis基本操作:

  1. 键值对操作
    • 设置键值对:SET key value
    • 获取键对应的值:GET key
    • 删除键值对:DEL key
  2. 哈希操作
    • 设置哈希表中的字段值:HSET key field value
    • 获取哈希表中指定字段的值:HGET key field
    • 获取哈希表中所有字段和值:HGETALL key
  3. 列表操作
    • 在列表头添加元素:LPUSH key value
    • 在列表尾添加元素:RPUSH key value
    • 删除并获取列表头元素:LPOP key
  4. 集合操作
    • 向集合中添加元素:SADD key member
    • 从集合中删除元素:SREM key member
    • 获取集合中所有元素:SMEMBERS key
  5. 有序集合操作
    • 向有序集合中添加元素:ZADD key score member
    • 获取有序集合中指定范围内的元素:ZRANGE key start end
    • 获取有序集合中指定范围内的元素(倒序):ZREVRANGE key start end

4.Redis雪崩,击穿,穿透

  1. Redis 雪崩
    • Redis 雪崩是指缓存中大量的键同时过期失效,导致大量请求直接打到数据库上,导致数据库短时间内承受不了大量的请求而崩溃。
    • 解决方案:
      • 设置不同的过期时间,避免缓存同时失效。
      • 使用 Redis 高可用方案,如 Redis Sentinel、Redis Cluster 等,保证 Redis 的高可用性。
      • 在应用程序中实现限流措施,避免瞬间大量的请求打到数据库上。
      • 对于必须从数据库中获取的数据,在 Redis 缓存失效时,直接从数据库中获取,并在重新写入缓存时设置较短的过期时间,避免缓存同时失效。
  2. Redis 击穿
    • Redis 击穿是指缓存中不存在的键或者已经过期的键,导致请求直接打到数据库上,导致数据库短时间内承受不了大量的请求而崩溃。
    • 解决方案:
      • 在查询缓存之前,先判断键是否存在,如果不存在,直接返回空值,避免请求直接打到数据库上。
      • 使用互斥锁(如分布式锁)或者信号量等机制,避免多个请求同时从数据库中获取同一个数据。
      • 将热点数据预先加载到缓存中,避免缓存失效时直接打到数据库上。
  3. Redis 穿透
    • Redis 穿透是指请求的键在缓存中不存在,每次请求都打到数据库上,导致数据库短时间内承受不了大量的请求而崩溃。
    • 解决方案:
      • 在查询缓存之前,先将键进行合法性校验,如对于非法的键(如负数),直接返回空值,避免请求直接打到数据库上。
      • 对于缓存中不存在的键,返回默认值,并将默认值写入缓存中,避免缓存穿透问题。
      • 使用布隆过滤器(Bloom Filter)等技术,过滤掉一部分肯定不存在的请求。

5.Redis发布订阅:

Redis 的发布订阅机制包括以下几个主要组件:

  1. 发布者(Publisher)

    • 发布者向 Redis 服务器发送一个消息,并指定一个频道(Channel)。
    • 发布者可以向多个频道发布消息。
  2. 订阅者(Subscriber)

    • 订阅者可以订阅一个或多个频道,以接收发布者发送的消息。
    • 订阅者可以随时取消订阅某个频道。
  3. 频道(Channel)

    • 频道是消息的分类,发布者向指定的频道发送消息,订阅者只接收指定频道的消息。
    • Redis 中的频道是动态创建的,没有预定义的频道。
  4. 消息(Message)

    • 消息是发布者发送给订阅者的信息,可以是任何类型的数据。

Redis 的发布订阅机制的工作流程如下:

  1. 发布者向 Redis 服务器发送消息,并指定一个频道。
  2. Redis 服务器将消息发送给所有订阅了该频道的订阅者。
  3. 订阅者接收到消息后,可以进行相应的处理。在 Java 中使用 Redis 的发布订阅机制需要借助 Jedis 或者 Redisson 等第三方库来操作 Redis。下面我将分别用 Jedis 和 Redisson 两种方式来演示 Redis 的发布订阅机制。

使用 Jedis 操作 Redis 发布订阅机制示例:

首先,确保你已经引入了 Jedis 相关的依赖。

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

以下是一个简单的示例代码:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPubSub;

public class RedisPubSubExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);

        // 订阅者
        new Thread(() -> {
            jedis.subscribe(new JedisPubSub() {
                @Override
                public void onMessage(String channel, String message) {
                    System.out.println("Received message from channel [" + channel + "]: " + message);
                }
            }, "news");
        }).start();

        // 发布者
        new Thread(() -> {
            try {
                Thread.sleep(1000); // 等待一秒钟再发布消息
                jedis.publish("news", "Hello, this is a news");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

在上面的示例中,我们使用 Jedis 创建了一个订阅者线程和一个发布者线程。订阅者通过 jedis.subscribe() 方法来订阅频道,并通过 onMessage() 方法接收到消息。发布者通过 jedis.publish() 方法向指定频道发布消息。

使用 Redisson 操作 Redis 发布订阅机制示例:

同样地,在使用 Redisson 之前,需要确保你已经引入了 Redisson 的依赖。以下是一个使用 Redisson 的示例代码:

import org.redisson.Redisson;
import org.redisson.api.RTopic;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;

public class RedissonPubSubExample {
    public static void main(String[] args) {
        Config config = new Config();
        config.useSingleServer().setAddress("redis://127.0.0.1:6379");
        RedissonClient redisson = Redisson.create(config);

        // 订阅者
        RTopic newsTopic = redisson.getTopic("news");
        newsTopic.addListener((channel, message) -> {
            System.out.println("Received message from channel [" + channel + "]: " + message);
        });

        // 发布者
        new Thread(() -> {
            try {
                Thread.sleep(1000); // 等待一秒钟再发布消息
                newsTopic.publish("Hello, this is a news");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}

6.Redis事务:

Redis 支持的事务主要包括 MULTI、EXEC、DISCARD 和 WATCH 四种事务操作。下面我将详细说明每种事务的作用和用法:

  1. MULTI: MULTI 命令用于标记事务的开始,表示接下来的命令将作为一个事务进行处理。在 MULTI 执行后,所有接下来的命令都会被放入队列中等待执行,直到 EXEC 命令被调用。
  2. EXEC: EXEC 命令用于触发之前加入队列的事务中的所有命令执行。如果在执行事务期间出现错误,所有命令会被回滚,否则会一次性执行事务中的所有命令。
  3. DISCARD: DISCARD 命令用于取消事务,清空事务队列中的所有命令,恢复正常的非事务状态。可以在 MULTI 后、EXEC 前使用 DISCARD 来取消事务。
  4. WATCH: WATCH 命令用于在事务执行之前监视一个或多个键,并在事务执行时检查这些键是否被其他客户端修改。如果任何被监视的键被修改,事务将被取消,客户端需要重新执行事务。WATCH 可以保证事务执行过程中数据的一致性。

使用 Redis 的事务可以确保一系列命令在一个原子操作中执行,保证了这些命令的连贯性和一致性。事务还可以提高性能,减少网络开销,并减少并发操作时的竞争情况。

下面是一个简单的示例代码演示 Redis 事务的使用:

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class RedisTransactionExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);

        // 开启事务
        Transaction tx = jedis.multi();

        // 将多个命令放入事务队列
        tx.set("key1", "value1");
        tx.set("key2", "value2");

        // 执行事务
        tx.exec();
        
        // 关闭连接
        jedis.close();
    }
}

在上面的示例中,我们首先通过 jedis.multi() 开启一个事务,并将多个命令放入事务队列中。最后通过 tx.exec() 执行事务。如果需要取消事务,可以使用 tx.discard() 方法。这样就实现了简单的 Redis 事务操作。

7.Redis持久化:

Redis 提供了两种持久化方式来保证数据不会因为进程退出而丢失,分别是快照(snapshotting)和日志(append-only file)。

  1. 快照持久化(Snapshotting):
    • Redis 会周期性地将内存中的数据生成一个快照文件(RDB 文件),这个快照文件是一个经过压缩的二进制文件,它包含了某个时间点上的 Redis 数据集。
    • 快照持久化是通过 SAVEBGSAVE 命令来触发的。SAVE 命令会在执行期间阻塞 Redis 服务器,而 BGSAVE 命令会在后台异步进行快照持久化,不会阻塞服务器。
    • 当 Redis 服务器重启时,可以通过加载最近一次生成的 RDB 文件来恢复数据。
  2. 日志持久化(Append-Only File):
    • Redis 的日志持久化是通过将所有写命令追加到一个文件中(AOF 文件)来实现的。这个文件包含了可以重建数据集的操作命令。
    • Redis 服务器在启动时会通过重新执行 AOF 文件中的命令来恢复数据。在运行时,Redis 会将写命令追加到 AOF 文件的末尾,确保写操作的持久化。
    • Redis 还提供了 AOF 文件的重写功能,通过重新生成一份更小的 AOF 文件来减少文件的体积。

选择适合的持久化方式:

  • 如果对数据的完整性要求比较高,可以开启 AOF 持久化,以保证每条写命令都会被持久化到文件中,但需要注意 AOF 文件可能会比 RDB 文件大。
  • 如果对数据的完整性要求不是非常严格,可以选择 RDB 持久化,因为 RDB 文件比 AOF 文件小,恢复数据也更快速。

8.Redis集群和主从复制:

Redis 集群: Redis 集群是为了解决单节点 Redis 的性能和容量限制而设计的分布式方案。它具有以下主要特点:

  1. 数据分片: Redis 集群将数据分散存储在多个节点上,每个节点负责存储部分数据。Redis 使用哈希槽(hash slot)来将数据分片到不同的节点上。默认情况下,集群有 16384 个哈希槽,每个节点负责一部分槽。
  2. 自动数据迁移: 当添加或删除节点时,Redis 集群会自动对数据进行重新分片和迁移,以达到均衡数据负载的目的。这意味着你可以动态地扩展或缩小集群的规模,而无需手动迁移数据。
  3. 故障转移: 当主节点发生故障时,Redis 集群会自动进行主从切换,将一个从节点提升为新的主节点。这个过程称为故障转移,旨在保证系统的高可用性。集群使用投票机制来选择新的主节点。
  4. 节点间通信和协调: Redis 集群使用 Cluster Bus 进行节点间的通信和协调工作。Cluster Bus 是一个基于 gossip 协议的轻量级通信机制,用于传播节点信息、集群状态变化、故障检测等。
  5. 客户端路由: 客户端发送的请求会根据键名计算哈希槽,并将请求发送到对应的节点。集群会维护一个槽与节点的映射表,以便正确地路由请求。

主从复制: Redis 主从复制是一种简单而有效的方式,用于提供数据的冗余备份和读取性能的提升。它具有以下主要特点:

  1. 主从关系: Redis 主从复制中有一个主节点(Master)和一个或多个从节点(Slave)。主节点负责处理写操作,并将写操作的日志传播给从节点。而从节点只负责接收主节点的写操作日志并进行复制。
  2. 数据复制: 主节点会将自己的数据复制到从节点,以确保数据的冗余备份。从节点会定期向主节点发送同步请求,获取最新的数据更新。
  3. 读写分离: 从节点可以用于处理读操作,从而减轻主节点的负载。客户端可以直接向从节点发送读请求,提高系统的读取性能。
  4. 故障恢复: 当主节点发生故障时,可以将一个从节点提升为新的主节点,以继续提供服务。Redis 主从复制具备自动故障转移的能力,能够在主节点故障后快速切换到新的主节点。
  5. 数据一致性: Redis 主从复制采用异步复制方式,从节点在接收到主节点的写操作之前可能存在一定的延迟。因此,在主节点故障恢复后,从节点的数据可能会与主节点略有不一致。

综上所述,Redis 集群和主从复制是两种不同的分布式方案,用于解决不同的需求。Redis 集群适合处理大规模数据和高并发访问的场景,提供自动分片和故障转移等功能;而主从复制适合提供冗余备份和读取性能优化的场景。根据实际需求,可以选择适合的方案或结合两者来使用。

9.redis哨兵:

Redis 哨兵(Sentinel)是 Redis 提供的一种高可用性解决方案,用于监控 Redis 主从复制集群中主服务器的状态,并在主服务器发生故障时自动进行故障转移,将一个从服务器升级为新的主服务器,以确保系统的持续稳定运行。以下是关于 Redis 哨兵的详细解释:

工作原理:

  1. 监控主服务器:哨兵通过定期向主服务器发送 PING 命令来监控主服务器的存活状态,如果主服务器无响应,则认为主服务器已下线。
  2. 选举领导者:当哨兵发现主服务器下线后,多个哨兵节点会进行选举,选择出一个哨兵节点作为领导者(leader)负责进行故障转移操作。
  3. 故障转移:领导者哨兵会与其他从服务器协商,选出一个从服务器作为新的主服务器,并将其他从服务器切换到新的主服务器上。
  4. 通知客户端:哨兵会向客户端发送通知,告知主从集群发生故障转移,客户端可以更新连接信息以连接到新的主服务器。

相关问题:

  1. 多哨兵部署:通常会部署多个哨兵节点,以防止单点故障和提高故障检测的准确性。
  2. 配置参数:需要在 Redis 配置文件中配置哨兵相关参数,如监控间隔、投票时间、故障转移超时等。
  3. 主从切换延迟:由于哨兵需要进行选举和协商过程,故障转移可能存在一定的延迟,需要根据业务需求来权衡。
  4. 健康检查:哨兵会定期检查主从服务器的健康状态,确保数据同步正常,避免出现数据不一致的情况。

通过部署 Redis 哨兵,可以有效提高 Redis 集群的可用性和稳定性,确保主从集群在主服务器故障时能够自动完成故障转移,减少系统宕机时间。在使用 Redis 哨兵时,需要注意配置参数、多哨兵部署和故障转移延迟等问题,以保证系统的正常运行和数据的安全性。

10.Redis缓存应用:

1. 高性能的读写操作: Redis 存储在内存中,因此读取和写入操作非常快速。这使得 Redis 成为一个优秀的缓存解决方案,能够显著减少应用程序对后端存储(如数据库)的访问次数,提高系统的响应速度。

2. 数据结构丰富: Redis 支持丰富的数据结构,包括字符串、哈希、列表、集合、有序集合等。这些数据结构的灵活性使得 Redis 能够适用于各种不同类型的缓存需求。

3. 缓存数据的过期和淘汰策略: Redis 允许为缓存数据设置过期时间,在数据过期后自动从内存中删除,这有助于节约内存空间。此外,Redis 也支持基于 LRU(Least Recently Used,最近最少使用)算法的内存淘汰策略,确保内存中始终存储着最有用的数据。

4. 发布与订阅: Redis 支持发布与订阅模式,允许客户端订阅特定的频道,并在频道上发布消息。这使得 Redis 不仅可以作为简单的键值存储,还可以用于实时消息传递和事件通知,适用于一些特定的缓存场景。

5. 分布式缓存: 通过 Redis 集群或者 Redis Sentinel(哨兵)来构建分布式缓存,以扩展缓存容量和提高可用性,同时保持良好的性能。

缓存应用场景:

  • 页面缓存: 将经常访问但不经常变化的页面内容缓存到 Redis 中,以减轻对数据库的访问压力,提高页面加载速度。
  • 会话缓存: 将用户会话信息、认证状态等存储在 Redis 中,以提升网站或应用的性能和可伸缩性。
  • 对象缓存: 将数据库查询结果、常用对象等缓存到 Redis 中,避免重复查询和计算,提高数据访问速度。

11.Redis分布式锁:

1:实现原理: Redis 分布式锁的实现原理主要基于以下两个关键组件:

  1. SETNX(SET if Not eXists)命令: SETNX 命令在 Redis 中用于设置键值对,但只有在键不存在时才会进行设置。通过 SETNX 命令,可以保证只有一个客户端能够成功地将键设置为指定的值,即获取到了锁。
  2. 过期时间(Expiration): 为了避免锁一直被占用而导致死锁,我们可以为获取到锁的客户端设置一个过期时间(expiration time)。客户端在释放锁之前需要在指定的时间内完成任务,否则锁会自动释放,其他客户端可以获取到锁。

2:使用方法: 以下是使用 Redis 分布式锁的一般步骤:

  1. 客户端尝试执行以下操作:
    • 使用 SETNX 命令尝试在 Redis 中设置一个特定的键作为锁。
    • 如果 SETNX 返回 1(表示成功获取到锁),则客户端获得了锁,可以开始执行任务。
    • 如果 SETNX 返回 0(表示锁已被其他客户端占用),则客户端没有获得锁,需要等待一段时间后重试或采取其他策略。
  2. 客户端执行任务:
    • 客户端在获取到锁之后,开始执行需要互斥访问的任务。
    • 注意:客户端应在规定的时间内完成任务,以免锁过期而被其他客户端获取。
  3. 客户端释放锁:
    • 任务执行完成后,客户端通过删除锁的方式来释放锁,即使用 DEL 命令将锁对应的键从 Redis 中删除。
    • 注意:客户端只能删除自己获取到的锁,以确保不会释放其他客户端持有的锁。

注意事项: 在使用 Redis 分布式锁时,还需要注意以下几点:

  • 锁的持有时间应该合理设置,既要保证任务能在规定时间内完成,又要避免锁长时间占用而影响其他进程的执行。
  • 获取锁和释放锁的过程应该是原子操作,可以使用 Redis 的 Lua 脚本来实现原子性。
  • 需要处理异常情况,例如获取锁时客户端发生故障,锁未被正确释放的情况。
  • 可以为锁添加唯一标识,以便识别不同的锁,并提供更多的操作,例如延长锁的持有时间。

3:演示

首先,你需要在项目中引入 Jedis 依赖,如果使用 Maven,可以在 pom.xml 中添加以下依赖:

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

接下来,我们通过 Java 代码来演示如何实现分布式锁:

import redis.clients.jedis.Jedis;

public class RedisDistributedLockDemo {

    private static final String LOCK_KEY = "distributed_lock";
    private static final int LOCK_EXPIRE_TIME = 10000; // 锁的过期时间,单位毫秒

    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost"); // 连接本地的 Redis 服务
        try {
            // 尝试获取锁
            if (acquireLock(jedis)) {
                // 成功获取到锁,执行任务
                System.out.println("成功获取到锁,开始执行任务...");
                // 模拟执行任务
                Thread.sleep(5000);
                // 任务执行完毕,释放锁
                releaseLock(jedis);
                System.out.println("任务执行完毕,释放锁");
            } else {
                // 未获取到锁
                System.out.println("未获取到锁,执行其他逻辑");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            jedis.close(); // 关闭连接
        }
    }

    // 尝试获取锁
    private static boolean acquireLock(Jedis jedis) {
        long result = jedis.setnx(LOCK_KEY, "locked");
        if (result == 1) {
            // 设置锁的过期时间,防止死锁
            jedis.pexpire(LOCK_KEY, LOCK_EXPIRE_TIME);
            return true;
        } else {
            return false;
        }
    }

    // 释放锁
    private static void releaseLock(Jedis jedis) {
        jedis.del(LOCK_KEY);
    }
}

在上面的示例中,我们使用 Jedis 客户端连接到本地的 Redis 服务,并定义了 acquireLock 方法用于尝试获取锁,以及 releaseLock 方法用于释放锁。在 main 方法中,我们首先尝试获取锁,如果成功获取到锁,则执行模拟的任务并在任务完成后释放锁;如果未能获取到锁,则执行其他逻辑。

12.Redis与Spring整合:

将 Redis 与 Spring 框架整合通常使用 Spring Data Redis 这个模块来实现,Spring Data Redis 提供了一种简单而强大的方式来操作 Redis 数据库。下面是将 Redis 与 Spring 整合的详细步骤,并列出每一步所需的 Java 代码:

步骤一:添加依赖

在 Maven 项目中,需要在 pom.xml 文件中添加 Spring Data Redis 依赖:

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

步骤二:配置 Redis 连接信息

在 Spring Boot 项目中,可以在 application.properties 或 application.yml 文件中配置 Redis 的连接信息:

application.properties:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=123

步骤三:创建 Redis 配置类

创建一个配置类,用于配置 RedisTemplate 和连接工厂:

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;

@Configuration
public class RedisConfig {

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        return new JedisConnectionFactory();
    }

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

步骤四:使用 RedisTemplate 操作 Redis 数据

在 Spring 中,可以通过注入 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, String> redisTemplate;

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

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

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, String> redisTemplate;

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

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

13:关于缓存的四个注解

  1. @Cacheable:用于标记方法的结果可以被缓存,当下次使用相同的参数调用该方法时,会直接从缓存中获取结果,而不再执行方法体。

    @Cacheable(cacheNames = "books")
    public Book getBookById(String id) {
        // 从数据库或其他数据源中获取书籍信息
        return book;
    }
    
  2. @CachePut:用于标记方法的结果应该被缓存,它会执行方法体,并将结果存储到缓存中,适用于更新缓存数据的场景。

    @CachePut(cacheNames = "books", key = "#book.id")
    public Book updateBook(Book book) {
        // 更新数据库或其他数据源中的书籍信息
        return book;
    }
    
  3. @CacheEvict:用于标记方法执行后将缓存中的数据清除,适用于删除或修改缓存数据的场景。

    @CacheEvict(cacheNames = "books", key = "#id")
    public void deleteBook(String id) {
        // 删除数据库或其他数据源中的书籍信息
    }
    
  4. @Caching:用于同时应用多个缓存注解,可以在一个方法中设置多个缓存操作。

    @Caching(
        cacheable = @Cacheable(cacheNames = "books", key = "#id"),
        put = @CachePut(cacheNames = "books", key = "#result.id"),
        evict = @CacheEvict(cacheNames = "allBooks", allEntries = true)
    )
    public Book getAndCacheBook(String id) {
        // 从数据库或其他数据源中获取书籍信息
        return book;
    }
    
  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值