轉(zhuǎn)載于:https://mp.weixin.qq.com/s/qvXm1pU8T_2mCZCjkTR7QA
1 Redis常見面試問題
1.1 Redis是單線程還是多線程
Redis
不同版本之間采用的線程模型是不一樣的暇韧,在Redis4.0
版本之前使用的是單線程模型
验游,在4.0
版本之后增加了多線程的支持。
在4.0
之前雖然說Redis
是單線程图张,也只是說它的網(wǎng)絡(luò)I/O
線程以及Set
和 Get
操作是由一個線程完成的垫挨。但是Redis
的持久化
韩肝、集群同步
還是使用其他線程來完成。
4.0之后添加了多線程
的支持九榔,主要是體現(xiàn)在大數(shù)據(jù)的異步刪除
功能上哀峻,例如 unlink key、flushdb async帚屉、flushall async
等
1.2 使用單線程原因
那為什么Redis在4.0之前會選擇使用單線程谜诫?而且使用單線程還那么快?
選擇單線程主要是使用簡單攻旦,不存在鎖競爭
喻旷,可以在無鎖的情況下完成所有操作,不存在死鎖和線程切換帶來的性能和時間上的開銷牢屋,但同時單線程也不能完全發(fā)揮出多核CPU性能
為什么單線程那么快主要有以下幾個原因:
-
Redis
的大部分操作都在內(nèi)存中完成且预,內(nèi)存中的執(zhí)行效率本身就很快槽袄,并且采用了高效的數(shù)據(jù)結(jié)構(gòu),比如哈希表和跳表锋谐。 - 使用單線程避免了多線程的競爭遍尺,省去了多線程切換帶來的時間和性能開銷,并且不會出現(xiàn)死鎖涮拗。
- 采用
I/O
多路復用機制處理大量客戶端的Socket
請求乾戏,因為這是基于非阻塞的 I/O 模型,這就讓Redis
可以高效地進行網(wǎng)絡(luò)通信三热,I/O的讀寫流程也不再阻塞鼓择。 - 很多的客戶端連接先到linux中的內(nèi)核,內(nèi)核和redis中間使用的是epoll(非阻塞的多路復用)就漾,那些進程一筆一筆的進行的呐能。
在分布式情況下,這個數(shù)據(jù)一致性很重要抑堡。每個連接里邊命令是順序到達趴生、順序處理的疾层,但是如果說里面有個key渤刃,這個key為a膘侮,那么兩個客戶端發(fā)了一個對a的操作据块,那么無論從網(wǎng)絡(luò)當中跳躍誰先到達的关拒,或者指定誰先輪到誰了灾常。那么其實這兩個人對一個的操作俺叭,很難判定是誰先誰后舌仍,但是如果是你一個人妒貌,它里邊線性,而且沒有使用多線程铸豁,線程還是安全的灌曙,雖然它可以有多線程,但是線程安全节芥,對a的操作在刺,這邊能控制住,先創(chuàng)建a再刪除a头镊,只要這邊能操作的話蚣驼,那么這個數(shù)據(jù)是可以保證的。如果是單線程相艇,這個客戶端就是一個線程颖杏,就是一個socket里面也是一個線程,那么這個線程肯定是先發(fā)出一個創(chuàng)建a再發(fā)出一個刪除a坛芽,但是如果客戶端里邊是多線程留储,那么這里一個創(chuàng)建命令和刪除命令翼抠,指不定誰跑到前面了,如果線程不是安全的話获讳,那么有可能先把刪除的發(fā)出去阴颖,再把創(chuàng)建的發(fā)出去。
點擊了解Linux中epoll原理機制
1.3 Redis高可用
Redis實現(xiàn)高可用主要有三種方式:主從復制
丐膝、哨兵模式
量愧,以及 Redis 集群
1.3.1 主從復制
將從前的一臺 Redis
服務(wù)器,同步數(shù)據(jù)到多臺從 Redis
服務(wù)器上帅矗,即一主多從的模式侠畔,這個跟MySQL
主從復制的原理一樣。
點擊了解redis 持久化中的主從復制同步
1.3.2 哨兵模式
使用 Redis
主從復制的時候损晤,會有一個問題软棺,就是當 Redis
的主從服務(wù)器出現(xiàn)故障宕機時,需要手動進行恢復尤勋,為了解決這個問題喘落,Redis
增加了哨兵模式(因為哨兵模式做到了可以監(jiān)控主從服務(wù)器,并且提供自動容災(zāi)恢復的功能)最冰。
它專注于對 Redis 實例
(主節(jié)點瘦棋、從節(jié)點)運行狀態(tài)的監(jiān)控,并能夠在主節(jié)點發(fā)生故障時通過一系列的機制實現(xiàn)選主
及主從切換
暖哨,實現(xiàn)自動故障轉(zhuǎn)移赌朋,確保整個 Redis 系統(tǒng)的可用性。
sentinel
主要做四件事情:
- 監(jiān)控
master
和slave
狀態(tài)篇裁,判斷是否下線沛慢。
每秒一次的頻率向master
和slave
以及其他sentinel
發(fā)送PING
命令,如果該節(jié)點距離最后一次響應(yīng) PING 的時間超過down-after-milliseconds
選項所指定的值达布, 則這個實例會被 Sentinel 標記為主觀下線团甲,當master
被標記主觀下線。
其他正在監(jiān)視這個master
的所有sentinel
會按照每秒一次的頻率確認master
是否主觀下線黍聂。
當足夠多的sentinel
都認為master
主觀下線躺苦,則標記這個master
客觀下線。 - 選舉新
master
产还,如果 master 出現(xiàn)故障匹厘,sentine 需要選舉一個 slave 晉升為新 master。晉升為新 master 的 slave 是有條件的脐区,先過濾不滿足條件的愈诚,再打分排優(yōu)先級。-
slave
優(yōu)先級,通過replica-priority 100
配置扰路,值越低尤溜,優(yōu)先級越高。 - 復制偏移量(
processed replication offset
)汗唱,已復制的數(shù)據(jù)量越多越好宫莱,slave_repl_offset
與master_repl_offset
差值越小。 -
slave runID
哩罪,在優(yōu)先級和復制進度都相同的情況下授霸,runID
最小的 slave 得分最高,會被選為新主庫际插。 - 過濾掉下線碘耳、網(wǎng)絡(luò)異常的
slave
。 - 過濾掉經(jīng)常與
master
斷開的slave
框弛。
-
- 選舉領(lǐng)導者哨兵(Leader Sentinel)辛辨,執(zhí)行主從切換,從
sentinel
集群中選舉一個leader
執(zhí)行故障自動切換瑟枫。
第一個判定master
主觀下線的sentinel
收到其他sentinel
節(jié)點的回復并確定master
客觀下線后斗搞,就會給其他sentinel
節(jié)點發(fā)送命令申請成為 leader。
選舉領(lǐng)導者哨兵而不是直接從從節(jié)點中選舉新的主節(jié)點慷妙,主要是為了以下原因:- 協(xié)調(diào)一致性:通過選舉領(lǐng)導者哨兵僻焚,可以確保在集群中僅有一個哨兵負責主從切換,避免多個哨兵同時進行切換操作導致的不一致性膝擂。
- 集中決策:領(lǐng)導者哨兵集中管理整個主從切換過程虑啤,使得切換過程更加有序和可控。
- 分擔職責:哨兵負責監(jiān)控和管理 Redis 節(jié)點架馋,而從節(jié)點主要用于數(shù)據(jù)復制和故障切換狞山。在發(fā)生故障時,選舉領(lǐng)導者哨兵來管理切換過程绩蜻,可以讓從節(jié)點專注于數(shù)據(jù)同步铣墨,分擔系統(tǒng)負載
成為leader
的條件是收到的贊成票大于等于quorum
的值且贊半數(shù)以上室埋。
- 通知办绝,通知其他
slave
執(zhí)行replicaof
與新的master
同步數(shù)據(jù),并通知客戶端與新 master 建立連接姚淆。
1.3.3 Redis Cluster(集群)
哨兵模式
基于主從模式孕蝉,實現(xiàn)讀寫分離,它還可以自動切換腌逢,系統(tǒng)可用性更高降淮。但是它每個節(jié)點存儲的數(shù)據(jù)是一樣的,浪費內(nèi)存,并且不好在線擴容佳鳖。因此霍殴,Reids Cluster
集群(切片集群的實現(xiàn)方案)應(yīng)運而生,它在Redis3.0加入的系吩,實現(xiàn)了Redis的分布式存儲来庭。對數(shù)據(jù)進行分片,也就是說每臺Redis節(jié)點上存儲不同的內(nèi)容穿挨,來解決在線擴容的問題月弛。并且,它可以保存大量數(shù)據(jù)科盛,即分散數(shù)據(jù)到各個Redis實例帽衙,還提供復制和故障轉(zhuǎn)移的功能。
Redis Cluster
是一種分布式去中心化的運行模式贞绵,是在 Redis 3.0 版本中推出的 Redis 集群方案厉萝,它將數(shù)據(jù)分布在不同的服務(wù)器上,以此來降低系統(tǒng)對單主節(jié)點的依賴榨崩,從而提高 Redis
服務(wù)的讀寫性能冀泻。
使用哨兵模式在數(shù)據(jù)上有副本數(shù)據(jù)做保證,在可用性上又有哨兵監(jiān)控蜡饵,一旦master
宕機會選舉salve
節(jié)點為master
節(jié)點弹渔,那為什么還需要使用集群模式呢?
哨兵模式歸根節(jié)點還是主從模式
溯祸,在主從模式下我們可以通過增加salve
節(jié)點來擴展讀并發(fā)能力肢专,但是沒辦法擴展寫能力和存儲能力,存儲能力只能是master
節(jié)點能夠承載的上限焦辅。所以為了擴展寫能力和存儲能力博杖,我們就需要引入集群模式。
集群中那么多Master
節(jié)點筷登,redis cluster
在存儲的時候如何確定選擇哪個節(jié)點呢剃根?
Redis Cluster
采用的是數(shù)據(jù)分片
實現(xiàn)節(jié)點選擇的
1.4 Redis內(nèi)存(數(shù)據(jù))淘汰策略
在redis
中,我們是可以去設(shè)置最大使用內(nèi)存大小server.maxmemory
的前方,當redis
內(nèi)存數(shù)據(jù)集大小上升到一定程度的時候狈醉,就會施行數(shù)據(jù)淘汰機制。
不同位數(shù)的操作系統(tǒng)惠险,maxmemory
的默認值是不同的:
- 在 64 位操作系統(tǒng)中苗傅,
maxmemory
的默認值是 0,表示沒有內(nèi)存大小限制班巩,那么不管用戶存放多少數(shù)據(jù)到Redis
中渣慕,Redis
也不會對可用內(nèi)存進行檢查,直到 Redis 實例因內(nèi)存不足而崩潰也無作為。 - 在 32 位操作系統(tǒng)中逊桦,
maxmemory
的默認值是3G
眨猎,因為 32 位的機器最大只支持4GB
的內(nèi)存,而系統(tǒng)本身就需要一定的內(nèi)存資源來支持運行强经,所以 32 位操作系統(tǒng)限制最大 3 GB 的可用內(nèi)存是非常合理的宵呛,這樣可以避免因為內(nèi)存不足而導致Redis
實例崩潰。
Redis
提供了8種數(shù)據(jù)淘汰策略夕凝,分為不進行數(shù)據(jù)淘汰
和進行數(shù)據(jù)淘汰
兩類策略宝穗,
不進行數(shù)據(jù)淘汰的策略 noeviction
(Redis3.0
之后,默認的內(nèi)存淘汰策略)码秉,它表示當運行內(nèi)存超過最大設(shè)置內(nèi)存時逮矛,不淘汰任何數(shù)據(jù),這時如果有新的數(shù)據(jù)寫入转砖,會報錯通知禁止寫入须鼎,不淘汰任何數(shù)據(jù),但是如果沒用數(shù)據(jù)寫入的話府蔗,只是單純的查詢或者刪除操作的話晋控,還是可以正常工作。
-
no-enviction
:禁止淘汰數(shù)據(jù)姓赤,如果redis寫滿了將不提供寫請求赡译,直接返回錯誤
進行數(shù)據(jù)淘汰的策略:
-
volatile-lru
:從已經(jīng)設(shè)置過期時間的數(shù)據(jù)集中,挑選最近最少使用的數(shù)據(jù)淘汰不铆,即:最久未使用的鍵值 -
volatile-ttl
:從已經(jīng)設(shè)置過期時間的數(shù)據(jù)集中蝌焚,挑選即將要過期的數(shù)據(jù)淘汰。 -
volatile-random
:從已經(jīng)設(shè)置過期時間的數(shù)據(jù)集中誓斥,隨機挑選數(shù)據(jù)淘汰只洒。 -
volatile-lfu
:從已經(jīng)設(shè)置過期時間的數(shù)據(jù)集中,會使用LFU
算法選擇設(shè)置了過期時間的鍵值對劳坑,即:最不常用的鍵值 -
allkeys-lru
:從所有的數(shù)據(jù)集中毕谴,挑選最近最少使用的數(shù)據(jù)淘汰。 -
allkeys-random
:從所有的數(shù)據(jù)集中距芬,隨機挑選數(shù)據(jù)淘汰涝开。 -
allkeys-lfu
:淘汰整個鍵值中最不常用的鍵值
附錄:LRU
和LFU
是不同的:
-
LRU
是最近最少使用頁面置換算法(Least Recently Used
),也就是首先淘汰最長時間未被使用的頁面 -
LFU
是最近最不常用頁面置換算法(Least Frequently Used
),也就是淘汰一定時期內(nèi)被訪問次數(shù)最少的頁
使用策略規(guī)則:
- 如果數(shù)據(jù)呈現(xiàn)
冪律分布
,也就是一部分數(shù)據(jù)訪問頻率高蔑穴,一部分數(shù)據(jù)訪問頻率低忠寻,則使用allkeys-lru
- 如果數(shù)據(jù)呈現(xiàn)
平等分布
,也就是所有的數(shù)據(jù)訪問頻率都相同存和,則使用allkeys-random
1.5 Redis過期鍵刪除策略
Redis
過期鍵刪除策略:
-
定時刪除
:在設(shè)置鍵的過期時間的同時,創(chuàng)建一個timer
,讓定時器在鍵的過期時間到達時捐腿,立即執(zhí)行對鍵的刪除操作纵朋。(主動刪除)
對內(nèi)存友好,但是對cpu時間不友好茄袖,有較多過期鍵的而情況下操软,刪除過期鍵會占用相當一部分cpu時間。 -
惰性刪除
:放任過期鍵不管宪祥,但是每次從鍵空間中獲取鍵時聂薪,都檢查取到的鍵是否過去,如果過期就刪除蝗羊,如果沒過期就返回該鍵藏澳。(被動刪除)
對cpu
時間友好,程序只會在取出鍵的時候才會對鍵進行過期檢查耀找,這不會在刪除其他無關(guān)過期鍵上花費任何cpu時間翔悠,但是如果一個鍵已經(jīng)過期,而這個鍵又保留在數(shù)據(jù)庫中野芒,那么只要這個過期鍵不被刪除蓄愁,他所占用的內(nèi)存就不會釋放,對內(nèi)存不友好狞悲。 -
定期刪除
:每隔一段時間就對數(shù)據(jù)庫進行一次檢查撮抓,刪除里面的過期鍵。(主動刪除)采用對內(nèi)存
和cpu
時間折中的方法摇锋,每隔一段時間就對一些key
進行采樣檢查胀滚,檢查是否過期,如果過期就進行刪除
1乱投、采樣一定個數(shù)的key
咽笼,采樣的個數(shù)可以進行配置,并將其中過期的key
全部刪除戚炫;
2剑刑、如果過期key
的占比超過可接受的過期key
的百分比,則重復刪除的過程双肤,直到過期key
的比例降至可接受的過期key
的百分比以下
1.6 Redis的key和value可以存儲的最大值分別是多少
雖然Key
的大小上限為512M
,但是一般建議key
的大小不要超過1KB
施掏,這樣既可以節(jié)約存儲空間,又有利于Redis
進行檢索茅糜。
value
的最大值也是512M
七芭。對于String
類型的value
值上限為512M
,而集合蔑赘、鏈表狸驳、哈希等key
類型预明,單個元素的value
上限也為512M
1.7 Redis實現(xiàn)數(shù)據(jù)的去重
-
Redis
的set
:它可以去除重復元素,也可以快速判斷某一個元素是否存在于集合中耙箍,如果元素很多(比如上億的計數(shù))撰糠,占用內(nèi)存很大。 -
Redis
的bit
:它可以用來實現(xiàn)比set內(nèi)存高度壓縮的計數(shù)辩昆,它通過一個bit
設(shè)置為1
或者0
阅酪,表示存儲某個元素是否存在信息。例如網(wǎng)站唯一訪客計數(shù)汁针,可以把user_id
作為bit
的偏移量offset
术辐,如設(shè)置為1
表示有訪問,使用1 MB
的空間就可以存放800多萬用戶的一天訪問計數(shù)情況施无。 -
HyperLogLog
:實現(xiàn)超大數(shù)據(jù)量精確的唯一計數(shù)都是比較困難的辉词,HyperLogLog
可以僅僅使用 12 k左右的內(nèi)存,實現(xiàn)上億的唯一計數(shù)帆精,而且誤差控制在百分之一左右较屿。 -
bloomfilter
布隆過濾器:布隆過濾器是一種占用空間很小的數(shù)據(jù)結(jié)構(gòu),它由一個很長的二進制向量和一組Hash映射函數(shù)組成卓练,它用于檢索一個元素是否在一個集合中
1.8 Redis序列化
Redis
什么時候需要序列化隘蝎?
-
序列化
:將Java
對象轉(zhuǎn)換成字節(jié)流的過程。 -
反序列化
:將字節(jié)流轉(zhuǎn)換成Java
對象的過程襟企。
為什么需要序列化呢嘱么?
打個比喻:作為大城市漂泊的碼農(nóng),搬家是常態(tài)顽悼。當我們搬書桌時曼振,桌子太大了就通不過比較小的門,因此我們需要把它拆開再搬過去蔚龙,這個拆桌子的過程就是序列化冰评。而我們把書桌復原回來(安裝)的過程就是反序列化啦。
比如想把內(nèi)存中的對象狀態(tài)保存到一個文件中或者數(shù)據(jù)庫中的時候(最常用木羹,如保存到redis
)甲雅;再比喻想用套接字在網(wǎng)絡(luò)上傳送對象的時候,都需要序列化坑填。
RedisSerializer
接口 是 Redis
序列化接口抛人,用于 Redis KEY
和 VALUE
的序列化,有如下序列化方式:
-
JDK
序列化方式 (默認) -
String
序列化方式 -
JSON
序列化方式 -
XML
序列化方式
1.9 大key
1.9.1 定義
Redis
中的 大key
是指存儲在Redis
中的占用內(nèi)存較大的鍵值對脐瑰。大key
可能會導致Redis
的性能下降妖枚,因為大key
占用的內(nèi)存較多,需要較長的時間來進行讀寫操作苍在。而且绝页,當大key
被刪除時荠商,會阻塞Redis
的其他操作。
常見的大key包括:
- 存儲大量數(shù)據(jù)的字符串類型鍵值對抒寂。
- 存儲大量元素的列表结啼、集合或有序集合掠剑。
- 包含大量字段的哈希表屈芜。
1.9.2 大Key解決方案
為了避免大key
對Redis
性能的影響,可以采取以下措施:
- 將
大key
拆分為多個較小的鍵值對朴译,以減少每個鍵值對的內(nèi)存占用井佑。 - 使用分布式緩存,將
大key
分散到多個Redis
實例上眠寿。 - 使用壓縮算法對
大key
進行壓縮躬翁,減少內(nèi)存占用。 - 使用
Redis
的分片功能盯拱,將大key
分散到多個分片上盒发,減少單個Redis
實例的負載。 - 對
大Key
進行清理狡逢。將不適用Redis能力的數(shù)據(jù)存至其它存儲宁舰,并在Redis中刪除此類數(shù)據(jù)。注意奢浑,要使用異步刪除蛮艰。 - 監(jiān)控Redis的內(nèi)存水位∪副耍可以通過監(jiān)控系統(tǒng)設(shè)置合理的Redis內(nèi)存報警閾值進行提醒壤蚜,例如Redis內(nèi)存使用率超過70%、Redis的內(nèi)存在1小時內(nèi)增長率超過20%等徊哑。
- 對過期數(shù)據(jù)進行定期清袜刷。堆積大量過期數(shù)據(jù)會造成
大Ke
y的產(chǎn)生,例如在HASH數(shù)據(jù)類型中以增量的形式不斷寫入大量數(shù)據(jù)而忽略了數(shù)據(jù)的時效性莺丑≈罚可以通過定時任務(wù)的方式對失效數(shù)據(jù)進行清理。
1.10 熱Key
1.10.1 定義
Redis熱key
是指在Redis
中被頻繁訪問的鍵窒盐。當某個鍵被頻繁訪問時草则,它就被認為是熱key
。熱key
通常是由于某些熱門操作蟹漓、熱門數(shù)據(jù)或者高并發(fā)訪問所導致的
通常以其接收到的 Key
被請求頻率來判定炕横,例如:
-
QPS
集中在特定的Key:Redis實例的總QPS(每秒查詢率)為10,000,而其中一個Key的每秒訪問量達到了7,000葡粒。 - 帶寬使用率集中在特定的Key:對一個擁有上千個成員且總大小為1 MB的HASH Key每秒發(fā)送大量的HGETALL操作請求份殿。
- CPU使用時間占比集中在特定的Key:對一個擁有數(shù)萬個成員的Key(ZSET類型)每秒發(fā)送大量的ZRANGE操作請求膜钓。
1.10.2 如何解決熱key
熱key
可能對Redis
的性能產(chǎn)生重大影響。當一個鍵被頻繁訪問時卿嘲,Redis
需要頻繁地從內(nèi)存中讀取或?qū)懭朐撴I的值颂斜,這可能導致內(nèi)存帶寬的瓶頸、CPU利用率的增加以及延遲的增加拾枣。此外沃疮,如果一個熱key的值過大,可能會占用大量的內(nèi)存梅肤,進一步影響Redis的性能
解決方案:
- 在
Redis
集群架構(gòu)中對熱Key
進行復制司蔬,數(shù)據(jù)分片
在Redis
集群架構(gòu)中,由于熱Key
的遷移粒度問題姨蝴,無法將請求分散至其他數(shù)據(jù)分片俊啼,導致單個數(shù)據(jù)分片的壓力無法下降。此時左医,可以將對應(yīng)熱Key進行復制并遷移至其他數(shù)據(jù)分片授帕,例如將熱Key foo復制出3個內(nèi)容完全一樣的Key并名為foo2、foo3浮梢、foo4跛十,將這三個Key遷移到其他數(shù)據(jù)分片來解決單個數(shù)據(jù)分片的熱Key壓力。 - 使用讀寫分離架構(gòu)黔寇。
如果熱Key
的產(chǎn)生來自于讀請求偶器,您可以將實例改造成讀寫分離架構(gòu)來降低每個數(shù)據(jù)分片的讀請求壓力,甚至可以不斷地增加從節(jié)點缝裤。但是讀寫分離架構(gòu)在增加業(yè)務(wù)代碼復雜度的同時屏轰,也會增加Redis集群架構(gòu)復雜度。不僅要為多個從節(jié)點提供轉(zhuǎn)發(fā)層(如Proxy憋飞,LVS等)來實現(xiàn)負載均衡霎苗,還要考慮從節(jié)點數(shù)量顯著增加后帶來故障率增加的問題。Redis集群架構(gòu)變更會為監(jiān)控榛做、運維唁盏、故障處理帶來了更大的挑戰(zhàn)。 - 使用合適的數(shù)據(jù)結(jié)構(gòu)
根據(jù)實際情況選擇合適的數(shù)據(jù)結(jié)構(gòu)检眯,如列表厘擂、集合、有序集合等锰瘸,來存儲熱key的值刽严,以提高讀寫性能。 - 緩存策略
使用合理的緩存策略避凝,比如設(shè)置合適的過期時間舞萄、使用LRU算法等眨补,以減少對熱key的訪問頻率。 - 持久化策略
根據(jù)業(yè)務(wù)需求選擇合適的持久化方式倒脓,如RDB快照撑螺、AOF日志等,以確保數(shù)據(jù)的安全性和可靠性崎弃。
1.11 Redis中緩沖區(qū)
Redis中的緩沖區(qū)主要根據(jù)其功能和用途進行劃分甘晤,可以歸納為以下幾種:
- 客戶端緩沖區(qū):
- 輸入緩沖區(qū):緩存客戶端發(fā)送過來的命令,
Redis
主線程從該緩沖區(qū)中讀取命令進行處理吊履。 - 輸出緩沖區(qū):當
Redis
主線程處理完數(shù)據(jù)后安皱,將結(jié)果寫入該緩沖區(qū)调鬓,再返回給客戶端艇炎。 - 緩存區(qū)溢出原因:
- 寫入了BigKey,即一次性寫入了大量數(shù)據(jù)腾窝,超過了緩沖區(qū)的大小缀踪。
- 服務(wù)端處理請求的速度過慢,導致無法及時處理請求虹脯,使得客戶端發(fā)送的請求在緩沖區(qū)內(nèi)越積越多驴娃。
- 輸入緩沖區(qū):緩存客戶端發(fā)送過來的命令,
- 復制緩沖區(qū):
- 復制緩沖區(qū):在全量復制過程中,主節(jié)點在向從節(jié)點傳輸
RDB
文件的同時循集,會繼續(xù)接收客戶端發(fā)送的寫命令請求唇敞。這些寫命令會先保存在復制緩沖區(qū)中,等RDB
文件傳輸完成后咒彤,再發(fā)送給從節(jié)點去執(zhí)行疆柔。 - 復制積壓緩沖區(qū):在增量復制時,主節(jié)點和從節(jié)點進行常規(guī)同步時镶柱,會把寫命令暫存在
復制積壓緩沖區(qū)
中旷档。 - 溢出原因:
- 主庫傳輸RDB文件以及從庫加載RDB文件耗時長,同時主庫接收的寫命令操作較多歇拆。
- 緩沖區(qū)大小設(shè)置不合理鞋屈。
- 復制緩沖區(qū):在全量復制過程中,主節(jié)點在向從節(jié)點傳輸
- AOF緩沖區(qū):
- AOF緩沖區(qū):當
Redis
進行持久化時,會先將客戶端傳來的命令存放在AOF
緩沖區(qū)故觅,再根據(jù)具體的策略(always厂庇、everysec、no)去寫入磁盤中的AOF文件中输吏。 - AOF重寫緩沖區(qū):在
Redis
進行AOF
重寫時权旷,主進程會fork一個子進程進行AOF
重寫,此時主進程接收的指令會存放在AOF重寫緩沖區(qū)中评也。當AOF重寫完成后炼杖,這些指令會被追加到AOF文件中灭返。
- AOF緩沖區(qū):當
- 內(nèi)存級緩存:
雖然不是嚴格意義上的緩沖區(qū)
,但Redis
的內(nèi)存級緩存是其最常見的使用場景坤邪。通過將數(shù)據(jù)存儲在內(nèi)存中熙含,減少讀取數(shù)據(jù)庫的頻率,提高數(shù)據(jù)訪問速度艇纺。 - 其他內(nèi)存使用:
-
Redis
空進程自身內(nèi)存消耗非常少怎静,通常used_memory_rss
在3MB左右,used_memory在800KB左右黔衡。 - 對象內(nèi)存:存儲著用戶所有的數(shù)據(jù)蚓聘,消耗可以簡單理解為sizeof(keys)+sizeof(values)。
- 內(nèi)存碎片:正常的碎片率在1.03左右
-