**redis缓存如何解决数据更新的问题**
方案1
[主动]后台点击更新缓存按钮,从DB查找最新数据集合,删除原缓存数据,存储新数据到缓存;
问题:更新过程中删除掉缓存后刚好有业务在查询,那么这个时候返回的数据会是空,会影响用户体验
方案2
[被动]前台获取数据时发现没有缓存数据就会去数据库同步数据到缓存
问题:当并发请求获取缓存数据不存在的时候,就会产生并发的查询数据的操作。
方案3
[主动]后台点击更新缓存按钮,从DB查找最新数据集合,这里不删除缓存,通过遍历数据覆盖和删除掉无效的数据
问题:逻辑相对麻烦,而且更新机制无法通用;
推荐
以上的几种更新方案我都遇到过,因为产生了各种问题,所以我想到了一个相对好的方案,类似预加载功能,先把数据加载到缓存中,缓存成功后再切换显示最新的数据,将旧数据设置过期;
方案4
前台获取缓存的时候需要先得到缓存数据对应的Redis Key(简称:[ShowingKey](可以是最近一次更新缓存的时间戳或者根据自己规则自定义),然后根据[ShowingKey]去读取缓存数据(简称:[缓存];
更新总结
第1种更新方案影响用户体验一般不推荐使用
第2种更新方案可以通过程序锁,锁住更新操作只能有一个进入DB查询,可以避免问题
第3种更新方案不会有第1,2 的问题,但是更新逻辑写起来比较麻烦,而且更新方案不能抽象通用
第4种更新方案使用提前加载到缓存,然后在切换需要显示的缓存数据,可以完美解决1,2,3中的问题, redis内存不足,滥用
问题
数据不断累加,无效数据未清理,缓存未设置过期时间
存储数据中包含未使用到字段,整个对象序列化到redis中
冷数据,或者根本不会再去使用的无效数据没有清理
解决
数据区分无效时间,设置过期时间,使无效数据过期;(如:通过日期后缀命名Key)
区分冷数据,清理掉冷数据;
缓存数据从简,redis key命名从简,数据字段命名从简,无效字段不添加在缓存中;键命名规范
redis缓存和map缓存
Redis 可以实现分布式的缓存,Map 属于本地缓存,只能存在创建它的程序里
Redis 的缓存可以持久化,Map 是内存对象,程序一重启数据就没了
Redis 缓存有过期机制,Map 本身无此功能
Redis 可以处理每秒百万级的并发,是专业的缓存服务,Map 只是一个普通的对象
Redis 可以用几十 G 内存来做缓存,Map 不行,一般 JVM 也就分几个 G 数据就够大了
Redis 有丰富的 API,Map 就简单太多了
关于本地缓存和分布式缓存
缓存分为本地缓存和分布式缓存。
以java为例,使用自带的map或者guava实现的是本地缓存,其最主要的特点是轻量、快速,生命周期随着jvm的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。
使用redis或memcached之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。缺点是需要保持redis或memcached服务的高可用,整个程序架构上较为复杂。
********mysql的两种搜索引擎********
InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;
- InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;
- InnoDB 是聚集索引,MyISAM 是非聚集索引。InnoDB 必须要有主键,通过主键索引效率很高。MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。
- InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;
- InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一
本文讨论了Java应用中Redis缓存的更新策略,包括主动更新、被动更新及其优缺点。提出了一种预加载方案以改善用户体验,同时强调了数据过期管理和无效数据清理的重要性。还对比了Redis分布式缓存与本地缓存(如Map)的差异,并提及InnoDB与MyISAM存储引擎的区别。
173万+

被折叠的 条评论
为什么被折叠?



