缓存Redis等
REDIS
redis客户端对比
在对比Java中常用的Redis客户端时,主要有三种官方推荐的客户端:Jedis、Lettuce和Redisson。Spring Boot 2.x版本之后,默认的Redis客户端是Lettuce以下是它们的对比:
-
Jedis:
- 简介:Jedis是一个老牌的Redis Java客户端,提供了全面的Redis命令支持。
- 优点:轻量、简洁,便于集成和改造;支持连接池、pipelining、事务、LUA Scripting、Redis Sentinel和Redis Cluster。
- 缺点:不支持读写分离,需要自行实现;文档较差,几乎没有文档。
-
Lettuce:
- 简介:Lettuce是一个可扩展的线程安全的Redis客户端,支持异步模式。
- 优点:基于Netty框架,支持高级Redis特性,如哨兵、集群、管道等;API线程安全,多个线程可以共享一个连接。
- 缺点:学习使用成本相对较高。
-
Redisson:
- 简介:Redisson是一个基于Redis实现的Java驻内存数据网格,提供了一系列的分布式Java常用对象和许多分布式服务。
- 优点:提供了很多分布式相关操作服务,如分布式锁、分布式集合等;支持读写分离和读负载均衡;内建Tomcat Session Manager,可与Spring Session集成。
- 缺点:对字符串的操作支持较差。
使用建议:
- 如果不需要使用Redis的高级功能,推荐使用Lettuce,因为它的性能较好,API线程安全,且支持异步操作。
- 如果应用中需要使用到Redis的高级功能,建议使用Redisson,因为它提供了很多开箱即用的Redis高级功能。
综上所述,选择哪种客户端取决于具体的业务需求和项目特点。Jedis因其简单全面而被广泛使用,Lettuce因其性能和线程安全性而受到青睐,而Redisson则因其提供的分布式服务而特别适合需要这些高级功能的场景。
缓存击穿,缓存穿透,等
1 安全问题,缓存没有,数据库没有,黑客攻击会导致数据库奔溃。
2 非安全问题
- 缓存同时失效
解决方案
- 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。可以是一个基础时间(比如1小时)和一个随机的时间(随机产生0-600秒)叠加。
- 设置热点数据永远不过期
- 刚上线的时候进行缓存预热。缓存预热指系统上线后,将相关的缓存数据直接加载到缓存系统,而不是等待用户访问才来触发缓存加载。
- 秒杀等高并发场景下,取不到缓存同时访问数据库对数据库压力很大。
互斥锁,当缓存没找到数据,需要访问数据库前,启动互斥锁,只允许一个线程访问数据库并更新缓存。未能获取更新锁的线程要么等待锁释放后重新读取缓存,要么就返回空值或者默认值。
缓存适用方法: Cache-Aside
这可能是最常用的缓存方法。缓存位于一边,应用程序直接与缓存和数据库对话。
这种模式主要流程如下
- 应用在查询数据的时候,先从缓存Cache中读取数据,如果缓存中没有,则再从数据库中读取数据,得到数据库的数据之后,将这个数据也放到缓存Cache中。
- 如果应用要更新某个数据,也是先去更新数据库中的数据,更新完成之后,则通过指令让缓存Cache中的数据失效。
当使用cache-aside时,最常见的写策略是直接将数据写到数据库中。当这种情况发生时,缓存可能与数据库不一致。为了解决这个问题,开发人员通常会引入TTL,并继续提供陈旧的数据,直到TTL过期。
读者会好奇的问,为什么不先更新数据库,再更新缓存呢?
如果同时有两个写请求需要更新数据,每个写请求都先更新数据库再更新缓存,在并发场景可能会出现数据不一致的情况。
例如对于同一条记录,即使db有写锁,但如果写请求1与缓存所在机房距离太远或是卡顿(比如发生GC,cpu资源被其他线程抢占了等等),先发后至,写请求2先更新完了缓存,如果db无写锁问题就更大了,所以不推荐。
mySQL 里有 2000w 数据,redis 中只存 20w 的数据,如何保证 redis 中的数据都是热点数据
换句话说,redis缓存的空间是有限的,如何最有效的利用redis(缓存命中率),确保最佳性能
-
基于数据访问频率的缓存策略
- LRU(Least Recently Used)算法:
- 原理:LRU是一种常见的缓存淘汰策略。它的核心思想是根据数据的访问时间来判断数据是否为热点数据。当需要向Redis中插入新数据,但Redis的内存已满时,LRU算法会淘汰最近最少使用的数据。这样可以保证留在Redis中的数据都是最近经常被访问的热点数据。
- 在Redis中的实现:Redis本身提供了近似LRU的算法来实现缓存淘汰。可以通过配置
maxmemory - policy
参数为volatile - lru
(用于设置了过期时间的数据)或allkeys - lru
(用于所有数据)来启用LRU策略。不过需要注意的是,Redis的LRU是近似的,因为完全精确的LRU算法需要额外的记录开销,Redis采用了一种抽样的方式来近似实现LRU,在性能和准确性之间做了平衡。
- LFU(Least Frequently Used)算法:
- 原理:LFU算法则是基于数据的访问频率来判断是否为热点数据。它记录每个数据被访问的次数,当需要淘汰数据时,会选择访问次数最少的数据进行淘汰。与LRU不同,LFU更关注数据的长期访问频率,而不仅仅是最近是否被访问。
- 在Redis中的实现:Redis也支持LFU算法,可以将
maxmemory - policy
参数设置为volatile - lfu
或allkeys - lfu
来启用。在LFU算法中,Redis为每个键维护一个访问频率计数器,并且会根据一定的规则(如随着时间衰减访问频率等)来更准确地反映数据的热度。
- LRU(Least Recently Used)算法:
-
数据预热与动态调整
- 数据预热:
- 在系统启动或定期维护时,可以对Redis进行数据预热。通过分析历史数据访问记录或者业务的重点数据范围,预先将预计会成为热点的数据加载到Redis中。例如,对于一个电商系统,可以将热门商品的信息、频繁访问的分类页面数据等在系统启动时就加载到Redis中。
- 具体操作可以是编写脚本,从MySQL中查询出这些热点数据,然后插入到Redis中。这样可以在系统一开始运行时,就为用户提供快速访问热点数据的能力。
- 数据预热:
-
结合业务规则确定热点数据
- 不同的业务有不同的热点数据定义方式。例如,对于一个新闻网站,热点新闻的排名可能会根据浏览量、评论数、发布时间等多种因素综合确定。可以根据这些业务规则,在MySQL中通过复杂的SQL查询(如结合排序、分组、统计函数等)筛选出热点数据,然后更新到Redis中。
- 以新闻网站为例,可以定期(如每小时)运行以下SQL查询来找出热点新闻:
SELECT * FROM news_table WHERE publish_time > CURDATE() - INTERVAL 1 DAY ORDER BY views_count + comments_count DESC LIMIT 100;
上述查询会找出发布时间在一天内,并且根据浏览量和评论数之和排序后的前100条新闻,这些新闻可以被认为是热点新闻,然后将其相关数据(如新闻标题、内容摘要等)存储到Redis中,方便用户快速访问。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南