本地缓存,Redis缓存,数据库DB查询(结合代码分析)
问题背景
为什么要使用缓存?本地缓存/Redis缓存/数据库查询优先级?
一、为什么要使用缓存
原因:CPU的速度远远高于磁盘IO的速度
问题:很多信息存在数据库当中的,每次查询数据库就是一次IO操作
所以,提高响应速度,必须减少磁盘IO的操作,缓存就是为了提升系统性能而存在的
二、查询的优先级
1、本地缓存
2、Redis缓存
3、数据库查询
public static List<Content> getContentList(int positionId, String provCode, String areaCode) throws SQLException {
String key_p_p_a = positionId + "_" + provCode + "_" + areaCode;
List<Content> contentList = null;
String strTemp = "|";
StringBuilder cacheLogInfoSb = new StringBuilder("get cache [");
/*判断本地缓存是否存在*/
if (ContentService.MAP_CONTENT_P_P_A.containsKey(key_p_p_a)) {
contentList = ContentService.MAP_CONTENT_P_P_A.get(key_p_p_a);
cacheLogInfoSb.append(strTemp).append(" by cache MAP_CONTENT_P_P_A get List, key:").append(key_p_p_a)
.append(",List.size:").append(contentList.size());
/*判断Reids缓存是否存在*/
}else if (RedisCached.has(key_p_p_a)) {
contentList = (List<Content>) RedisCached.get(key_p_p_a.getBytes());
cacheLogInfoSb.append(strTemp).append(" by xmemcache MAP_CONTENT_P_P_A get List, key:").append(key_p_p_a)
.append(",List.size:").append(contentList.size());
/*数据库查询操作*/
} else {
try {
contentList = dao.getContentList(positionId, provCode, areaCode);
cacheLogInfoSb = new StringBuilder(" cache is not exists,get data by database");
} catch (SQLException e) {
cacheLogInfoSb.append(strTemp).append("SQLException:").append(e.toString());
e.printStackTrace();
throw e;
}
log.info(cacheLogInfoSb.toString() + "]");
log.info("[ContentService]加入缓存key_p_p_a, key:{},contentList.size:{}", key_p_p_a, contentList.size());
/*数据库查询后,将结果写入redis,方便下次查询*/
RedisCached.set(key_p_p_a, contentList, ContentService.Cache_ExPireTime_Day);
}
return contentList;
}
三、缓存常用的集合框架以及操作(实际使用得比较多的方法)
使用的MAP集合ConcurrentHashMap
public static Map<String, List<Content>> MAP_CONTENT_P_P_A = new ConcurrentHashMap<String, List<Content>>();
读取本地缓存get()
List<Content> list = ContentService.MAP_CONTENT_P_P_A.get(key);
设置本地缓存put()
ContentService.MAP_CONTENT_P_P_A.put(key_p_p_a, contentList);
定时更新本地/Redis缓存(代码演示)
/** 查询数据库,获取最新数据 **/
Map<String, List<Content>> position_content_map_p_p_a = dao.queryContentListRelateProvCodeAreaCode(positionId);
/** 清除本地缓存 **/
Iterator<String> contentskeysIterPPA = MAP_CONTENT_P_P_A.keySet().iterator();
while (contentskeysIterPPA.hasNext()) {
String key = contentskeysIterPPA.next();
if (key.startsWith(String.valueOf(positionId))) {
removeKeys.add(key);
}
}
/** 清除Redis缓存 **/
for (int i = 0; i < removeKeys.size(); i++) {
String key = removeKeys.get(i);
contentList.addAll(MAP_CONTENT_P_P_A.remove(key));
RedisCached.delete(key);
}
removeKeys.clear();
/** 把最新内容加入MAP_CONTENT_P_P_A缓存 **/
Iterator<String> keysIterppa = position_content_map_p_p_a.keySet().iterator();
while (keysIterppa.hasNext()) {
String key = keysIterppa.next();
reFreshContenList.addAll(position_content_map_p_p_a.get(key));
MAP_CONTENT_P_P_A.putAll(position_content_map_p_p_a);
}
本地缓存,Redis缓存,数据库DB查询(结合代码分析)的更多相关文章
- Mybatis一级缓存和二级缓存 Redis缓存
一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...
- tp5 数据库Db查询操作
$data = Db::query('select * from tf_action'); $data = Db::query('select * from tf_action where id &g ...
- 使用mybatis实现分页查询示例代码分析
*******************************************分页查询开始*************************************************** ...
- Redis 多级缓存架构和数据库与缓存双写不一致问题
采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...
- 简单的redis缓存操作(get、put)
简单的redis缓存操作(get.put) 本文介绍简单的redis缓存操作,包括引入jedisjar包.配置redis.RedisDao需要的一些工具.向redis中放数据(put).从redis中 ...
- 企业项目开发--分布式缓存Redis
第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...
- 高并发架构系列:Redis缓存和MySQL数据一致性方案详解
一.需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景, ...
- Redis缓存和MySQL数据一致性方案(转)
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- redis缓存击穿问题一种思路分享
思路每一个key都有一个附属key1,附属key1可以是key加特定前缀组成,key对应value为真正的缓存数据,附属key1对应的value不重要,可以是随便一个值,附属key1的作用主要是维护缓 ...
随机推荐
- L2 约束的最小二乘学习法
\[ \begin{align*} &J_{LS}{(\theta)} = \frac { 1 }{ 2 } { \left\| \Phi \theta - y \right\| }^{ 2 ...
- JAVA_SE基础——54.异常
异常的体系: ----------| Throwable 所以异常或者错误类的超类 --------------|Error 错误 错误一般是用于jvm或者是硬件引发的问题,所以我们一般不会通 ...
- Ubuntu的软件管理与安装
感谢燕十八,的Linux的基础进阶视频 来哥:应该是装的wineQQ,它用的12年的国际版,ubuntu的这个版本应该比较好用! [3]apt-get 用Linux apt-get命令的第一步就是引入 ...
- LeetCode & Q38-Count and Say-Easy
String Description: The count-and-say sequence is the sequence of integers with the first five terms ...
- Python内置函数(21)——tuple
英文文档: The constructor builds a tuple whose items are the same and in the same order as iterable's it ...
- Go语言的核心Routine-Channel
前言 Go语言通过routine,提供了并发编程的支持. Routine特性 (1) goroutine是Go语言运行库的功能,不是操作系统提供的功能,goroutine不是用线程实现的. 例:启动一 ...
- 排序技巧——双关键字排序(快速排序,sort)
一个萌新的成长之路 Background 在做题过程中,我们常会遇到对双关键字排序的情况,如:当分数相等时,序号小的在前. 这时我们可以通过定义cmp函数作为sort的参数进行排序. Solution ...
- 如何从0开发一个Atom组件
最近用Atom写博客比较多,然后发现一个很严重的问题..没有一个我想要的上传图片的方式,比如某乎上边就可以直接copy/paste文件,然后进行上传.然而在Atom上没有找到类似的插件,最接近的一个, ...
- cache和buffer
一.free命令是Linux查看内存使用情况的命令 1. centos 7风格 [root@bogon init.d]# free -m total used free shared buff/cac ...
- phpstorm 快捷键高效助手扩展 常用快捷键收集整理 2018-04-12 16:42:10
声明: 本文属于原创,未经博主许可,禁止任何形式转载! phpstorm 快捷键整理收集 以及高效复用代码快捷键扩展 常规快捷键大全请结合参考2篇博客: https://blog.csdn.net/y ...