news 2026/4/18 8:19:15

Redis-不止是缓存

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Redis-不止是缓存

一、Redis 到底是什么?

Redis(Remote Dictionary Server)是一个开源的、基于内存的、高性能的键值对数据库。它支持多种数据结构,包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等,因此也被称为 "数据结构服务器"。

Redis 的核心特点

  • 极致性能:基于内存操作,单线程模型,官方给出的 QPS(每秒查询率)可以达到 10 万 +
  • 丰富的数据结构:支持 8 种以上的数据结构,能满足各种业务场景
  • 持久化:支持 RDB 和 AOF 两种持久化方式,保证数据不丢失
  • 高可用:支持主从复制、哨兵模式和集群模式,能搭建高可用的分布式系统
  • 原子性:所有操作都是原子性的,不用担心并发问题

简单来说,Redis 就是一个 "又快又全能" 的数据库。它比 MySQL 快 100 倍以上,又比 Memcached 支持更多的数据结构和功能。

二、Redis 的 8 大核心应用场景

很多人只用 Redis 做缓存,这简直是 "杀鸡用牛刀"。下面我就介绍 Redis 最常用的 8 个应用场景,每一个都能解决你实际开发中的痛点。

1. 数据缓存(最常用)

这是 Redis 最基本也是最常用的功能。把热点数据(比如商品详情、用户信息、配置信息)存到 Redis 中,用户请求时直接从 Redis 获取,不用再查数据库,能极大提升系统性能,降低数据库压力。

典型场景:电商首页的商品列表、用户登录信息、系统配置参数。

2. 分布式锁

在分布式系统中,多个服务实例同时操作同一个资源时,需要用分布式锁来保证数据一致性。Redis 的SETNX命令可以非常方便地实现分布式锁。

典型场景:订单扣库存、秒杀活动、定时任务防重复执行。

3. 计数器

Redis 的INCR命令是原子性的,可以用来实现各种计数器功能。

典型场景:文章阅读量、点赞数、评论数、商品销量、接口调用次数统计。

4. 限流

基于 Redis 的计数器或滑动窗口算法,可以实现接口限流功能,防止系统被恶意请求打垮。

典型场景:短信验证码发送频率限制、API 接口调用频率限制、秒杀活动的流量控制。

5. 排行榜

Redis 的有序集合(Sorted Set)天生就是为排行榜设计的。它可以快速插入、删除和排序,性能非常高。

典型场景:游戏排行榜、商品销量排行榜、热门搜索排行榜。

6. 消息队列

Redis 的列表(List)可以作为简单的消息队列使用,支持先进先出(FIFO)的消息传递。

典型场景:异步任务处理、日志收集、订单状态变更通知。

7. 会话存储

把用户的 Session 信息存到 Redis 中,可以实现分布式系统的会话共享。

典型场景:单点登录(SSO)、分布式系统的用户状态管理。

8. 布隆过滤器

Redis 4.0 之后支持布隆过滤器插件,可以用来快速判断一个元素是否存在于一个集合中。

典型场景:缓存穿透防护、垃圾邮件过滤、重复数据判断。

三、Spring Boot 集成 Redis 完整教程

下面我就以最常用的 Spring Boot 框架为例,教你如何快速集成和使用 Redis。

第一步:引入依赖

pom.xml中引入 Spring Data Redis 依赖:

xml

<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 连接池依赖 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency>

第二步:配置 Redis

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

yaml

spring: redis: host: localhost port: 6379 password: 123456 database: 0 # 连接池配置 lettuce: pool: max-active: 8 max-wait: -1ms max-idle: 8 min-idle: 0

第三步:配置 RedisTemplate

默认的RedisTemplate会使用 JDK 序列化,序列化后的数据在 Redis 中看起来是乱码。我们需要自定义RedisTemplate,使用 Jackson2JsonRedisSerializer 序列化:

java

运行

@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // 使用Jackson2JsonRedisSerializer序列化值 Jackson2JsonRedisSerializer<Object> jacksonSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jacksonSerializer.setObjectMapper(objectMapper); // String序列化器 StringRedisSerializer stringSerializer = new StringRedisSerializer(); // key和hashKey使用String序列化 template.setKeySerializer(stringSerializer); template.setHashKeySerializer(stringSerializer); // value和hashValue使用Jackson序列化 template.setValueSerializer(jacksonSerializer); template.setHashValueSerializer(jacksonSerializer); template.afterPropertiesSet(); return template; } }

第四步:使用 RedisTemplate 操作 Redis

现在你就可以在代码中注入RedisTemplate,操作各种数据结构了:

java

运行

@Service public class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate; // 操作字符串 public void setUser(User user) { redisTemplate.opsForValue().set("user:" + user.getId(), user, 30, TimeUnit.MINUTES); } public User getUser(Long id) { return (User) redisTemplate.opsForValue().get("user:" + id); } // 操作哈希 public void setUserField(Long id, String field, Object value) { redisTemplate.opsForHash().put("user:" + id, field, value); } // 操作有序集合(排行榜) public void addScore(Long userId, double score) { redisTemplate.opsForZSet().incrementScore("rank", userId, score); } public Set<ZSetOperations.TypedTuple<Object>> getTop10() { return redisTemplate.opsForZSet().reverseRangeWithScores("rank", 0, 9); } }

四、深入原理:Redis 为什么这么快?

很多人都知道 Redis 很快,但很少有人能说清楚它为什么这么快。其实 Redis 的高性能是由四个关键因素共同决定的:

1. 完全基于内存

Redis 的所有数据都存储在内存中,内存的读写速度比磁盘快几个数量级。这是 Redis 快的最根本原因。

2. 单线程模型

Redis 采用单线程模型来处理请求,避免了多线程之间的上下文切换和竞争条件。很多人会问:"单线程怎么能处理这么多并发请求?"

答案是:Redis 的单线程指的是处理网络请求和命令执行的线程只有一个,但 Redis 还有其他线程负责持久化、集群同步等操作。而且单线程并不意味着性能差,只要 CPU 不是瓶颈,单线程的效率往往比多线程更高。

3. 高效的数据结构

Redis 的每种数据结构都经过了精心设计,底层使用了多种高效的数据结构实现:

  • 字符串:SDS(简单动态字符串)
  • 哈希:压缩列表 + 哈希表
  • 列表:压缩列表 + 双向链表
  • 集合:整数集合 + 哈希表
  • 有序集合:压缩列表 + 跳表

4. 非阻塞 I/O 多路复用

Redis 使用 I/O 多路复用技术(epoll)来处理多个网络连接,一个线程可以同时处理成千上万的客户端连接。

五、Redis 三大缓存问题与解决方案

在生产环境中使用 Redis,最常见的问题就是缓存穿透、缓存击穿和缓存雪崩。这三个问题如果处理不好,会导致数据库压力骤增,甚至宕机。

1. 缓存穿透

问题描述:用户请求的数据既不在缓存中,也不在数据库中。这样每次请求都会打到数据库上,恶意攻击者可以利用这个漏洞来攻击系统。

解决方案

  • 布隆过滤器:将所有可能存在的数据哈希到一个足够大的布隆过滤器中,请求先经过布隆过滤器过滤
  • 缓存空值:如果数据库中也没有数据,就缓存一个空值,并设置一个较短的过期时间

2. 缓存击穿

问题描述:一个热点 key 在过期的瞬间,有大量的并发请求同时访问这个 key。这些请求都会打到数据库上,导致数据库压力骤增。

解决方案

  • 互斥锁:当缓存失效时,只有第一个请求能获取到锁,去数据库查询数据并更新缓存
  • 永不过期:对于特别热点的 key,不设置过期时间,后台异步更新缓存

3. 缓存雪崩

问题描述:大量的 key 在同一时间过期,导致所有请求都打到数据库上,数据库压力骤增。

解决方案

  • 过期时间加随机值:给每个 key 的过期时间加上一个随机值,避免同时过期
  • 多级缓存:使用本地缓存 + Redis 缓存的多级缓存架构
  • 熔断降级:当数据库压力过大时,熔断部分非核心接口,返回默认数据

六、Redis 生产环境最佳实践

最后,我分享几个我在生产环境中总结的 Redis 最佳实践,帮你避开常见的坑:

  1. key 命名规范:使用冒号分隔的命名方式,如业务:模块:id,例如user:info:123
  2. 设置过期时间:所有的 key 都应该设置合理的过期时间,避免内存泄漏
  3. 避免大 key:单个 key 的大小不要超过 1MB,大 key 会导致网络传输慢、内存碎片多
  4. 批量操作:使用pipeline进行批量操作,减少网络往返次数
  5. 不要在 Redis 中存储大对象:大对象应该存储在数据库或对象存储中,Redis 只存储引用
  6. 开启持久化:根据业务需求选择合适的持久化方式,重要数据一定要开启持久化
  7. 监控 Redis 状态:监控 Redis 的内存使用率、QPS、命中率等指标,及时发现问题
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 8:19:15

终极指南:5步免费完整备份Mac微信聊天记录,告别数据丢失焦虑

终极指南&#xff1a;5步免费完整备份Mac微信聊天记录&#xff0c;告别数据丢失焦虑 【免费下载链接】WeChatExporter 一个可以快速导出、查看你的微信聊天记录的工具 项目地址: https://gitcode.com/gh_mirrors/wec/WeChatExporter 你是否曾经因为误删微信聊天记录而懊…

作者头像 李华
网站建设 2026/4/18 8:17:32

GitHub中文界面插件终极指南:3分钟让你的GitHub全面中文化

GitHub中文界面插件终极指南&#xff1a;3分钟让你的GitHub全面中文化 【免费下载链接】github-chinese GitHub 汉化插件&#xff0c;GitHub 中文化界面。 (GitHub Translation To Chinese) 项目地址: https://gitcode.com/gh_mirrors/gi/github-chinese 你是否曾经因为…

作者头像 李华
网站建设 2026/4/18 8:04:27

YOLO12镜像使用全攻略:从启动到检测,完整流程详解

YOLO12镜像使用全攻略&#xff1a;从启动到检测&#xff0c;完整流程详解 1. YOLO12镜像概述 YOLO12是2025年最新发布的目标检测模型&#xff0c;采用革命性的注意力为中心架构&#xff0c;在保持实时推理速度的同时实现了最先进的检测精度。该镜像预装了YOLO12-M模型和完整的…

作者头像 李华
网站建设 2026/4/18 7:56:41

Windows 添加右键菜单:复制 / 分割路径(URI路径)

很实用的一个设置。我们知道&#xff0c;Windows 中的路径是使用 \ 分割的&#xff0c;但 \ 在大多数编程语言中被用于转义字符&#xff0c;这使得在 Windows 下复制的路径字符串都不能直接在程序中使用&#xff0c;需要手动把 \ 替换成 /&#xff0c;使用 / 分割的路径在绝大…

作者头像 李华
网站建设 2026/4/18 7:56:36

QGIS自动化脚本:高效批量导出矢量图层实战

1. 为什么需要批量导出矢量图层&#xff1f; 在日常的GIS工作中&#xff0c;我们经常会遇到需要处理大量矢量图层的情况。比如在做城市规划分析时&#xff0c;可能需要同时导出几十个甚至上百个不同区域的土地利用图层&#xff1b;在进行环境监测时&#xff0c;可能需要批量处理…

作者头像 李华