问题背景

为什么要使用缓存?本地缓存/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查询(结合代码分析)的更多相关文章

  1. Mybatis一级缓存和二级缓存 Redis缓存

    一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...

  2. tp5 数据库Db查询操作

    $data = Db::query('select * from tf_action'); $data = Db::query('select * from tf_action where id &g ...

  3. 使用mybatis实现分页查询示例代码分析

    *******************************************分页查询开始*************************************************** ...

  4. Redis 多级缓存架构和数据库与缓存双写不一致问题

    采用三级缓存:nginx本地缓存+redis分布式缓存+tomcat堆缓存的多级缓存架构 时效性要求非常高的数据:库存 一般来说,显示的库存,都是时效性要求会相对高一些,因为随着商品的不断的交易,库存 ...

  5. 简单的redis缓存操作(get、put)

    简单的redis缓存操作(get.put) 本文介绍简单的redis缓存操作,包括引入jedisjar包.配置redis.RedisDao需要的一些工具.向redis中放数据(put).从redis中 ...

  6. 企业项目开发--分布式缓存Redis

    第九章 企业项目开发--分布式缓存Redis(1) 注意:本章代码将会建立在上一章的代码基础上,上一章链接<第八章 企业项目开发--分布式缓存memcached> 1.为什么用Redis ...

  7. 高并发架构系列:Redis缓存和MySQL数据一致性方案详解

    一.需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景, ...

  8. Redis缓存和MySQL数据一致性方案(转)

    需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...

  9. redis缓存击穿问题一种思路分享

    思路每一个key都有一个附属key1,附属key1可以是key加特定前缀组成,key对应value为真正的缓存数据,附属key1对应的value不重要,可以是随便一个值,附属key1的作用主要是维护缓 ...

随机推荐

  1. istio入门(03)istio的helloworld-场景说明

    一.原生应用 四个微服务: python微服务:一个deployment(deployment含有一个pod,pod内含有一个容器) java微服务:三个deployment(deployment含有 ...

  2. Spring知识点回顾(06)Profile 和 条件注解 @Conditional

    1.设定环境中的active profiles 如:DispatcherServerlet的init-param spring.profiles.active=production spring.pr ...

  3. 阿里云API网关(8)开发指南-SDK下载

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  4. windbg分析Kernel32.dll导出表

    写在前面的话: 继续上篇,在获得了Kernel32.dll基址的基础上,分析它的导出表结构: 对PE结构不太熟悉的同学,可以参考看雪论坛里的一篇帖子:https://bbs.pediy.com/thr ...

  5. less规范

    Less 编码规范 (1.1) 简介 该文档主要的设计目标是提高 Less 文档的团队一致性与可维护性. Less 代码的基本规范和原则与 CSS 编码规范 保持一致. 编撰 吕俊涛 本文档由商业运营 ...

  6. python爬虫requests json与字典对象互相转换

    import requests import json ''' json.loads(json_str) json字符串转换成字典 json.dumps(dict) 字典转换成json字符串 ''' ...

  7. POJ-2031 Building a Space Station---MST + 空间距离

    题目链接: https://vjudge.net/problem/POJ-2031 题目大意: 就是给出三维坐标系上的一些球的球心坐标和其半径,搭建通路,使得他们能够相互连通.如果两个球有重叠的部分则 ...

  8. tkinter的冷却技能

    validatecommand=(f,s1,s2,s3) f就是冷却后的验证函数名,s1,s2,s3这些时额外的选项,这些选项会作为参数依次传给f函数. register()冷却作用:register ...

  9. Delphi X10.2 + FireDAC 使用 SQL 语句 UPDATE

    MainForm.Conn.StartTransaction; UserManagerQuery.SQL.Clear; UserManagerQuery.SQL.Text := 'UPDATE tab ...

  10. 0415关于通过FILEBEAT,LOGSTASH,ES,KIBNA实现数据的采集

    如何通过FILEBEAT,LOGSTASH,ES,KIBNA实现数据的采集总体参考网址:https://www.olinux.org.cn/elk/1157.html官方网址:https://www. ...