Redis核心機制-緩存、分布式鎖

目錄

緩存

緩存更新策略

定期生成

實時生成

緩存問題

緩存預熱(Cache preheating)

緩存穿透(Cache penetration)

緩存雪崩(Cache avalanche)

緩存擊穿(Cache breakdown)

分布式鎖

分布式鎖基礎實現

引入過期時間

引入校驗id

引入lua腳本

引入watch dog(看門狗)

引入Redlock算法


緩存

緩存的核心思路就是把常用的數據放入訪問速度更快的地方,方便隨時讀取。使用Redis作為緩存,數據是直接存儲在內存上的,對于關系型數據庫例如MySql來說速度更快。

為什么說關系型數據庫性能不高?

1.數據庫將數據存儲在硬盤上,硬盤的IO速度沒有內存快。

2.如果查詢不能命中索引,就需要進行表的遍歷,這就會大大增加硬盤IO次數。

3.關系型數據庫會對SQL的執行做一系列的解析,校驗,優化工作。

4.復雜查詢更加消耗效率。(笛卡爾積)

?如果全部請求直接訪問數據庫,對于數據庫壓力很大,很容易使數據庫服務器宕機。使用Redis緩存可以加快讀操作,寫操作還是得寫在數據庫中。

緩存更新策略

定期生成

每隔一定時間,對訪問數據頻次較高的數據進行統計,挑選出訪問頻次最高的前N%的數據,導入到Redis中。實時性比較低,面對突發情況不友好。如春節期間,“春節”的搜索頻率變高,在平時搜索頻率比較低。

實時生成

用戶查詢數據,如果沒有在Redis中命中,就在數據庫中查詢,然后將結果更新到Redis中。如果Redis緩存滿了,就可以使用內存淘汰策略進行刪除:

FIFO(First In First Out)先進先出

將緩存中存在時間最久的數據淘汰。

LRU(Least Recently Used)淘汰最久未使用的

記錄每個key的最近訪問時間,把最近訪問時間最老的key淘汰。

LFU(淘汰訪問次數最少的)

記錄每個key最近一段時間的訪問次數,淘汰訪問次數最少得到。

Random隨機淘汰

隨機淘汰緩存中的key。

緩存問題

緩存預熱(Cache preheating)

剛剛啟動Redis作為MySQL緩存時,Redis自身為空,所有請求都會直接直接訪問數據庫,從而對數據庫造成很大的壓力。

提前準備熱點數據導入Redis中,使Redis更快提供服務,解決緩存預熱問題。

緩存穿透(Cache penetration)

訪問的key在Redis和MySQL中都不存在,此時key不會放入緩存中,后續如果接著訪問這個key,依然會訪問到數據庫。這樣會給數據庫造成壓力。

針對查詢的key進行校驗,如要查詢的key為手機號,首先對key的格式進行校驗。

針對數據庫不存在的key也放入redis中。

使用布隆過濾器,判定key是否存在。

緩存雪崩(Cache avalanche)

短時間內,大量的key失效(Redis掛了/大量key同時過期),導致數據庫壓力增大。

部署高可用的Redis系統,完善監控報警體系。

不給key設置過期時間,或者設置過期時間時加入隨機因子。

緩存擊穿(Cache breakdown)

熱點key突然過期,大量請求直接訪問MySQL數據庫。

將這些熱點key設置為永不過期。

分布式鎖

分布式系統中,當不同節點訪問統一資源時,就需要通過鎖進行互斥控制,避免出現類似“線程 安全”問題。在分布式這種多進程,多主機的的場景中,就需要有一臺服務器進行記錄加鎖操作。

分布式鎖基礎實現

使用Redis實現分布式鎖,本質上就是通過設置一個鍵值對,然后通過鍵值對來判定是否已有其他進程加鎖。

例如在網上買票的時候,車站提供了多個服務器處理買票的請求,客戶端每次買票需要查詢車票數量,判斷車票數量是否大于1,滿足條件車票數量減一。在高并發情況下,可能會導致超賣情況,此時引入分布式鎖。

此時服務器對數據庫進行操作時,就會先判斷Redis中是否有加鎖的鍵值對,Redis中的key就可以代表車次,表示該車次的票正在其他進程中進行操作。Redis中提供了setnx操作,當key設置成功,則代表加鎖成功,反之就代表已經有其他進程進行加鎖了。設置成功后,就可以對數據庫進行讀寫操作了,操作完成之后再把Redis上剛剛的key進行刪除。

但是這個方案并不完整,當加鎖的進程在執行刪除key操作之前遇到問題(如宕機),此時刪除操作不能進行,其他進程也不能獲取鎖

引入過期時間

為解決加鎖后加鎖進程意外宕機的情況,在設置key時順便設置過期時間,表示進程持有鎖的最大時間,達到時間后就會自動刪除key,使用set ex nx命令進行設置,不能分開設置,由于Redis事務不能保證兩個操作都能成功執行,可能就會出現set nx操作成功,但是expire失敗的情況。此時任然會出現無法正確釋放鎖的問題。

但是仍然存在問題,其他進程也可以操作Redis刪除key,此時加鎖就失去了意義

引入校驗id

為解決其他進程刪除key,引入校驗機制,在設置鍵值對時,value設置為可以識別加鎖服務器的身份。在執行解鎖操作時,先根據value判斷是否為加鎖的服務器。該邏輯用偽代碼表示:

String key = "要加鎖的資源id";
String serverId = "服務器的編號";
//加鎖,設置過期時間為10s
redis.set(key,serverId,"NX","EX","10s");
//執行各種邏輯,如數據庫的增刪查改
select();
update();
delete();
insert();
//解鎖,先判斷是否為加鎖進程
if(redis.get(key) == serverId) {redis.del(key);
}

在執行解鎖操作時,解鎖的邏輯是分為兩步的,不是原子操作。一個服務器內部,可能是多線程的,同一個服務器內部,兩個線程都在執行解鎖操作,就可能導致del操作被重復執行,然后將其他加鎖線程的鎖給刪除了。

引入lua腳本

?為了使解鎖操作變為原子的,使用Redis支持的lua腳本,將查詢和刪除操作打包為原子操作,可以將上述代碼編寫成一個.lua后綴的文件,一個lua腳本會被Redis服務器以原子的方式進行執行。

引入watch dog(看門狗)

設置key過期時間后,任然存在當前任務沒有執行完,key就過期了的情況,導致鎖提前失效。引入watch dog,本質上是加鎖的服務器上一個單獨的線程,通過這個線程來對鎖的過期時間進行“續約”。這個線程并不是Redis提供,而是業務服務器上的線程。

假設設置一個key,過期時間為10s,設定看門狗線程沒3s檢測一次。

當3s時間到的時候,看門狗就會判定當前任務是否完成。

如果完成,可通過lua腳本直接釋放鎖。

未完成,則將過期時間重新設置為10s(續約)。

這樣就不用擔心鎖提前失效的問題。如果該服務器掛了,那么看門狗線程也隨之掛了,沒人給鎖續約,到達過期時間后key就會過期,讓其他服務器能夠獲取鎖。

引入Redlock算法

?實踐中Redis一般是以集群的方式部署的(至少是主從結構),Redis成為分布式鎖可能會遇到一些極端情況:負責加鎖的master節點剛剛進行加鎖操作,然后就掛了,此時slave節點成了新的master節點,由于此時的key并沒有同步給slave節點,導致加鎖操作形同虛設。

解決辦法:引入一組Redis節點,每一組Redis節點都包含master節點和slave節點,組與組之間的數據都是一致的,相互之間為“備份”關系。在進行加鎖操作時,設置加鎖操作的超時時間,比如設置為30ms,超過30ms沒有加鎖,則視為加鎖失敗。如果當前節點加鎖失敗。就立即嘗試下一個節點,當加鎖成功的節點超過總結點的一半,則視為加鎖成功。即使某些節點掛了也不會影響鎖的正確性。

文章結束,感謝觀看!?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74710.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74710.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74710.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

CF每日5題(1300-1500)

最近急速補練藍橋杯中,疏于cf練習。 感覺自己過題還是太慢了。 今日水題,我水水水水。 1- 1979C lcm 水 1400 第 i i i局贏了,1個硬幣頂 k [ i ] k[i] k[i]個貢獻,所以每局分硬幣 x i 1 k [ i ] x_i{1\over k[i]} xi?k[i]1?個…

從代碼學習深度學習 - LSTM PyTorch版

文章目錄 前言一、數據加載與預處理1.1 代碼實現1.2 功能解析二、LSTM介紹2.1 LSTM原理2.2 模型定義代碼解析三、訓練與預測3.1 訓練邏輯代碼解析3.2 可視化工具功能解析功能結果總結前言 深度學習中的循環神經網絡(RNN)及其變種長短期記憶網絡(LSTM)在處理序列數據(如文…

easy-poi 一對多導出

1. 需求: 某一列上下兩行單元格A,B值一樣且這兩個單元格, 前面所有列對應單元格值一樣的話, 就對A,B 兩個單元格進行縱向合并單元格 1. 核心思路: 先對數據集的國家,省份,城市...... id 身份證進行排序…

AI比人腦更強,因為被植入思維模型【42】思維投影思維模型

giszz的理解:本質和外在。我們的行為舉止,都是我們的內心的表現。從外邊可以看內心,從內心可以判斷外在。曾國藩有7個識人的方法,大部分的人在他的面前如同沒穿衣服一樣。對于我們自身的啟迪,我認為有四點&…

Spring Boot 打印日志

1.通過slf4j包中的logger對象打印日志 Spring Boot內置了日志框架slf4j,在程序中調用slf4j來輸出日志 通過創建logger對象打印日志,Logger 對象是屬于 org.slf4j 包下的不要導錯包。 2.日志級別 日志級別從高到低依次為: FATAL:致命信息,表…

【IOS webview】源代碼映射錯誤,頁面卡住不動

報錯場景 safari頁面報源代碼映射錯誤,頁面卡住不動。 機型:IOS13 技術棧:react 其他IOS也會報錯,但不影響頁面顯示。 debug webpack配置不要GENERATE_SOURCEMAP。 解決方法: GENERATE_SOURCEMAPfalse react-app…

ES中經緯度查詢geo_point

0. ES版本 6.x版本 1. 創建索引 PUT /location {"settings": {"number_of_shards": 1,"number_of_replicas": 0},"mappings": {"location": {"properties": {"id": {"type": "keywor…

OpenCV界面編程

《OpenCV計算機視覺開發實踐:基于Python(人工智能技術叢書)》(朱文偉,李建英)【摘要 書評 試讀】- 京東圖書 OpenCV的Python開發環境搭建(Windows)-CSDN博客 OpenCV也支持有限的界面編程,主要是針對窗口、控件和鼠標…

GOC L2 第五課模運算和周期二

課堂回顧: 求取余數的過程叫做模運算 每輪的動作都是重復的,我們稱這個過程位周期。 課堂學習: 剩余計算器 秋天到了,學校里的蘋果熟了,太乙老師,想讓哪吒幫忙設計一個計算器,看每個小朋友能分…

54.大學生心理健康管理系統(基于springboot項目)

目錄 1.系統的受眾說明 2.相關技術 2.1 B/S結構 2.2 MySQL數據庫 3.系統分析 3.1可行性分析 3.1.1時間可行性 3.1.2 經濟可行性 3.1.3 操作可行性 3.1.4 技術可行性 3.1.5 法律可行性 3.2系統流程分析 3.3系統功能需求分析 3.4 系統非功能需求分析 4.系統設計…

Redis 除了數據類型外的核心功能 的詳細說明,包含事務、流水線、發布/訂閱、Lua 腳本的完整代碼示例和表格總結

以下是 Redis 除了數據類型外的核心功能 的詳細說明,包含事務、流水線、發布/訂閱、Lua 腳本的完整代碼示例和表格總結: 1. Redis 事務(Transactions) 功能描述 事務通過 MULTI 和 EXEC 命令將一組命令打包執行,保證…

STM32F103C8T6單片機硬核原理篇:討論GPIO的基本原理篇章1——只討論我們的GPIO簡單輸入和輸出

目錄 前言 輸出時的GPIO控制部分 標準庫是如何操作寄存器完成GPIO驅動的初始化的? 問題1:如何掌握GPIO的編程細節——跟寄存器如何打交道 問題2:哪些寄存器,去哪里找呢? 問題三,寄存器的含義&#xff…

前端布局難題:父元素padding導致子元素無法全屏?3種解決方案

大家好,我是一諾。今天要跟大家分享一個我在實際項目中經常用到的CSS技巧——如何讓子元素突破父元素的padding限制,實現真正的全屏寬度效果。 為什么會有這個需求? 記得我剛入行的時候,接到一個需求:要在內容區插入…

當網頁受到DDOS網絡攻擊有哪些應對方法?

分布式拒絕服務攻擊也是人們較為熟悉的DDOS攻擊,這類攻擊會通過大量受控制的僵尸網絡向目標服務器發送請求,以此來消耗服務器中的資源,致使用戶無法正常訪問,當網頁受到分布式拒絕服務攻擊時都有哪些應對方法呢? 建立全…

LeNet-5簡介及matlab實現

文章目錄 一、LeNet-5網絡結構簡介二、LeNet-5每一層的實現原理2.1. 第一層 (C1) :卷積層(Convolution Layer)2.2. 第二層 (S2) :池化層(Pooling Layer)2.3. 第三層(C3):…

【LLM】MCP(Python):實現 stdio 通信的Client與Server

本文將詳細介紹如何使用 Model Context Protocol (MCP) 在 Python 中實現基于 STDIO 通信的 Client 與 Server。MCP 是一個開放協議,它使 LLM 應用與外部數據源和工具之間的無縫集成成為可能。無論你是構建 AI 驅動的 IDE、改善 chat 交互,還是構建自定義…

Docker 安裝 Elasticsearch 教程

目錄 一、安裝 Elasticsearch 二、安裝 Kibana 三、安裝 IK 分詞器 四、Elasticsearch 常用配置 五、Elasticsearch 常用命令 一、安裝 Elasticsearch (一)創建 Docker 網絡 因為后續還需要部署 Kibana 容器,所以需要讓 Elasticsearch…

Swagger @ApiOperation

ApiOperation 注解并非 Spring Boot 自帶的注解,而是來自 Swagger 框架,Swagger 是一個規范且完整的框架,用于生成、描述、調用和可視化 RESTful 風格的 Web 服務,而 ApiOperation 主要用于為 API 接口的操作添加描述信息。以下為…

【奇點時刻】GPT4o新圖像生成模型底層原理深度洞察報告(篇2)

由于上一篇解析深度不足,經過查看學習相關論文,以下是一份對 GPT-4o 最新的圖像生成模型 的深度梳理與洞察,從模型原理到社區解讀、對比傳統擴散模型,再到對未來趨勢的分析。為了便于閱讀,整理成以下七個部分&#xff…

C# 窗體應用(.FET Framework ) 打開文件操作

一、 打開文件或文件夾加載數據 1. 定義一個列表用來接收路徑 public List<string> paths new List<string>();2. 打開文件選擇一個文件并將文件放入列表中 OpenFileDialog open new OpenFileDialog(); // 過濾 open.Filter "(*.jpg;*.jpge;*.bmp;*.png…