Redis閒談(1):構建知識圖譜
場景:Redis面試
(圖片來源於網路)
面試官 : 我看到你的簡歷上說你熟練使用Redis,那麼你講一下Redis是幹嘛用的?
小明 : (心中竊喜,Redis不就是快取嗎?)redis主要用作快取,透過記憶體高效地儲存非持久化資料。
面試官 : Redis可以用作持久化的儲存嗎?
小明 :嗯...應該可以吧...
面試官 : 那Redis怎麼進行持久化操作呢?
小明 :嗯...不是太清楚。
面試官 : Redis的記憶體淘汰機制有哪些?
小明 :嗯...沒了解過
面試官 :我們還可以用Redis做哪些事情?分別利用了Redis的哪個指令?
小明 :我只知道Redis還可以做分散式鎖、訊息佇列...
面試官 :好了,我們進入下一個話題...
思考 :很明顯,小明同學在面試過程中關於Redis的表現和回答肯定是比較失敗的。Redis是我們工作中每天都會使用到的東西,為什麼一到面試卻變成了丟分項呢?
作為開發者,我們習慣了使用大神們已經封裝好的東西,以此保障我們能夠更專注於業務開發,卻不知道這些常用工具的底層實現是什麼,因此儘管平時應用起來得心應手,但一到面試還是無法讓面試官眼前一亮。
本文總結了一些Redis的知識點,有原理有應用,希望可以幫助到大家。
Redis是什麼
REmote DIctionary Server(Redis) 是一個由Salvatore Sanfilippo寫的key-value儲存系統。
Redis是一個開源的使用ANSI 、C語言編寫、遵守BSD協議、支援網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。
這裡我引用了Redis教程裡對Redis的描述,很官方,但是很標準。 可基於記憶體亦可持久化的日誌型、Key-Value資料庫。 我認為這個描述很貼切很全面。
Redis的行業地位
Redis是網際網路技術領域使用最為廣泛的儲存中介軟體,因超高的效能、完美的文件、多方面的應用能力以及豐富完善的客戶端支援在儲存方面獨當一面,廣受好評,尤其以其效能和讀取速度而成為了領域中最受青睞的中介軟體。基本上每一個軟體公司都會使用redis,其中包括很多大型網際網路公司,比如京東、阿里、騰訊、github等。因此,Redis也成為了後端開發人員必不可少的技能。
知識圖譜
在我看來,學習每一項技術,都需要有一個清晰的脈絡和結構,不然你也不知道自己會了哪些、還有多少沒學會。就像一本書,如果沒有目錄章節,也就失去了靈魂。
因此我試圖總結出Redis的知識圖譜,也稱為腦圖,如下圖所示,可能知識點不是很全,後續會不斷更新補充。
本系列文章的知識點也會和這個腦圖基本一致,本文先介紹Redis的基本知識,後續文章會詳細介紹Redis的資料結構、應用、持久化等多個方面。
Redis優點
速度快:
作為快取工具,Redis最廣為人知的特點就是快,到底有多快呢?Redis單機qps(每秒的併發)可以達到110000次/s,寫的速度是81000次/s。 那麼,Redis為什麼這麼快呢?
-
絕大部分請求是純粹的記憶體操作,非常快速;
-
使用了很多查詢操作都特別快的資料結構進行資料儲存,Redis中的資料結構是專門設計的。如HashMap,查詢、插入的時間複雜度都是O(1);
-
採用單執行緒,避免了不必要的上下文切換和競爭條件,也不存在多程式或者多執行緒導致的切換而消耗CPU,不用去考慮各種鎖的問題,不存在加鎖、釋放鎖操作,沒有因為可能出現死鎖而導致的效能消耗;
-
用到了非阻塞I/O多路複用機制。
豐富的資料型別
Redis有5種常用的資料型別:String、List、Hash、set、zset,每種資料型別都有自己的用處。
原子性,支援事務
Redis支援事務,並且它的所有操作都是原子性的,同時Redis還支援對幾個操作合併後的原子性執行。
豐富的特性
Redis具有豐富的特性,比如可以用作分散式鎖;可以持久化資料;可以用作訊息佇列、排行榜、計數器;還支援publish/subscribe、通知、key過期等等。當我們要用中介軟體來解決實際問題的時候,Redis總能發揮出自己的用處。
Redis和Memcache對比
Memcache和Redis都是優秀的、高效能的記憶體資料庫,一般我們說到Redis的時候,都會拿Memcache來和Redis做對比。(為什麼要做對比呢?當然是要襯托出Redis有多好,沒有對比,就沒有傷害~)對比的方面包括:
1) 儲存方式
-
Memcache把資料全部存在記憶體之中,斷電後會掛掉,無法做到資料的持久化,且資料不能超過記憶體大小。
-
Redis有一部分資料存在硬碟上,可以做到資料的永續性。
2) 資料支援型別
-
Memcache對資料型別支援相對簡單,只支援String型別的資料結構。
-
Redis有豐富的資料型別,包括:String、List、Hash、Set、Zset。
3) 使用的底層模型
-
它們之間底層實現方式以及與客戶端之間通訊的應用協議不一樣。
-
Redis直接自己構建了VM機制 ,因為一般的系統呼叫系統函式,會浪費一定的時間去移動和請求。
4) 儲存值大小
-
Redis最大可以儲存1GB,而memcache只有1MB。
看到這裡,會不會覺得Redis特別好,全是優點,完美無缺?其實Redis還是有很多缺點的,這些缺點平常我們該如何克服呢?
Redis存在的問題及解決方案
1. 快取資料庫的雙寫一致性的問題
問題 :一致性的問題是分散式系統中很常見的問題。一致性一般分為兩種:強一致性和最終一致性,當我們要滿足強一致性的時候,Redis也無法做到完美無瑕,因為資料庫和快取雙寫,肯定會出現不一致的情況,Redis只能保證最終一致性。
解決 :我們如何保證最終一致性呢?
-
第一種方式是給快取設定一定的過期時間,在快取過期之後會自動查詢資料庫,保證資料庫和快取的一致性。
-
如果不設定過期時間的話,我們首先要選取正確的更新策略:先更新資料庫再刪除快取。但我們刪除快取的時候也可能出現某些問題,所以需要將要刪除的快取的key放到訊息佇列中去,不斷重試,直到刪除成功為止。
2. 快取雪崩問題
問題: 我們應該都在電影裡看到過雪崩,開始很平靜,然後一瞬間就開始崩塌,具有很強的毀滅性。這裡也是一樣的,我們執行程式碼的時候將很多快取的實效時間設定成一樣,接著這些快取在同一時間都會實效,然後都會重新訪問資料庫更新資料,這樣會導致資料庫連線數過多、壓力過大而崩潰。
解決:
-
設定快取過期時間的時候加一個隨機值。
-
設定雙快取,快取1設定快取時間,快取2不設定,1過期後直接返回快取2,並且啟動一個程式去更新快取1和2。
3. 快取穿透問題
問題: 快取穿透是指一些非正常使用者(駭客)故意去請求快取中不存在的資料,導致所有的請求都集中到到資料庫上,從而導致資料庫連線異常。
解決:
-
利用互斥鎖。快取失效的時候,不能直接訪問資料庫,而是要先獲取到鎖,才能去請求資料庫。沒得到鎖,則休眠一段時間後重試。
-
採用非同步更新策略。無論key是否取到值,都直接返回。value值中維護一個快取失效時間,快取如果過期,非同步起一個執行緒去讀資料庫,更新快取。需要做快取預熱(專案啟動前,先載入快取)操作。
-
提供一個能迅速判斷請求是否有效的攔截機制。比如利用布隆過濾器,內部維護一系列合法有效的key,迅速判斷出請求所攜帶的Key是否合法有效。如果不合法,則直接返回。
4. 快取的併發競爭問題
問題:
快取併發競爭的問題,主要發生在多執行緒對某個key進行set的時候,這時會出現資料不一致的情況。
比如Redis中我們存著一個key為amount的值,它的value是100,兩個執行緒同時都對value加100然後更新,正確的結果應該是變為300。但是兩個執行緒拿到這個值的時候都是100,最後結果也就是200,這就導致了快取的併發競爭問題。
解決
-
如果多執行緒操作沒有順序要求的話,我們可以設定一個分散式鎖,然後多個執行緒去爭奪鎖,誰先搶到鎖誰就可以先執行。這個分散式鎖可以用zookeeper或者Redis本身去實現。
-
可以利用Redis的incr命令。
-
當我們的多執行緒操作需要順序的時候,我們可以設定一個訊息佇列,把需要的操作加到訊息佇列中去,嚴格按照佇列的先後執行命令。
Redis的過期策略
Redis隨著資料的增多,記憶體佔用率會持續變高,我們以為一些鍵到達設定的刪除時間就會被刪除,但是時間到了,記憶體的佔用率還是很高,這是為什麼呢?
Redis採用的是 定期刪除 和 惰性刪除 的記憶體淘汰機制。
定期刪除
定期刪除和定時刪除是有區別的:
-
定時刪除是必須嚴格按照設定的時間去刪除快取,這就需要我們設定一個定時器去不斷地輪詢所有的key,判斷是否需要進行刪除。但是這樣的話cpu的資源會被大幅度地佔據,資源的利用率變低。所以我們選擇採用定期刪除,。
-
定期刪除是時間由我們定,我們可以每隔100ms進行檢查,但還是不能檢查所有的快取,redis還是會卡死,只能隨機地去檢查一部分快取,但是這樣會有一些快取無法在規定時間內刪除。這時惰性刪除就派上用場了。
惰性刪除
舉個簡單的例子:中學的時候,平時作業太多,根本做不完,老師說下節課要講這個卷子,你們都做完了吧?其實有很多人沒做完,所以需要在下節課之前趕緊補上。
惰性刪除也是這個道理,我們的這個值按理說應該沒了,但是它還在,當你要獲取這個key的時候,發現這個key應該過期了,趕緊刪了,然後返回一個'沒有這個值,已經過期了!'。
現在我們有了定期刪除 + 惰性刪除的過期策略,就可以高枕無憂了嗎?並不是這樣的,如果這個key一直不訪問,那麼它會一直滯留,也是不合理的,這就需要我們的記憶體淘汰機制了。
Redis的記憶體淘汰機制
Redis的記憶體淘汰機制一般有6種,如下圖所示:
那麼我們如何去配置Redis的記憶體淘汰機制呢?
在redis.conf中我們可以進行配置
# maxmemory-policy allkeys-lru
小結
本文初探Redis,大概整理出了Redis的知識圖譜,對照之下可以發現Redis居然有這麼多的知識點需要學習;接著我們分析了Redis的優缺點,知道了其基於記憶體的高效的讀寫速度和豐富的資料型別,也分析了Redis面對資料一致性、快取穿透、快取雪崩等問題時該如何處理;最後我們瞭解了Redis的過期策略和快取淘汰機制。
相信大家已經對Redis有了一些瞭解,下篇文章我們將分析Redis的資料結構、每一種資料型別是如何實現的、對應的命令有哪些。
希望大家多多支援,有不正確的地方歡迎大家指出。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69918724/viewspace-2643043/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 構建知識圖譜-初學
- 【知識圖譜】 一個有效的知識圖譜是如何構建的?
- 知識圖譜構建與應用
- 實驗案例1構建簡單的金融知識圖譜
- 使用ChatGPT自動構建知識圖譜ChatGPT
- 構建知識圖譜的八個好處
- 專案實戰:如何構建知識圖譜
- 【知識圖譜】知識圖譜資料構建的“硬骨頭”,阿里工程師如何拿下?深度學習在知識圖譜構建中的應用。阿里工程師深度學習
- 知識圖譜構建之實體關係挖掘
- 知識圖譜Knowledge Graph構建與應用
- 安全知識圖譜|構建APT組織圖譜,打破資訊孤島效應APT
- 知識圖譜|知識圖譜的典型應用
- 知識圖譜01:知識圖譜的定義
- NLPIR系統自動構建公共安全知識圖譜
- 知識圖譜構建與應用推薦學習分享
- 知識圖譜學習記錄--知識圖譜概述
- 為知識的海洋繪製地圖 —— 利用CirroData-Graph圖資料庫構建知識圖譜地圖資料庫
- 從 0 開始構建知識圖譜的 5 個啟動建議
- 知識圖譜之知識表示
- NLPIR系統構建知識圖譜助力智慧客服應用
- 基於 Nebula Graph 構建百億關係知識圖譜實踐
- 華為雲專家講述知識圖譜構建流程及方法
- go 知識圖譜Go
- OI知識圖譜
- 大資料架構師知識圖譜大資料架構
- NLPIR系統自動構建知識圖譜核查招標檔案
- 用.Net實現GraphRag:從零開始構建智慧知識圖譜
- [知識圖譜構建] 一.Neo4j圖資料庫安裝初識及藥材供應圖譜例項資料庫
- 知識圖譜學習
- Http/2知識圖譜HTTP
- 開源知識圖譜
- 知識圖譜應用
- 知識圖譜實戰開發案例剖析(1)
- 如何用NLP與知識圖譜支援MarTech建設?
- NLPIR系統自動構建企業上市大資料知識圖譜大資料
- 阿里數字商業知識圖譜構建及開放(附下載)阿里
- 知識圖譜技術的新成果—KGB知識圖譜介紹
- 知識圖譜入門——知識表示與知識建模