php cachelock,巧用lock解决缓存击穿的解决方案
背景
缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。
解决方案
1、设置热点数据永远不过期。
2、加互斥锁,互斥锁参考代码如下:
2.1、根据key生成object()
private static object GetMemoryCacheLockObject(string key){string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);lock (CacheObject){var lockObject = CacheObject[cacheLockKey];if (lockObject == null){// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取lockObject = new object();CacheObject.Set(cacheLockKey,lockObject,new System.Runtime.Caching.CacheItemPolicy(){AbsoluteExpiration = DateTimeOffset.UtcNow.AddMinutes(10)});}return lockObject;}}
2.2、lock住GetMemoryCacheLockObject(key)
public T Get(string key, Func getDataWork, TimeSpan absoluteExpireTime, bool forceRefresh = false, bool returnCopy = true) where T : class{try{lock (GetMemoryCacheLockObject(key)){/*System.ArgumentNullException: Value cannot be null.at System.Threading.Monitor.Enter(Object obj)at BQoolCommon.Helpers.Cache.MemoryCacheLayer.Get[T](String key, Func`1 getDataWork, TimeSpan absoluteExpireTime, Boolean forceRefresh, Boolean returnCopy) in D:\Source\BQoolCommon\BQoolCommon.Helpers\Cache\MemoryCacheLayer.cs:line 46*/T result = CacheObject[key] as T;if (result != null && forceRefresh){// 是否清除Cache,強制重查result = null;}if (result == null){//執行取得資料的委派作業result = getDataWork();if (result != null){Set(key, result, absoluteExpireTime);}}if (returnCopy){//複製一份新的參考string serialize = JsonConvert.SerializeObject(result);return JsonConvert.DeserializeObject(serialize);}else{return result;}}}catch{return getDataWork();}}
总结说明
1、缓存中有数据,直接走下述代码就返回结果了
T result = CacheObject[key] as T;
2、缓存中没有数据,第1个进入的线程,获取锁并从数据库去取数据,没释放锁之前,其他并行进入的线程会等待,再重新去缓存取数据。这样就防止都去数据库重复取数据,重复往缓存中更新数据情况出现。
try{lock (GetMemoryCacheLockObject(key)){/*System.ArgumentNullException: Value cannot be null.at System.Threading.Monitor.Enter(Object obj)at BQoolCommon.Helpers.Cache.MemoryCacheLayer.Get[T](String key, Func`1 getDataWork, TimeSpan absoluteExpireTime, Boolean forceRefresh, Boolean returnCopy) in D:\Source\BQoolCommon\BQoolCommon.Helpers\Cache\MemoryCacheLayer.cs:line 46*/T result = CacheObject[key] as T;
3、取得每个 Key专有的 lock object;若同时有多个 thread要求相同资料,只会(到数据库)查第一次,剩下的从 cache读取。
string cacheLockKey = string.Format(MemoryCacheLockObjectFormat, key);lock (CacheObject){var lockObject = CacheObject[cacheLockKey];if (lockObject == null){// 取得每個 Key專屬的 lock object;若同時有多個 thread要求相同資料,只會(到資料庫)查第一次,剩下的從 cache讀取lockObject = new object();
往期
精彩
回顾
php cachelock,巧用lock解决缓存击穿的解决方案相关推荐
- 巧用lock解决缓存击穿的解决方案
背景 缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力. 解决方案 1.设置热 ...
- Spring Cache使用Redisson分布式锁解决缓存击穿问题
文章目录 1 什么是缓存击穿 2 为什么要使用分布式锁 3 什么是Redisson 4 Spring Boot集成Redisson 4.1 添加maven依赖 4.2 配置yml 4.3 配置Redi ...
- 分布式之一行代码解决缓存击穿问题
开局一张图,内容全靠编- 我只能说一言难尽--我只能说,感情影响了一名剑客拔剑的速度,就是这样! 引言 今天,重新回顾一下缓存击穿这个问题! 之所以写这个文章呢,因为目前网上流传的文章落地性太差(什么 ...
- 使用BloomFilter布隆过滤器解决缓存击穿、垃圾邮件识别、集合判重
Bloom Filter是一个占用空间很小.效率很高的随机数据结构,它由一个bit数组和一组Hash算法构成.可用于判断一个元素是否在一个集合中,查询效率很高(1-N,最优能逼近于1). 在很多场景下 ...
- Redis( 缓存篇 ==> 互斥锁解决缓存击穿
我们可以在查询缓存未命中的时候添加一个互斥锁.这样一来,在面对高并发的情况下,只有第一个进来的线程才可以拿到锁然后操作数据库,待操作结束后释放锁,未拿到锁的用户则等待一段时间重新查询缓存,直到缓存重建 ...
- Redis缓存击穿问题及解决思路
Redis缓存击穿问题及解决思路 1. 什么是缓存击穿 2. 解决方案 2.1 使用锁来解决(互斥锁) 2.2 逻辑过期 2.3 进行对比 1. 什么是缓存击穿 缓存击穿也叫热点key问题,就是一个被 ...
- Redis分布式锁防止缓存击穿
缓存击穿 和缓存穿透不同的是,缓存击穿是指:缓存中没有,但是数据库中存在的热点数据. 例如:首页的热点新闻,并发访问量非常大的热点数据,如果缓存过期失效,服务器会去查询DB,这时候如果大量的并发去查询 ...
- 明白了缓存穿透和缓存雪崩,再了解一下缓存击穿!
作者 l 会点代码的大叔(CodeDaShu) 在往期文章中,我们介绍了缓存穿透和缓存雪崩,其中缓存雪崩,是对于一些设置了过期时间的 key,在某个时间点集体失效后,有大量的请求落到数据库上导致被击垮 ...
- 【Redis笔记】缓存穿透与缓存击穿以及应对方法
[Redis笔记]缓存穿透与缓存击穿以及应对方法 一.缓存穿透 1. 缓存穿透概念 2. 缓存穿透解决方法 示例代码 二.缓存击穿 1. 缓存击穿概念 2. 缓存击穿解决方法 方法一:互斥锁 示例代码 ...
最新文章
- 互次方科技金立(沃兹):深入浅出项目管理
- Nature:2020年最佳科学影像,每一张都是壁纸,每一张都是历史
- openresty开发系列12--lua介绍及常用数据类型简介
- 解决iOS地图持续定位耗电问题
- FFmpeg 源代码:avcodec_find_encoder()和avcodec_find_encoder_by_name()
- nginx长连接出现504的解决办法
- 小额贷款利息违法吗?
- python依赖注入_如何做依赖注入python方式?
- sigal mq_notify
- setState是同步的还是异步的(都有)
- Windows上设置Docker共享盘符
- ucc编译器(x86移植)
- oracle 创建表同时添加注释
- 《圈圈教你玩USB》 第三章 USB鼠标的实现——看书笔记( 2 )
- 蓝桥杯题目练习 提升篇 [蓝桥杯2018初赛]三体攻击
- 明华读卡器 java_明华读卡器Java例程
- 独家插件!非常好用的CASS地形图绘制插件
- 【读书笔记】你离考研成功就差这本书
- 中国网游未来发展方向预测
- Dreamweaver中如何设定文字——大小、字体、颜色
热门文章
- JQuery Datatables单元格内显示数据太长,截取部分显示功能
- 编写有效用例电子版_剖析用例设计方法的使用
- 4列变成5列 datatable_云南美食界“5巨头”,谁才是NO.1?你家乡的那道菜也在列...
- python同时输出两个数组_python中实现将多个print输出合成一个数组
- 为什么用pyqt的不多_现在农村提倡用天然气和清洁煤球取暖,为何农民不爱用?看完懂了...
- 搜狗浏览器怎么实现图标旋转 搜狗浏览器实现图标旋转的方法
- 如何在Chrome浏览器中创建账户?
- 谷歌浏览器怎么截图 Google Chrome截图方法
- java中字典算法_Java字典生成算法讲解
- java+的数组分割符_Java:使用分隔符连接基元数组