问题背景

为什么要使用缓存?本地缓存/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. CSS基础:块级元素与盒模型

    简介 在 HTML4.01 中,元素通常可以分为块级元素( “Block-level element” ) 和内联元素 ( "Inline-level element" ) 两大类 ...

  2. JMeter入门(01)概念和样例

    一.概念 JMeter 是一款专门用于功能测试和压力测试的轻量级测试开发平台,实现了许多和互联网相关的网络测试组件,同时还保留着很强的扩展性. JMeter可以用来测试诸如:静态文件,Java Ser ...

  3. OAuth2.0学习(1-12)开源的OAuth2.0项目和比较

    OAuth2.0学习(2-1)OAuth的开源项目   1.开源项目列表 http://www.oschina.net/project/tag/307/oauth?lang=19&sort=t ...

  4. 从零搭建 webpack3 环境 #1 - 安装使用

    目录: (1)什么是webpack (2)webpack核心概念 (3)环境安装 (4)开始使用webpack 1.什么是webpack 官网的一幅图对webpack的解释,从图中可以看出,webpa ...

  5. Python学习之输入输出、数据类型

    #coding=utf-8 # 输入 print'100+200=',100+200 # 输入 # name = raw_input('tell me your name:') # print'hel ...

  6. Django 框架介绍

    Django 框架介绍 MVC框架和MTV框架 简单了解一下什么是MVC框架.MVC(Model View Controller),是模型(model)-视图(view)-控制器(controller ...

  7. AES(高级加密)

    AES(高级加密) #3.6安装 pip3 install pycryptodome #mac pip3 install pycrypto a. 事例: ####################### ...

  8. 如何使用Visual Studio 2017自带的源代码反编译功能

    反编译C#源代码,大家可能第一时间想到 .NET Reflector 这个工具.但是这个工具反编译出来的代码跟实际源码还是有一定差距的,阅读起来不是很便利. 本人在查看Visual Studio 20 ...

  9. Python系列之 - 反射

    一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被 ...

  10. Node.js的安装以及Node.js的模块管理

    索引: Node.js的安装以及Node.js的模块管理Node.js开发环境搭建以及对ES6的支持Node.js构建Vue.js项目Vue.js单文件组件的开发基于Vue.js的UI组件(Eleme ...