網站首頁 編程語言 正文
Redis擊穿
redis緩存擊穿是指某一個非常熱點的key(即在客戶端搜索的比較多的關鍵字)突然失效了,這時從客戶端發送的大量的請求在redis里找不到這個key,就會去數據里找,最終導致數據庫壓力過大崩掉。
解決方案:
1.將value的時效設置成永不過期 這種方式非常簡單粗暴但是安全可靠。但是非常占用空間對內存消耗也是極大。個人并不建議使用該方法,應該根據具體業務邏輯來操作。
2.使用Timetask做一個定時任務 使用Timetask做定時,每隔一段時間對一些熱點key進行數據庫查詢,將查詢出的結果更新至redis中。前條件是不會給數據庫過大的壓力。
3.通過synchronized+雙重檢查機制 當發生reids穿透的時候,這時海量請求發送到數據庫。這時我們的解決辦法是只讓只讓一個線程去查詢這個熱點key,其它線程保持阻塞狀態(可以讓它們sleep幾秒)。當這個進入數據庫的線程查詢出key對應的value時,我們再將其同步至redis的緩存當中,其它線程睡醒以后再重新去redis里邊請求數據。
例子:
private static volaite Object obj = new Object(); public String getValue(String key){ String value=redis.get(key,String.class); if(value==null||StringUtils.isBlank(value){ synchronized(obj){ //進入synchronized以后再去redis里查一遍,防止上一個搶到鎖的線程已經更新過了。 value=redis.get(key,String.class); if(value==null||StringUtils.isBlank(value){ value=db.query(key); redis.set(key,value,1000); } } } return value; }
缺點:存在死鎖和線程阻塞的風險。
Redis雪崩
指的是當海量的請求去查詢多個key時,此時redis緩存中失效或者查不到,然后海量的請求都去都去db查詢,從而導致db壓力突然飆升崩潰。
出現原因:
1.key同時失效
2.redis本身崩潰了
解決方案:
1.設置緩存時,隨機初始化其失效時間
如果是redis的key同時失效,可采取該辦法,具體失效時間根據業務情況決定…
2.將不同的熱點key放置到不同的節點上去
因redis一般都是集群部署,將不同的熱點key平均的放置到不同節點,也可以有效避免雪崩。
3.將value的時效設置成永不過期
4.使用Timetask做一個定時任務,在失效之前重新刷redis緩存
Redis穿透
因為不良用戶惡意頻繁查詢才會對系統造成很大的問題: key緩存并且數據庫不存在,所以每次查詢都會查詢數據庫從而導致數據庫崩潰。
(例如:我們在數據庫存放的數據其主鍵都是自增且沒有負數的,某些黑客就利用這一點,不斷用主鍵id為-1的參數來發起海量查詢請求,導致這些請求在redis中查不到相應的數據,只能去數據庫中查詢,從而導致數據庫崩潰。)
解決方案:
1.當類似的請求發過來,無論查出什么結果都放入redis緩存
這樣解決當他下次再用同一個參數發起請求時,會直接進到redis里邊去,不會再進入數據庫。
2.拉黑其ip
3.對請求的參數進行合法性校驗,在判斷其不合法的前提下直接return掉
4.使用布隆過濾器
可以將布隆過濾器理解成一個白名單或者黑名單,它的作用就是判斷一個元素是否存在于這個過濾器。
白名單: 過濾器里有數據庫中所有的合法的參數key,請求經過布隆過濾器,布隆過濾器判斷這個請求的key在不在過濾器,在就放行讓請求進入redis,不在就直接return空數據。
public static void main(String[] args){ Config config = new Config(); config.useSingleServer().setAddress("redis://127.0.0.1:6379"); config.useSingleServer().setPassword("1234"); //構造Redsson RedissonClient redisson = Redisson.create(config); RBloomFilterbloomFilter = redisson.getBloomFilter("phoneList");//給我們自己定義的布隆過濾器取名叫phoneList,名字隨便取 //初始化布隆過濾器設置預計元素為100000000L, 誤差率為3% bloomFilter.tryInit(100000000L,0.03); //將10086插入到布隆過濾器中 bloomFilter.add("10086"); //判斷下面號碼是否存在布隆過濾器中 //false System.out.println("123456"); //true System.out.println("10086"); }
缺點:
布隆過濾器可能會造成誤判,從而穿透redis進入DB,但是這個誤判概率是非常小的。
原文鏈接:https://blog.csdn.net/m0_48811221/article/details/123301041
相關推薦
- 2022-03-26 C語言的字符函數和字符串函數詳解_C 語言
- 2022-11-20 深入了解C++智能指針的使用_C 語言
- 2023-01-02 Kotlin?RadioGroup與ViewPager實現底層分頁按鈕方法_Android
- 2022-12-12 flutter?Bloc?實現原理示例解析_Android
- 2022-07-14 浮點數乘法和整形乘除法的效率經驗比較_C 語言
- 2022-02-26 sparksql之通過 structType 創建 DataFrames(編程接口)
- 2022-07-07 在Kubernetes集群中搭建Istio微服務網格的過程詳解_云其它
- 2022-03-13 在Linux系統中安裝Docker的過程_docker
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支