Redis4

Redis除了緩存,還有哪些應用?

Redis實現消息隊列

**使用Pub/Sub模式:**Redis的Pub/Sub是一種基于發布/訂閱的消息模式,任何客戶端都可以訂閱一個或多個頻道,發布者可以向特定頻道發送消息,所有訂閱該頻道的客戶端都會收到此消息。該方式實現起來比較簡單,發布者和訂閱者完全解耦,支持模式匹配訂閱。但是這種方式不支持消息持久化,消息發布后若無訂閱者在線則會被丟棄;不保證消息的順序和可靠性傳輸。

使用List結構:使用List的方式通常是使用LPUSH命令將消息推入一個列表,消費者使用BLPOP或BRPOP阻塞地從列表中取出消息(先進先出FIFO)。這種方式可以實現簡單的任務隊列。這種方式可以結合Redis的過期時間特性實現消息的TTL;通過Redis事務可以保證操作的原子性。但是需要客戶端自己實現消息確認、重試等機制,相比專門的消息隊列系統功能較弱。

Redis實現分布式鎖

set nx方式:Redis提供了幾種方式來實現分布式鎖,最常用的是基于SET命令的爭搶鎖機制。客戶端可以使用SET resource_name lock_value NX PX milliseconds命令設置鎖,其中NX表示只有當鍵不存在時才設置,PX指定鎖的有效時間(毫秒)。如果設置成功,則認為客戶端獲得鎖。客戶端完成操作后,解鎖的還需要先判斷鎖是不是自己,再進行刪除,這里涉及到 2 個操作,為了保證這兩個操作的原子性,可以用 lua 腳本來實現

**RedLock算法:**為了提高分布式鎖的可靠性,Redis作者Antirez提出了RedLock算法,它基于多個獨立的Redis實例來實現一個更安全的分布式鎖。它的基本原理是客戶端嘗試在多數(大于半數)Redis實例上同時加鎖,只有當在大多數實例上加鎖成功時才認為獲取鎖成功。鎖的超時時間應該遠小于單個實例的超時時間,以避免死鎖。該方式可以通過跨多個節點減少單點故障的影響,提高了鎖的可用性和安全性。

Redis支持并發操作嗎?

單個 Redis 命令的原子性:Redis 的單個命令是原子性的,這意味著一個命令要么完全執行成功,要么完全不執行,確保操作的一致性。這對于并發操作非常重要。但是一系列操作命令不是原子的

多個操作的事務:Redis 支持事務,可以將一系列的操作放在一個事務中執行,使用 MULTI、EXEC、DISCARD 和 WATCH 等命令來管理事務。這樣可以確保一系列操作的原子性。

Redis分布式鎖的實現原理?什么場景下用到分布式鎖?

分布式鎖是用于分布式環境下并發控制的一種機制,用于控制某個資源在同一時刻只能被一個應用所使用。如下圖所示:Redis 本身可以被多個客戶端共享訪問,正好就是一個共享存儲系統,可以用來保存分布式鎖,而且 Redis 的讀寫性能高,可以應對高并發的鎖操作場景。Redis 的 SET 命令有個 NX 參數可以實現「key不存在才插入」,所以可以用它來實現分布式鎖:

如果 key 不存在,則顯示插入成功,可以用來表示加鎖成功;

如果 key 存在,則會顯示插入失敗,可以用來表示加鎖失敗。

基于 Redis 節點實現分布式鎖時,對于加鎖操作,我們需要滿足三個條件。

加鎖包括了讀取鎖變量、檢查鎖變量值和設置鎖變量值三個操作,但需要以原子操作的方式完成,所以,我們使用 SET 命令帶上 NX 選項來實現加鎖;

鎖變量需要設置過期時間,以免客戶端拿到鎖后發生異常,導致鎖一直無法釋放,所以,我們在 SET 命令執行時加上 EX/PX 選項,設置其過期時間;

鎖變量的值需要能區分來自不同客戶端的加鎖操作,以免在釋放鎖時,出現誤釋放操作,所以,我們使用 SET 命令設置鎖變量值時,每個客戶端設置的值是一個唯一值,用于標識客戶端;

滿足這三個條件的分布式命令如下:

SET lock_key unique_value NX PX 10000

lock_key 就是 key 鍵;

unique_value 是客戶端生成的唯一的標識,區分來自不同客戶端的鎖操作;

NX 代表只在 lock_key 不存在時,才對 lock_key 進行設置操作;

PX 10000 表示設置 lock_key 的過期時間為 10s,這是為了避免客戶端發生異常而無法釋放鎖。

而解鎖的過程就是將 lock_key 鍵刪除(del lock_key),但不能亂刪,要保證執行操作的客戶端就是加鎖的客戶端。所以,解鎖的時候,我們要先判斷鎖的 unique_value 是否為加鎖客戶端,是的話,才將 lock_key 鍵刪除。

可以看到,解鎖是有兩個操作,這時就需要 Lua 腳本來保證解鎖的原子性,因為 Redis 在執行 Lua 腳本時,可以以原子性的方式執行,保證了鎖釋放操作的原子性。

// 釋放鎖時,先比較 unique_value 是否相等,避免鎖的誤釋放

if redis.call("get",KEYS[1]) == ARGV[1] then

??return redis.call("del",KEYS[1])

else

??return 0

end

這樣一來,就通過使用 SET 命令和 Lua 腳本在 Redis 單節點上完成了分布式鎖的加鎖和解鎖。

Redis的大Key問題是什么?

Redis大key問題指的是某個key對應的value值所占的內存空間比較大,導致Redis的性能下降、內存不足、數據不均衡以及主從同步延遲等問題

到底多大的數據量才算是大key?

沒有固定的判別標準,通常認為字符串類型的key對應的value值占用空間大于1M,或者集合類型的k元素數量超過1萬個,就算是大key

Redis大key問題的定義及評判準則并非一成不變,而應根據Redis的實際運用以及業務需求來綜合評估。

例如,在高并發且低延遲的場景中,僅10kb可能就已構成大key;然而在低并發、高容量的環境下,大key的界限可能在100kb。因此,在設計與運用Redis時,要依據業務需求與性能指標來確立合理的大key閾值。

大Key問題的缺點?

內存占用過高。大Key占用過多的內存空間,可能導致可用內存不足,從而觸發內存淘汰策略。在極端情況下,可能導致內存耗盡,Redis實例崩潰,影響系統的穩定性。

性能下降。大Key會占用大量內存空間,導致內存碎片增加,進而影響Redis的性能。對于大Key的操作,如讀取、寫入、刪除等,都會消耗更多的CPU時間和內存資源,進一步降低系統性能。

阻塞其他操作。某些對大Key的操作可能會導致Redis實例阻塞。例如,使用DEL命令刪除一個大Key時,可能會導致Redis實例在一段時間內無法響應其他客戶端請求,從而影響系統的響應時間和吞吐量。

網絡擁塞。每次獲取大key產生的網絡流量較大,可能造成機器或局域網的帶寬被打滿,同時波及其他服務。

例如:一個大key占用空間是1MB,每秒訪問1000次,就有1000MB的流量。

主從同步延遲。當Redis實例配置了主從同步時,大Key可能導致主從同步延遲。由于大Key占用較多內存,同步過程中需要傳輸大量數據,這會導致主從之間的網絡傳輸延遲增加,進而影響數據一致性。

數據傾斜。在Redis集群模式中,某個數據分片的內存使用率遠超其他數據分片,無法使數據分片的內存資源達到均衡。另外也可能造成Redis內存達到maxmemory參數定義的上限導致重要的key被逐出,甚至引發內存溢出。

Redis大key如何解決?

對大Key進行拆分。例如將含有數萬成員的一個HASH Key拆分為多個HASH Key,并確保每個Key的成員數量在合理范圍。在Redis集群架構中,拆分大Key能對數據分片間的內存平衡起到顯著作用。

對大Key進行清理。將不適用Redis能力的數據存至其它存儲,并在Redis中刪除此類數據。注意,要使用異步刪除。

監控Redis的內存水位。可以通過監控系統設置合理的Redis內存報警閾值進行提醒,例如Redis內存使用率超過70%、Redis的內存在1小時內增長率超過20%等。

對過期數據進行定期清。堆積大量過期數據會造成大Key的產生,例如在HASH數據類型中以增量的形式不斷寫入大量數據而忽略了數據的時效性。可以通過定時任務的方式對失效數據進行清理。

什么是熱key?

通常以其接收到的Key被請求頻率來判定,例如:

QPS集中在特定的Key:Redis實例的總QPS(每秒查詢率)為10,000,而其中一個Key的每秒訪問量達到了7,000。

帶寬使用率集中在特定的Key:對一個擁有上千個成員且總大小為1 MB的HASH Key每秒發送大量的HGETALL操作請求。

CPU使用時間占比集中在特定的Key:對一個擁有數萬個成員的Key(ZSET類型)每秒發送大量的ZRANGE操作請求。

如何解決熱key問題?

在Redis集群架構中對熱Key進行復制。在Redis集群架構中,由于熱Key的遷移粒度問題,無法將請求分散至其他數據分片,導致單個數據分片的壓力無法下降。此時,可以將對應熱Key進行復制并遷移至其他數據分片,例如將熱Key foo復制出3個內容完全一樣的Key并名為foo2、foo3、foo4,將這三個Key遷移到其他數據分片來解決單個數據分片的熱Key壓力。

使用讀寫分離架構如果熱Key的產生來自于讀請求,您可以將實例改造成讀寫分離架構來降低每個數據分片的讀請求壓力,甚至可以不斷地增加從節點。但是讀寫分離架構在增加業務代碼復雜度的同時,也會增加Redis集群架構復雜度。不僅要為多個從節點提供轉發層(如Proxy,LVS等)來實現負載均衡,還要考慮從節點數量顯著增加后帶來故障率增加的問題。Redis集群架構變更會為監控、運維、故障處理帶來了更大的挑戰。

如何保證 redis 和 mysql 數據緩存一致性問題?

更新緩存還是刪除緩存:

下面,我們來分析一下,應該采用更新緩存還是刪除緩存的方式。

更新緩存

優點:每次數據變化都及時更新緩存,所以查詢時不容易出現未命中的情況。

缺點:更新緩存的消耗比較大。如果數據需要經過復雜的計算再寫入緩存,那么頻繁的更新緩存,

就會影響服務器的性能。如果是寫入數據頻繁的業務場景,那么可能頻繁的更新緩存時,卻沒有業

務讀取該數據。

刪除緩存

優點:操作簡單,無論更新操作是否復雜,都是將緩存中的數據直接刪除。?

缺點:刪除緩存后,下一次查詢緩存會出現未命中,這時需要重新讀取一次數據庫。

從上面的比較來看,一般情況下,刪除緩存是更優的方案

如果先操作緩存

什么時候會出現數據緩存不一致的情況?線程1想要修改數據,那它先把redis里的舊數據刪除,然后再去數據庫里去修改數據,這樣的話下次查詢數據的時候,redis里不存在就會去數據庫里查找,數據庫里找到后就會更新一份最新的數據給redis里,這樣redis和mysql數據就一致了,但是假如在數據庫正要修改數據的時候網絡突然阻塞了,這樣的話線程2去讀數據,讀到一個過時的未修改的舊數據,然后數據庫修改成新數據,這樣的話redis和數據庫數據就不一致了。

緩存是通過犧牲強一致性來提高性能的。這是由CAP理論決定的。緩存系統適用的場景就是非強一致性的場景,它屬于CAP中的AP。所以,如果需要數據庫和緩存數據保持強一致,就不適合使用緩存(因為保證了強一致性,那么性能就沒法保證了,那么用緩存的意義也不大了,因為我們用緩存本身就是要提高性能)

所以說我們只能保證最終一致性(也就是最終結果是一樣的),不能保證強一致性

解決策略:延遲雙刪

1. 刪除緩存;

2. 更新數據庫;

3. sleep N毫秒; (延遲是為了讓redis讀取到舊的數據)

4. 再次刪除緩存。

如果先操作數據庫

??也無法避免數據緩存不一致的情況

對于讀數據,我會選擇旁路緩存策略,如果 cache 不命中,會從 db 加載數據到 cache。對于寫數據,我會選擇更新 db 后,再刪除緩存。

所以使用緩存提升性能,就是會有數據更新的延遲。這需要我們在設計時結合業務仔細思考是否適合用緩存。然后緩存一定要設置過期時間,這個時間太短、或者太長都不好:

太短的話請求可能會比較多的落到數據庫上,這也意味著失去了緩存的優勢。

太長的話緩存中的臟數據會使系統長時間處于一個延遲的狀態,而且系統中長時間沒有人訪問的數據一直存在內存中不過期,浪費內存。

但是,通過一些方案優化處理,是可以最終一致性的。

針對刪除緩存異常的情況,可以使用 2 個方案避免:

刪除緩存重試策略(消息隊列)

訂閱 binlog,再刪除緩存(Canal+消息隊列)

消息隊列方案

我們可以引入消息隊列,將第二個操作(刪除緩存)要操作的數據加入到消息隊列,由消費者來操作數據。

如果應用刪除緩存失敗,可以從消息隊列中重新讀取數據,然后再次刪除緩存,這個就是重試機制。當然,如果重試超過的一定次數,還是沒有成功,我們就需要向業務層發送報錯信息了。

如果刪除緩存成功,就要把數據從消息隊列中移除,避免重復操作,否則就繼續重試。

訂閱 MySQL binlog,再操作緩存

「先更新數據庫,再刪緩存」的策略的第一步是更新數據庫,那么更新數據庫成功,就會產生一條變更日志,記錄在 binlog 里。

于是我們就可以通過訂閱 binlog 日志,拿到具體要操作的數據,然后再執行緩存刪除,阿里巴巴開源的 Canal 中間件就是基于這個實現的。

Canal 模擬 MySQL 主從復制的交互協議,把自己偽裝成一個 MySQL 的從節點,向 MySQL 主節點發送 dump 請求,MySQL 收到請求后,就會開始推送 Binlog 給 Canal,Canal 解析 Binlog 字節流之后,轉換為便于讀取的結構化數據,供下游程序訂閱使用。

下圖是 Canal 的工作原理:

binlog日志采集發送到MQ隊列里面,然后編寫一個簡單的緩存刪除消息者訂閱binlog日志,更新log刪除緩存,并且通過ACK機制確認處理這條更新log,保證數據緩存一致性

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

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

相關文章

LEFE-Net:一種軸承故障診斷的輕量化高效特征提取網絡

一、研究背景與挑戰 軸承作為旋轉機械的核心部件,其健康狀態直接影響設備運行的安全性和可靠性。傳統的故障診斷方法(如振動分析、油液檢測)依賴人工經驗,效率低且易受主觀因素影響。近年來,基于深度學習的數據驅動方…

springboot+Apache POI 寫共導入導出

SpringBoot Apache POI 實現數據導入導出 功能特點: 智能列匹配: 支持精確列名匹配 支持忽略大小寫的列名匹配 自動匹配字段名(當未指定ExcelProperty時) 強大的類型轉換: 支持基本數據類型(Integer/Lon…

Games101 Lecture3,Lecture4

旋轉矩陣邏輯推導 齊次坐標,解決平移的特殊情況 引入一個維度(無物理意義?),輔助表達平移,為零時,表示向量,不為零時,表示點(/w) 三維旋轉矩陣 相…

折線圖多數據處理

前言: skline1有年份和新申請單位數,skline2有年份和有效期內單位數,我想要把1和2的年份放在一起從小到大放,沒有重復的,新申請單位數和有效期內單位數和年份的排列順序一致 實現: // 獲取原始數據 List…

documents4j導出pdf

一、前言 上一篇我們介紹了導出word,既然有了導出word,那么到處pdf也將會出現,導出word和pdf基本上是配套的需求,跑不了,那么本次我就簡單介紹一下導出pdf。 二、代碼實現 2.1、依賴引入 導出pdf是基于documents4j實現…

從零到一體驗 Qwen-TTS:用四川話合成語音的全流程技術實錄

今天很高興看到Qwen-TTS開源。試一試四川方言(大概是成都版)效果如何。本人無法判斷、有興趣的伙伴可以幫忙聽一聽。 四川方言TTS "胖娃胖嘟嘟,騎馬上成都,成都又好耍。胖娃騎白馬,白馬跳得高。胖娃耍關刀&…

php數據導出pdf文件

一.導出pdf文件,首先要安裝相關的類庫文件,我用的是dompdf類庫。 1.安裝類庫文件: composer require dompdf/dompdf 2.引入類庫文件到你的控制器中,創建方法: public function generatePdf(){//你需要打印的查詢內容…

Beam2.61.0版本消費kafka重復問題排查

1.問題出現過程 在測試環境測試flink的job的任務消費kafka的情況,通過往job任務發送一條消息,然后flink web ui上消費出現了兩條。然后通過重啟JobManager和TaskManager后,任務從checkpoint恢復后就會出現重復消費。當任務不從checkpoint恢復…

關于 java:9. Java 網絡編程

一、Socket 編程 Socket(套接字)是網絡通信的端點,是對 TCP/IP 協議的編程抽象,用于實現兩臺主機間的數據交換。 通俗來說: 可以把 Socket 理解為“電話插口”,插上后客戶端和服務端才能“通話”。 Sock…

主流零信任安全產品深度介紹

騰訊 iOA 零信任安全管理系統 功能:提供零信任接入、終端安全、數據防泄密等十余種功能模塊。可實現基于身份的動態訪問控制、終端安全一體化防護、數據防泄密體系等。核心優勢:基于騰訊內部千萬級終端實踐打磨,沉淀豐富場景方案&#xff0c…

LabVIEW裝配車體撓度無線測量

針對軌道交通車輛裝配過程中車體撓度測量需求,基于LabVIEW開發無線快速測量系統,采用品牌硬件構建高精度數據采集與傳輸架構。系統通過 ZigBee 無線傳輸技術、高精度模數轉換模塊及激光位移傳感器,實現裝配車體撓度的實時、自動、非接觸測量&…

java微服務-linux單機CPU接近100%優化

你這個場景: 4核16G 機器 同時運行了 8個 Spring Boot 微服務,每個 JAR 文件 100多 MB 導致 CPU 接近100% 確實是一個常見但資源緊繃的部署情境。下面是分層的優化建議,包括 JVM、系統、服務架構等多個方面,幫助你 降 CPU、穩…

MySQL表的約束和基本查詢

一.表的約束 1.1空屬性 當我們填寫問卷的時候,經常會有不允許為空的問題,比如電話號,姓名等等.而mysql上我們可以在創建表的時候,如果想要某一列不允許為空,可以加上not null來加以限制: mysql> create table myclass( -> class_name varchar(20) not null, -> cla…

VBA代碼解決方案第二十六講:如何新建EXCEL工作簿文件

《VBA代碼解決方案》(版權10028096)這套教程是我最早推出的教程,目前已經是第三版修訂了。這套教程定位于入門后的提高,在學習這套教程過程中,側重點是要理解及掌握我的“積木編程”思想。要靈活運用教程中的實例像搭積木一樣把自己喜歡的代碼…

【unity游戲開發——網絡】套接字Socket的重要API

注意:考慮到熱更新的內容比較多,我將熱更新的內容分開,并全部整合放在【unity游戲開發——網絡】專欄里,感興趣的小伙伴可以前往逐一查看學習。 文章目錄 1、Socket套接字的作用2、Socket類型與創建3、核心屬性速查表4、關鍵方法指…

計算機網絡(二)應用層HTTP協議

目錄 1、HTTP概念 ?編輯2、工作流程?? 3、HTTP vs HTTPS?? 4、HTTP請求特征總結? 5、持久性和非持久性連接 非持久連接(HTTP/1.0)?? ??持久連接(HTTP/1.1)?? 1、HTTP概念 HTTP(HyperText Transfer …

c# IO密集型與CPU密集型任務詳解,以及在異步編程中的使用示例

文章目錄 IO密集型與CPU密集型任務詳解(C#示例)一、基本概念1. IO密集型任務2. CPU密集型任務 二、C#示例1. IO密集型示例1.1 文件操作異步示例1.2 網絡請求異步示例1.3 數據庫操作異步示例 2. CPU密集型示例2.1 基本CPU密集型異步處理2.2 并行處理CPU密…

用lines_gauss的width屬性提取缺陷

自己做了一個圖,這個圖放在資源里了 結果圖是這樣(這里只結算了窄區) 代碼和備注如下 read_image (Image11, C:/Users/Administrator/Desktop/分享/15/11.png) rgb1_to_gray (Image11, GrayImage) invert_image (GrayImage, ImageInvert) thr…

從0到100:房產中介小程序開發筆記(中)

背景調研 為中介帶來諸多優勢,能借助它打造專屬小程序,方便及時更新核實租賃信息,確保信息準確無誤,像房屋的大致地址、租金數額、租賃條件、房源優缺點等關鍵信息都能清晰呈現。還可上傳房屋拍攝照片,這樣用戶能提前…

【AI 時代的網絡爬蟲新形態與防護思路研究】

網絡爬蟲原理與攻擊防護的深度研究報告 網絡爬蟲技術已進入AI驅動的4.0時代,全球自動化請求流量占比突破51%,傳統防御手段在面對高度仿真的AI爬蟲時已顯疲態。基于2025年最新數據,深入剖析網絡爬蟲的基本原理、工作流程、分類與攻擊方式&…