<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Redis緩存那點破事 | 絕殺面試官 25 問!

          共 5816字,需瀏覽 12分鐘

           ·

          2021-09-18 22:30

          為了便于大家查找問題,了解全貌,整理個目錄,我們可以快速全局了解關(guān)于Redis 緩存,面試官一般喜歡問哪些問題?



          接下來,我們逐條來看看每個問題及答案


          Redis 有哪些特性?

          答案:

          • 性能高, 讀的速度是100000次/s,寫的速度是80000次/s
          • 數(shù)據(jù)持久化,支持RDB 、AOF
          • 支持事務(wù)。通過MULTIEXEC指令包起來。
          • 多種數(shù)據(jù)結(jié)構(gòu)類型
          • 主從復(fù)制
          • 其他特性:發(fā)布/訂閱、通知、key過期等


          Redis 為什么這么快?

          答案:

          • 完全基于內(nèi)存,沒有磁盤IO上的開銷,異步持久化除外
          • 單線程,避免多個線程切換的性能損耗
          • 非阻塞的IO多路復(fù)用機(jī)制
          • 底層的數(shù)據(jù)存儲結(jié)構(gòu)優(yōu)化,使用原生的數(shù)據(jù)結(jié)構(gòu)提升性能。


          Redis 底層的基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)有哪些?

          答案:

          • 字符串。沒有采用C語言的傳統(tǒng)字符串,而是自己實現(xiàn)的一個簡單動態(tài)字符串SDS的抽象類型,并保存了長度信息。
          • 鏈表(linkedlist)。雙向無環(huán)鏈表結(jié)構(gòu),每個鏈表的節(jié)點由一個listNode結(jié)構(gòu)來表示,每個節(jié)點都有前置和后置節(jié)點的指針
          • 字典(hashtable)。保存鍵值對的抽象數(shù)據(jù)結(jié)構(gòu),底層使用hash表,每個字典帶有兩個hash表,供平時使用和rehash時使用。
          • 跳躍表(skiplist)。跳躍表是有序集合的底層實現(xiàn)之一。redis跳躍表由zskiplist和zskiplistNode組成,zskiplist用于保存跳躍表 信息(表頭、表尾節(jié)點、?度等),zskiplistNode用于表示表跳躍節(jié)點,每個跳躍表的層高都是1- 32的隨機(jī)數(shù),在同一個跳躍表中,多個節(jié)點可以包含相同的分值,但是每個節(jié)點的成員對象必須是唯一的,節(jié)點按照分值大小排序,如果分值相同,則按照成員對象的大小排序。
          • 整數(shù)集合(intset)。用于保存整數(shù)值的集合抽象數(shù)據(jù)結(jié)構(gòu),不會出現(xiàn)重復(fù)元素,底層實現(xiàn)為數(shù)組。
          • 壓縮列表(ziplist)。為節(jié)約內(nèi)存而開發(fā)的順序性數(shù)據(jù)結(jié)構(gòu),可以包含多個節(jié)點,每個節(jié)點可以保存一個字節(jié)數(shù)組或者整數(shù)值。


          Redis 支持哪些數(shù)據(jù)類型?

          答案:五種常用數(shù)據(jù)類型:StringHashSetListSortedSet。三種特殊的數(shù)據(jù)類型:BitmapHyperLogLogGeospatial,其中Bitmap 、HyperLogLog的底層都是 String 數(shù)據(jù)類型,Geospatial 底層是 Sorted Set 數(shù)據(jù)類型。

          • 字符串對象string:int整數(shù)、embstr編碼的簡單動態(tài)字符串、raw簡單動態(tài)字符串
          • 列表對象list:ziplist、linkedlist
          • 哈希對象hash:ziplist、hashtable
          • 集合對象set:intset、hashtable
          • 有序集合對象zset:ziplist、skiplist


          Redis 常用的 5 種數(shù)據(jù)結(jié)構(gòu)和應(yīng)用場景?

          答案:

          • String:緩存、計數(shù)器、分布式鎖等
          • List:鏈表、隊列、微博關(guān)注人時間軸列表等
          • Hash:用戶信息、Hash 表等
          • Set:去重、贊、踩、共同好友等
          • Zset:訪問量排行榜、點擊量排行榜等


          為什么采用單線程?

          答案:官方回復(fù),CPU不會成為Redis的制約瓶頸,Redis主要受內(nèi)存、網(wǎng)絡(luò)限制。例如,在一個普通的 Linux 系統(tǒng)上,使用pipelining 可以每秒傳遞 100 萬個請求,所以如果您的應(yīng)用程序主要使用 O(N) 或 O(log(N)) 命令,則幾乎不會使用太多 CPU,屬于IO密集型系統(tǒng)。


          Redis 6.0 之后又改用多線程呢?

          答案:Redis的多線程主要是處理數(shù)據(jù)的讀寫、協(xié)議解析。執(zhí)行命令還是采用單線程順序執(zhí)行。

          主要是因為redis的性能瓶頸在于網(wǎng)絡(luò)IO而非CPU,使用多線程進(jìn)行一些周邊預(yù)處理,提升了IO的讀寫效率,從而提高了整體的吞吐量。antirez 在 RedisConf 2019 分享時提到,Redis 6 引入的多線程 IO 對性能提升至少一倍以上。


          過期鍵Key 的刪除策略有哪些?

          答案:有3種過期刪除策略。惰性刪除、定期刪除、定時刪除

          • 惰性刪除。使用key時才進(jìn)行檢查,如果已經(jīng)過期,則刪除。缺點:過期的key如果沒有被訪問到,一直無法刪除,一直占用內(nèi)存,造成空間浪費(fèi)。
          • 定期刪除。每隔一段時間做一次檢查,刪除過期的key,每次只是隨機(jī)取一些key去檢查。
          • 定時刪除。為每個key設(shè)置過期時間,同時創(chuàng)建一個定時器。一旦到期,立即執(zhí)行刪除。缺點:如果過期鍵比較多時,占用CPU較多,對服務(wù)的性能有很大影響。


          如果Redis的內(nèi)存空間不足,淘汰機(jī)制?

          答案:

          • volatile-lru:從已設(shè)置過期時間的key中,移出最近最少使用的key進(jìn)行淘汰
          • allkeys-lru:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,移除最近最少使用的key(這個是最常用的)
          • volatile-ttl:從已設(shè)置過期時間的key中,移出將要過期的key
          • volatile-random:從已設(shè)置過期時間的key中,隨機(jī)選擇key淘汰
          • allkeys-random:從key中隨機(jī)選擇key進(jìn)行淘汰
          • no-eviction:禁止淘汰數(shù)據(jù)。當(dāng)內(nèi)存達(dá)到閾值的時候,新寫入操作報錯
          • volatile-lfu:從已設(shè)置過期時間的數(shù)據(jù)集(server.db[i].expires)中挑選最不經(jīng)常使用的數(shù)據(jù)淘汰(LFU(Least Frequently Used)算法,也就是最頻繁被訪問的數(shù)據(jù)將來最有可能被訪問到)
          • allkeys-lfu:當(dāng)內(nèi)存不足以容納新寫入數(shù)據(jù)時,在鍵空間中,移除最不經(jīng)常使用的key。


          Redis 突然掛了怎么解決?

          答案:1、從系統(tǒng)可用性角度思考,Redis Cluster引入主備機(jī)制,當(dāng)主節(jié)點掛了后,自動切換到備用節(jié)點,繼續(xù)提供服務(wù)。2、Client端引入本地緩存,通過開關(guān)切換,避免Redis突然掛掉,高并發(fā)流量把數(shù)據(jù)庫打掛。


          Redis 持久化有哪些方式?

          答案:

          1、快照RDB。將某個時間點上的數(shù)據(jù)庫狀態(tài)保存到RDB文件中,RDB文件是一個壓縮的二進(jìn)制文件,保存在磁盤上。當(dāng)Redis崩潰時,可用于恢復(fù)數(shù)據(jù)。通過SAVEBGSAVE來生成RDB文件。

          • SAVE:會阻塞redis進(jìn)程,直到RDB文件創(chuàng)建完畢,在進(jìn)程阻塞期間,redis不能處理任何命令請求。
          • BGSAVE:會fork出一個子進(jìn)程,然后由子進(jìn)程去負(fù)責(zé)生成RDB文件,父進(jìn)程還可以繼續(xù)處理命令請求,不會阻塞進(jìn)程。

          2、只追加文件AOF。以日志的形式記錄每個寫操作(非讀操作)。當(dāng)不同節(jié)點同步數(shù)據(jù)時,讀取日志文件的內(nèi)容將寫指令從前到后執(zhí)行一次,即可完成數(shù)據(jù)恢復(fù)。


          Redis 常用場景

          答案:

          • 1、緩存,有句話說的好,「性能不夠,緩存來湊」
          • 2、分布式鎖,利用Redis 的 setnx
          • 3、分布式session
          • 4、計數(shù)器,通過incr命令
          • 5、排行榜,Redis 的 有序集合
          • 6、其他


          Redis 緩存要注意的七大經(jīng)典問題?

          答案:列舉了億級系統(tǒng),高訪問量情況下Redis緩存可能會遇到哪些問題?以及對應(yīng)的解決方案。

          • 1、緩存集中失效
          • 2、緩存穿透
          • 3、緩存雪崩
          • 4、緩存熱點
          • 5、緩存大Key
          • 6、緩存數(shù)據(jù)的一致性
          • 7、數(shù)據(jù)并發(fā)競爭預(yù)熱


          Redis 集群方案有哪幾種?

          答案:

          • 主從復(fù)制模式
          • Sentinel(哨兵)模式
          • Redis Cluster模式


          Redis 主從數(shù)據(jù)同步(主從復(fù)制)的過程?

          答案:

          • 1、slave啟動后,向master發(fā)送sync命令
          • 2、master收到sync之后,執(zhí)行bgsave保存快照,生成RDB全量文件
          • 3、master把slave的寫命令記錄到緩存
          • 4、bgsave執(zhí)行完畢之后,發(fā)送RDB文件到slave,slave執(zhí)行
          • 5、master發(fā)送緩沖區(qū)的寫命令給slave,slave接收命令并執(zhí)行,完成復(fù)制初始化。
          • 6、此后,master每次執(zhí)行一個寫命令都會同步發(fā)送給slave,保持master與slave之間數(shù)據(jù)的一致性


          主從復(fù)制的優(yōu)缺點?

          答案:

          1、優(yōu)點:

          • master能自動將數(shù)據(jù)同步到slave,可以進(jìn)行讀寫分離,分擔(dān)master的讀壓力
          • master、slave之間的同步是以非阻塞的方式進(jìn)行的,同步期間,客戶端仍然可以提交查詢或更新請求

          缺點:

          • 不具備自動容錯與恢復(fù)功能,master 節(jié)點宕機(jī)后,需要手動指定新的 master
          • master宕機(jī),如果宕機(jī)前數(shù)據(jù)沒有同步完,則切換IP后會存在數(shù)據(jù)不一致的問題
          • 難以支持在線擴(kuò)容,Redis的容量受限于單機(jī)配置


          Sentinel(哨兵)模式的優(yōu)缺點?

          答案:哨兵模式基于主從復(fù)制模式,增加了哨兵來監(jiān)控自動處理故障

          1、優(yōu)點:

          • 哨兵模式基于主從復(fù)制模式,所以主從復(fù)制模式有的優(yōu)點,哨兵模式也有
          • master 掛掉可以自動進(jìn)行切換,系統(tǒng)可用性更高

          2、缺點:

          • Redis的容量受限于單機(jī)配置
          • 需要額外的資源來啟動sentinel進(jìn)程


          Redis Cluster 模式的優(yōu)缺點?

          答案:實現(xiàn)了Redis的分布式存儲,即每臺節(jié)點存儲不同的內(nèi)容,來解決在線擴(kuò)容的問題。

          1、優(yōu)點:

          • 無中心架構(gòu),數(shù)據(jù)按照slot分布在多個節(jié)點
          • 集群中的每個節(jié)點都是平等的,每個節(jié)點都保存各自的數(shù)據(jù)和整個集群的狀態(tài)。每個節(jié)點都和其他所有節(jié)點連接,而且這些連接保持活躍,這樣就保證了我們只需要連接集群中的任意一個節(jié)點,就可以獲取到其他節(jié)點的數(shù)據(jù)。
          • 可線性擴(kuò)展到1000多個節(jié)點,節(jié)點可動態(tài)添加或刪除
          • 能夠?qū)崿F(xiàn)自動故障轉(zhuǎn)移,節(jié)點之間通過gossip協(xié)議交換狀態(tài)信息,用投票機(jī)制完成slave到master的角色轉(zhuǎn)換

          缺點:

          • 數(shù)據(jù)通過異步復(fù)制,不保證數(shù)據(jù)的強(qiáng)一致性
          • slave充當(dāng) “冷備”,不對外提供讀、寫服務(wù),只作為故障轉(zhuǎn)移使用。
          • 批量操作限制,目前只支持具有相同slot值的key執(zhí)行批量操作,對mset、mget、sunion等操作支持不友好
          • key事務(wù)操作支持有限,只支持多key在同一節(jié)點的事務(wù)操作,多key分布在不同節(jié)點時無法使用事務(wù)功能
          • 不支持多數(shù)據(jù)庫空間,一臺redis可以支持16個db,集群模式下只能使用一個,即db 0。Redis Cluster模式不建議使用pipeline和multi-keys操作,減少max redirect產(chǎn)生的場景。


          Redis 如何做擴(kuò)容?

          答案:為了避免數(shù)據(jù)遷移失效,通常使用一致性哈希實現(xiàn)動態(tài)擴(kuò)容縮容,有效減少需要遷移的Key數(shù)量。

          但是Cluster 模式,采用固定Slot槽位方式(16384個),對每個key計算CRC16值,然后對16384取模,然后根據(jù)slot值找到目標(biāo)機(jī)器,擴(kuò)容時,我們只需要遷移一部分的slot到新節(jié)點即可。


          Redis 的集群原理?

          答案:一個redis集群由多個節(jié)點node組成,而多個node之間通過cluster meet命令來進(jìn)行連接,組成一個集群。

          數(shù)據(jù)存儲通過分片的形式,整個集群分成了16384個slot,每個節(jié)點負(fù)責(zé)一部分槽位。整個槽位的信息會同步到所有節(jié)點中。

          key與slot的映射關(guān)系:

          • 健值對 key,進(jìn)行 CRC16 計算,計算出一個 16 bit 的值
          • 將 16 bit 的值對 16384 取模,得到 0 ~ 16383 的數(shù)表示 key 對應(yīng)的哈希槽


          Redis 如何做到高可用?

          答案:哨兵機(jī)制。具有自動故障轉(zhuǎn)移、集群監(jiān)控、消息通知等功能。

          哨兵可以同時監(jiān)視所有的主、從服務(wù)器,當(dāng)某個master下線時,自動提升對應(yīng)的slave為master,然后由新master對外提供服務(wù)。


          什么是 Redis 事務(wù)?

          答案:Redis事務(wù)是一組命令的集合,將多個命令打包,然后把這些命令按順序添加到隊列中,并且按順序執(zhí)行這些命令。

          Redis事務(wù)中沒有像Mysql關(guān)系型數(shù)據(jù)庫事務(wù)隔離級別的概念,不能保證原子性操作,也沒有像Mysql那樣執(zhí)行事務(wù)失敗會進(jìn)行回滾操作


          Redis 事務(wù)執(zhí)行流程?

          答案:通過MULTIEXECWATCH等命令來實現(xiàn)事務(wù)機(jī)制,事務(wù)執(zhí)行過程將一系列多個命令按照順序一次性執(zhí)行,在執(zhí)行期間,事務(wù)不會被中斷,也不會去執(zhí)行客戶端的其他請求,直到所有命令執(zhí)行完畢。

          具體過程:

          • 服務(wù)端收到客戶端請求,事務(wù)以MULTI開始
          • 如果正處于事務(wù)狀態(tài)時,則會把后續(xù)命令放入隊列同時返回給客戶端QUEUED,反之則直接執(zhí)行這 個命令
          • 當(dāng)收到客戶端的EXEC命令時,才會將隊列里的命令取出、順序執(zhí)行,執(zhí)行完將當(dāng)前狀態(tài)從事務(wù)狀態(tài)改為非事務(wù)狀態(tài)
          • 如果收到 DISCARD 命令,放棄執(zhí)行隊列中的命令,可以理解為Mysql的回滾操作,并且將當(dāng)前的狀態(tài)從事務(wù)狀態(tài)改為非事務(wù)狀態(tài)

          WATCH 監(jiān)視某個key,該命令只能在MULTI命令之前執(zhí)行。如果監(jiān)視的key被其他客戶端修改,EXEC將會放棄執(zhí)行隊列中的所有命令。UNWATCH 取消監(jiān)視之前通過WATCH 命令監(jiān)視的key。通過執(zhí)行EXEC 、DISCARD 兩個命令之前監(jiān)視的key也會被取消監(jiān)視。


          Redis 與 Guava 、Caffeine 有什么區(qū)別?

          答案:緩存分為本地緩存和分布式緩存。

          1、Caffeine、Guava,屬于本地緩存,特點:

          • 直接訪問內(nèi)存,速度快,受內(nèi)存限制,無法進(jìn)行大數(shù)據(jù)存儲。
          • 無網(wǎng)絡(luò)通訊開銷,性能更高。
          • 只支持本地應(yīng)用進(jìn)程訪問,同步更新所有節(jié)點的本地緩存數(shù)據(jù)成本較高。
          • 應(yīng)用進(jìn)程重啟,數(shù)據(jù)會丟失。

          所以,本地緩存適合存儲一些不易改變或者低頻改變的高熱點數(shù)據(jù)。

          2、Redis屬于分布式緩存,特點:

          • 集群模式,支持大數(shù)據(jù)量存儲
          • 數(shù)據(jù)集中存儲,保證數(shù)據(jù)的一致性
          • 數(shù)據(jù)跨網(wǎng)絡(luò)傳輸,性能低于本地緩存。但同一個機(jī)房,兩臺服務(wù)器之間請求跑一個來回也就需要500微秒,比起其優(yōu)勢,這點損耗完全可以忽略,這也是分布式緩存受歡迎的原因。
          • 支持副本機(jī)制,有效的保證了高可用性。


          如何實現(xiàn)一個分布式鎖?

          答案:

          • 1、數(shù)據(jù)庫表,性能比較差
          • 2、使用Lua腳本 (包含 SETNX + EXPIRE 兩條指令)
          • 3、SET的擴(kuò)展命令(SET key value [EX][PX] [NX|XX])
          • 4、Redlock 框架
          • 5、Zookeeper Curator框架提供了現(xiàn)成的分布式鎖


          要求整治程序員高薪的那個人,被打了!


          緩存和數(shù)據(jù)庫一致性問題,看這篇就夠了


          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  大香蕉大香蕉最新视频在线75 | 老鸭窝在线免费视频 | 大香蕉中文电影 | 亚洲免费欧洲 | 国产精品毛片一区视频播 |