10. MyBatis缓存 前言 上一篇章我们已经了解了 MyBatis 加载策略,本篇章再来认识一下 MyBatis 缓存。 什么是缓存? # 缓存和缓冲的区别 1. 第一次听歌, 这首歌在本地缓存中没有, 要从网络上下载,会下载到硬盘上,作为缓存(比较慢) 2. 再次听歌, 这首歌本地缓存有了, 不需要网络上下载(比较快) ) 为什么使用缓存? “经常访问但又不经常修改的数据... ” 缓存是用来提高再次查询效率的,所有的持久层框架基本上都有缓存机制 Mybatis也提供了缓存策略,分为一级缓存,二级缓存 一级缓存 介绍 MyBatis 一级缓存是 而二级缓存则是针对一个映射查询的多次会话的查询缓存。 为true代表开启二级缓存;为false代表不开启二级缓存。
Mybatis 的一级缓存 一级缓存是 SqlSession 级别的,通过同一个 SqlSession 查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问 , 一级缓存时默认开启的 当应用程序执行查询操作时,首先查询一级缓存,如果命中缓存,则直接返回命中的结果,否则查询数据库,并将查询结果缓存到一级缓存中。 一级缓存是 SqlSession 级别的缓存,意味着同一个 SqlSession 中的所有操作共享缓存,但不同的 SqlSession 中缓存是相互独立的。 它将数据缓存在应用程序进程的内存中,相比于一级缓存的局部缓存,二级缓存是全局性的进程内缓存,可以被多个 SqlSession 共享,并且可以跨越多个 SqlSession 的生命周期。 如果二级缓存没有命中,再查询一级缓存 如果一级缓存也没有命中,则查询数据库 SqlSession 关闭之后,一级缓存中的数据会写入二级缓存 5.
NewLife.XCode是一个有10多年历史的开源数据中间件,支持nfx/netcore,由新生命团队(2002~2019)开发完成并维护至今,以下简称XCode。 XCode的数据层缓存设计于2003年,那时候只做网站和普通MIS系统,数据库性能还很差…… 数据层缓存:以查询sql为key,把查询结果缓存起来,提升系统性能! 缓存设置 数据层缓存只有一个缓存时间的设置DataCacheExpire,位于配置文件 config/xcode.config 中,默认0秒表示不启用。 连接字符串配置提供了个性化,针对部分连接需要打开数据层缓存,或者不同连接采用不能缓存时间的场景。 总结 2016年起,XCode采取了“简约”且稍微“保守”的理念,于是数据层缓存默认配置0秒,大部分场景推荐使用10~60秒。
Windows 10是目前广泛使用的操作系统之一。由于长时间运行Windows 10电脑,会积累大量临时文件、日志和其他不需要的文件,导致系统变慢并占用磁盘空间。 图片 这就是为什么需要垃圾清理。 以下是Windows 10电脑垃圾清理教程: 1. 使用磁盘清理工具 Windows 10自带了一个磁盘清理工具,可以帮助您找到和清除不需要的文件。 清理浏览器缓存和Cookie 浏览器缓存和Cookie也会占用磁盘空间,并可能导致您的浏览器变慢。打开浏览器,并找到选项,然后选择“浏览数据”。 选择要清除的数据类型(例如,缓存、Cookie等),然后单击“清除数据”按钮。 清空浏览器缓存和Cookie后,您应该可以看到浏览器速度的明显提升。 图片 总之,这些是Windows 10电脑垃圾清理的主要方法,按照教程定期清理可以使您的计算机运行得更快更稳定。
在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存。缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题。现在我们看一下怎么实现。 最近最少使用缓存的回收 为了实现缓存回收,我们需要很容易做到: 查询出最近最晚使用的项 给最近使用的项做一个标记 链表可以实现这两个操作。检测最近最少使用的项只需要返回链表的尾部。
但从上边的问题来看,数据库已无法满足需求,增加缓存就很有必要了 Django Cache Django本身就带有一个强大的缓存系统,提供不同级别的缓存粒度:可以缓存特定的视图,也可以只缓存部分模板片段, 这正是我所需要的,每次产生的新日志都不再直接写入数据库,而是先写入缓存中,待任务执行完成后一次写入数据库,这样将大大降低对数据库的消耗,且缓存大都使用内存来存储,读写效率极高 缓存配置 Django的底层缓存 ,仅用于开发模式,只是实现缓存接口,并不做其他操作 自定义的缓存后台,例如redis等 我原本是想直接使用本地内存缓存的,这样就无需再安装Memcached服务了,但是本地内存缓存为进程私有,不可跨进程访问 ,从而来控制缓存的行为,有效的参数如下: TIMEOUT: 用于缓存的默认超时时间,以秒为单位,默认为300秒,当设置为None时表示永不过时,设置为0表示立刻过期不缓存 KEY_PREFIX: 缓存键前缀 默认情况下递增幅度为1,通过指定delta可以设置递增的幅度 >>> cache.set('num', 1) >>> cache.incr('num') 2 >>> cache.incr('num', 10
在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存。缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题。现在我们看一下怎么实现。 最近最少使用缓存的回收 为了实现缓存回收,我们需要很容易做到: 查询出最近最晚使用的项 给最近使用的项做一个标记 链表可以实现这两个操作。检测最近最少使用的项只需要返回链表的尾部。
原文:https://www.cnblogs.com/raichen/p/7750165.htm 缓存穿透 概念 缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存 缓存雪崩 概念 大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。 解决办法 从业务层面。 可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。 缓存击穿(并发) 概念 高并发系统,如果一个缓存失效,存在多进程同时查询DB,同时更新缓存。 这对缓存和DB都是比较大的挑战。 解决办法 使用互斥锁(mutex key): 这种解决方案思路比较简单,就是只让一个线程构建缓存,其他线程等待构建缓存的线程执行完,重新从缓存获取数据就可以了(如下图) ?
具体到底层的实现,往往是一个Map内存缓存: (1)查询key定长,例如:司机ID; (2)返回value也定长,例如:司机实体序列化后的二进制串; 即,类似这样的一个kv缓存结构: Map<driver_id 写多读少的业务,有一种优化方案:无锁缓存,将锁冲突降低到。 无锁缓存,可能存在什么问题? 如果缓存不加锁,读写吞吐量可以达到极限,但是多线程对缓存中同一块定长数据进行写操作时,有可能出现不一致的脏数据。 这个方案为了提高性能,牺牲了一致性。 读取时,获取到了错误的数据,是不能接受的。 加上签名之后,不但缓存要写入定长value本身,还要写入定长签名(例如16bitCRC校验): (1)线程1对缓存进行操作,对key想要写入value1,写入签名v1-sign; (2)线程2对缓存进行操作 (4)数据读取的时候,不但要取出value,还要像消息接收方收到消息一样,校验一下签名,如果发现签名不一致,缓存则返回NULL,即cache miss; 当然,对应到司机地理位置,除了内存缓存之前,肯定需要
具体到底层的实现,往往是一个Map内存缓存: (1)查询key定长,例如:司机ID; (2)返回value也定长,例如:司机实体序列化后的二进制串; 即,类似这样的一个kv缓存结构: Map<driver_id 写多读少的业务,有一种优化方案:无锁缓存,将锁冲突降低到。 无锁缓存,可能存在什么问题? 如果缓存不加锁,读写吞吐量可以达到极限,但是多线程对缓存中同一块定长数据进行写操作时,有可能出现不一致的脏数据。 这个方案为了提高性能,牺牲了一致性。 读取时,获取到了错误的数据,是不能接受的。 (1)线程1对缓存进行操作,对key想要写入value1; (2)线程2对缓存进行操作,对key想要写入value2; (3)不加锁,线程1和线程2对同一个定长区域进行一个并发的写操作,可能每个线程写成功一半 加上签名之后,不但缓存要写入定长value本身,还要写入定长签名(例如16bitCRC校验): (1)线程1对缓存进行操作,对key想要写入value1,写入签名v1-sign; (2)线程2对缓存进行操作
我在 10 年前开始使用缓存,从本地缓存、到分布式缓存、再到多级缓存,踩过很多坑。下面我结合自己使用缓存的历程,谈谈我对缓存的认识。 本地缓存 页面级缓存 我使用缓存的时间很早,2010 年左右使用过 OSCache,当时主要用在 JSP 页面中用于实现页面级缓存。 添加缓存之后,优化的效果很明显 , 任务耗时从原来的 40 分钟减少到了 5~10 分钟。 上面这个示例就是典型的「对象缓存」,它是本地缓存最常见的应用场景。 缓存不为空,则将缓存数据写入本地缓存中。 这篇文章属于缓存系列的开篇,更多是把我 10 多年工作中遇到的典型问题娓娓道来,并没有非常深入地去探讨原理性的知识。 我想我更应该和朋友交流的是:如何体系化的学习一门新技术。
win10 ipconfig flushdns 清除DNS缓存,修复上网问题 一、使用 ipconfig /flushdns 命令刷新DNS解析缓存 1、右键点击系统桌面左下角的【开始】,在开始的右键菜单中点击
这是我参与「掘金日新计划 · 10 月更文挑战」的第6天,点击查看活动详情 缓存穿透 缓存穿透是指数据库和缓存都没有的数据,每次都要经过缓存直接去访问数据库,大量的请求打到DB可能导致DB宕机。 ☘️解决思路 思路一:由于缓存穿透是因为缓存没有生效,是否可以针对DB不存在的数据设置缓存空值,让请求到缓存就OK。缓存的有效时间可以设置短点,如30s,避免误伤正常业务。 缓存击穿 缓存击穿是指数据库有,缓存没有的数据,大量请求访问这个缓存不存在的数据,最后请求打到DB可能导致DB宕机。 缓存雪崩 缓存雪崩是指数据库有,缓存没有的数据,大量请求访问这些缓存不存在的数据,最后请求打到DB可能导致DB宕机。 缓存一致性 缓存一致性指的是缓存与DB之间的数据一致性,我们需要通过各种手段来防止缓存与DB不一致,我们要保证缓存与DB的数据一致或者数据最终一致。 ☘️解决思路 思路一:先删除缓存再更新数据。
(二)本地缓存 本地缓存与分布式缓存对应,缓存进程和应用进程同属于一个JVM,数据的读、写在一个进程内完成。本地缓存没有网络开销,访问速度很快。 public interface CacheNameTimeConstant { String CACHE_DEFAULT = "CACHE_DEFAULT"; String CACHE_10SECS = "CACHE_10SECS"; String CACHE_60SECS = "CACHE_60SECS"; } 同一个CacheManager配置多个CacheName,此处仅配置过期时间的差异 expireAfterWrite(5, TimeUnit.SECONDS).build())); caches.add(new CaffeineCache(CacheNameTimeConstant.CACHE_10SECS , Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build())); caches.add(new
缓存穿透 缓存穿透是指查询一个一定不存在的数据,即缓存和数据库中都没有的数据。 由于缓存不命中,并且出于容错考虑,如果从数据库查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,失去了缓存的意义。 id=-1 查询一条id为-1的数据 如何解决缓存穿透 一:对查询不到的数据也做缓存处理,只是过期时间设置短一些! 缓存击穿 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力 如何解决缓存击穿 一 ,但是缓存过期后,没有数据提供 如何解决缓存雪崩 分成事前,事中,事后三步骤 事前 一:错开设置过期时间(比如电商缓存商品可以对商品过期时间加一个随机因子,错开缓存过期时间) 发生缓存雪崩之前,事情之前
,今天给大家整理一篇关于Redis经常被问到的问题:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级等概念的入门及简单解决方案。 一、缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而对数据库 (2)还有一个解决办法解决方案是:给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存,实例伪代码如下: ? 解释说明: 1、缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存; 2、缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60 三、缓存预热 缓存预热这个应该是一个比较常见的概念,相信很多小伙伴都应该可以很容易的理解,缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。
同时,客户端拿到新的资源及其修改时间与标识后,重新进行缓存。 概括如下图: 缓存验证 协商缓存就是缓存验证。 触发时机: 用户点击刷新按钮时会开始缓存验证。 如果缓存的响应头信息里含有"Cache-control: must-revalidate”的定义,在浏览的过程中也会触发缓存验证。 协商缓存中,就有很多这样的附带条件请求。 对应的字段,存储的是上次缓存的资源最终更新时间,也就是上次缓存资源时获取的Last-Modified的值。 下一次请求相同资源的时候,浏览器从自己的缓存中找出"不确定是否过期的"缓存。
摘要:本文主要讲解在使用缓存的过程中,经常出现的三个问题:缓存穿透、缓存雪崩、缓存热点。 1.概念 缓存穿透: 大多数缓存系统,都是以key-value的格式去存储数据的,当有个请求去查询某个key,但是这个key对应的value不存在,则这个请求就会到后端DB中查询;如果有人恶意去查询缓存中不存在的 缓存雪崩: 访问量很大的系统,一般都会用缓存服务,很多请求到达在缓存层拿到值后就返回了,这样有效的减轻了DB端的压力;但是如果,缓存服务挂掉了,那所有的请求都会直接打到DB层,数据库的压力瞬间就起来了, 这样DB很可能也挂掉了,这就是缓存雪崩。 缓存热点: 一般使用缓存时,策略如下:请求一个数据,如果缓存有,直接返回,如果缓存没有,就会去查询数据库,然后返回,同时,将此key和value缓存起来,设置一个过期时间;这样做有两个好处,不仅可以加快系统对外的响应速度
,服务进程间使用了基于APCu的共享缓存,后期我将该共享缓存组件化也贡献给了社区。 【workbunny】共享高速缓存 https://www.workerman.net/plugin/133 Redis 在游戏开发界实际上使用Redis的情况还是比较多的,我们使用Redis主要还是为了将一些数据缓存共享给各个服务器实例 我们使用缓存的场景很多都是MAP数据,所以我在实现插件的时候特别实现了类似Redis-Hash相关的功能:HSet/HGet/HDel/HKeys/HExists。 APCu(Alternative PHP Cache User Cache)是一个开放源代码的PHP缓存扩展,它提供了一种在PHP应用程序中存储和检索数据的快速方法。 它是APC(Alternative PHP Cache)的继任者,专注于用户数据的缓存,而不是opcode缓存。
第10讲关于权限和缓存的参数,这两类参数参数都用得比较少,但是一些场景下还是非常有用的: 权限参数 权限参数用于显示用户有相应权限的文章,对应的参数只有一个: perm (string) – 用户权限。 array( 'publish', 'private' ), 'perm' => 'readable', ); $query = new WP_Query( $args ); 缓存参数 用于设置停用将获取到的文章存到缓存中,对应的参数有三个: cache_results (boolean) – 缓存文章信息. update_post_meta_cache (boolean) – 缓存 post meta 信息. update_post_term_cache (boolean) – 缓存对应的分类或者标签信息 显示50篇文章,但是文章信息不加入缓存中: $args = array( 另外需要注意,如果使用了持久对象缓存(例如 memcached),这些标志默认设置为 false,因为当存在持久缓存时,无需在每次页面加载时更新缓存。