面试官:Redis中的缓冲区了解吗
Redis 大家肯定不陌生,但在使用層面看不到的地方,就容易被忽略。今天想和大家分享的內(nèi)容是 Redis 各個緩沖區(qū)的作用、溢出的后果及優(yōu)化方向。
在開始正文前,想多叨叨幾句。不管是 Redis 還是其他中間件,底層很多原理都是相似的,設(shè)計思想都是通用的。
大家以后如果在學(xué)什么新框架/組件,可以盡量和已經(jīng)學(xué)過的知識點進行聯(lián)想,這樣會更容易理解點的,不至于說死記硬背。
比如現(xiàn)在說到的緩沖區(qū),它的目的是什么呢?
無它,為了性能。
要么緩存數(shù)據(jù),提高響應(yīng)速度。比如 MySQL 中有個 change buffer
要么擔(dān)心消費者速度跟不上生產(chǎn),怕數(shù)據(jù)丟失。所以需要把生產(chǎn)數(shù)據(jù)先暫存起來。
Redis 的緩沖區(qū)就是這個作用。
另外,消費者速度跟不上,如果是同步處理的話,那是不是也會拖慢生產(chǎn)者,所以這里其實也是在保證生產(chǎn)者的速度。
可能有的讀者會說:扯淡,消費者都跟不上了,生產(chǎn)者再快有什么用?
其實有沒有一種可能,生產(chǎn)者根本不關(guān)心消費者什么時候用呢?前者是負責(zé)把后者需要的東西處理好給它就完事了。
生產(chǎn)者很忙,還有其他一大堆數(shù)據(jù)要處理,不能慢慢等消費者同步消費完才去做其他事情。
好像開頭擴展得有點多,我收一收,下面會詳細說到。有疑問的小伙伴請上車,七淅正式發(fā)車了。
1. 各緩沖區(qū)
首先 Redis 有什么緩沖區(qū)呢?
一共 4 個:
客戶端輸入緩沖區(qū)
客戶端輸出緩沖區(qū)
復(fù)制緩沖區(qū)
復(fù)制積壓緩沖區(qū)
2. 客戶端輸入緩沖區(qū)
服務(wù)器端會給每個連接的客戶端都設(shè)置了一個輸入緩沖區(qū)。
2.1 作用
暫存請求數(shù)據(jù)。
輸入緩沖區(qū)會先把客戶端發(fā)送過來的命令暫存起來,Redis 主線程再從輸入緩沖區(qū)中讀取命令,進行處理。
為了避免客戶端和服務(wù)器端的請求發(fā)送和處理速度不匹配,這點和等下要說的輸出緩沖區(qū)是一樣的。
2.2 溢出場景
首先緩沖區(qū)是一塊固定大小的內(nèi)存區(qū)域,如果要把這個地方填滿的話,那 Redis 會直接把客戶端連接關(guān)閉。
保護自己嘛,你客戶端掛了總比我服務(wù)端掛了好,服務(wù)端一掛就是所有客戶端都沒用了。
那填滿緩沖區(qū)就有 2 個情況了:
要么一下子填滿
要么生產(chǎn)速度大于消費速度,慢慢被填滿
那么把上述原理對應(yīng)到 Redis 的場景。
一下子填滿的情況可以是往 Redis 里寫大量數(shù)據(jù),百萬千萬數(shù)量級那種。
另一個情況可以是 Redis 服務(wù)端因執(zhí)行耗時操作,阻塞住了,導(dǎo)致沒法消費輸入緩沖區(qū)數(shù)據(jù)。
2.3 優(yōu)化
對應(yīng)上面 2 個溢出場景,優(yōu)化方向很自然就有了。
一下子填滿的情況,是不是可以考慮不要一下子寫這么多數(shù)據(jù),能否拆下數(shù)據(jù)(其實一下子寫大量數(shù)據(jù)本身就不合理哈)
另外,是否可以調(diào)高緩沖區(qū)大小呢?
這個其實是不行的哈,因為沒有可以設(shè)置的地方,目前服務(wù)端默認為每個客戶端輸入緩沖區(qū)分配的大小是 1GB。
那輪到第 2 個溢出場景:兩邊處理速度不一致。
正常來說,服務(wù)端不應(yīng)該出現(xiàn)長時間阻塞,所以需要看看是什么原因?qū)е碌淖枞?#xff0c;解決到就好了。
3. 客戶端輸出緩沖區(qū)
同輸入緩沖區(qū),服務(wù)器端也會給每個連接的客戶端都設(shè)置了一個輸出緩沖區(qū)。
3.1 作用
同上,也是暫存請求數(shù)據(jù)。
這個地方其實我在文章開頭說的,生產(chǎn)者不關(guān)心消費者什么時候用,只負責(zé)把消費者之前請求的東西處理好就完事了。
可能有點抽象,我是這么理解的,如果有不妥的地方可以留言糾正我一下。
服務(wù)端一般都會和多個客戶端連接,加上 redis 網(wǎng)絡(luò)通信模塊是單線程的(即使是新版本支持多線程也一樣)
假如沒有輸出緩沖區(qū)會發(fā)生什么事呢?
服務(wù)端處理了很多客戶端 A 的請求,需要經(jīng)過網(wǎng)絡(luò)這一耗時操作,返回給客戶端 A。在這個過程中,客戶端 B 的請求一直得不到服務(wù)端處理和響應(yīng),這樣吞吐量就上不去了。
有了緩沖區(qū)之后,至少能解放服務(wù)端,讓它去處理客戶端 B 的請求。
3.2 溢出場景
這里也是同輸入緩沖區(qū),我就不啰嗦了,溢出的話服務(wù)端也會關(guān)閉客戶端連接。
服務(wù)器端返回了大量數(shù)據(jù),一下子填滿了
返回數(shù)據(jù)的速度太快,比如執(zhí)行 MONITOR 命令,它會持續(xù)輸出監(jiān)測到的各個命令操作
緩沖區(qū)大小設(shè)置得不合理。
3.3 優(yōu)化
類似的,不要一下子讀大量數(shù)據(jù);不持續(xù)在線上執(zhí)行 MONITOR 命令。
而輸出緩沖區(qū)的大小是可以通過 client-output-buffer-limit 來設(shè)置的。
但是一般來說,我們都不用改,因為默認情況就夠了,這里了解下就好。
值得說一點的是,Redis 發(fā)布訂閱的消息也是在該緩沖區(qū)中,可以用下方參數(shù)來限制大小,比如:client-output-buffer-limit pubsub 8mb 2mb 60
含義如下:
pubsub 表示對訂閱客戶端進行設(shè)置。換成 normal 則表示當(dāng)前設(shè)置的是普通客戶端
整個配置的含義是:實際占用的緩沖區(qū)大小要超過 8MB,或者連續(xù) 60 秒內(nèi)對輸出緩沖區(qū)的寫入量超過 2MB 的話,服務(wù)端就會關(guān)閉客戶端連接。
4. 復(fù)制緩沖區(qū)
溫馨提示下,如果對 Redis 同步/復(fù)制不了解的讀者,比如不知道全量/增量復(fù)制,建議可以看下我這篇文章:一文讓你明白Redis主從同步
下面回到正題哈。
有復(fù)制肯定有主從,而主從間的數(shù)據(jù)復(fù)制包括全量復(fù)制和增量復(fù)制兩種。
全量復(fù)制是同步所有數(shù)據(jù),而增量復(fù)制只會把主從庫網(wǎng)絡(luò)斷連期間主庫收到的命令,同步給從庫。
4.1 作用
暫存數(shù)據(jù)。
主節(jié)點上會為每個從節(jié)點都維護一個復(fù)制緩沖區(qū)。
在全量復(fù)制時,主節(jié)點在向從節(jié)點傳輸 RDB 文件的同時,會繼續(xù)接收客戶端發(fā)送的寫命令請求,并保存在復(fù)制緩沖區(qū)中,等 RDB 文件傳輸完成后,再發(fā)送給從節(jié)點去執(zhí)行。
4.2 溢出場景
從節(jié)點接收和加載 RDB 較慢,同時主節(jié)點接收到了大量的寫命令,寫命令在復(fù)制緩沖區(qū)中就會越積越多,最后就會溢出。
一旦溢出,主節(jié)點會直接關(guān)閉和從節(jié)點進行復(fù)制操作的連接,導(dǎo)致全量復(fù)制失敗
4.3 優(yōu)化
可以控制主節(jié)點數(shù)據(jù)量在 2~4GB(僅供參考),這樣可以讓全量同步執(zhí)行得更快些,避免復(fù)制緩沖區(qū)累積過多命令
也可以調(diào)整緩沖區(qū)大小,還是之前的 client-output-buffer-limit 參數(shù)。
比如:config set client-output-buffer-limit slave 512mb 128mb 60
slave 參數(shù)表明該配置項是針對復(fù)制緩沖區(qū)的.
整個配置的含義是:實際占用的緩沖區(qū)大小要超過 512MB,或者連續(xù) 60 秒內(nèi)對輸出緩沖區(qū)的寫入量超過 128MB 的話,服務(wù)端就會關(guān)閉同步連接。
5. 復(fù)制積壓緩沖區(qū)
這個是在新增復(fù)制用到的緩沖區(qū)。
PS:具體介紹還是推薦看上面提到的文章哈,寫到這里已經(jīng) 3k+ 字了,頂不住啦~
5.1 作用
暫存數(shù)據(jù)。
從節(jié)點意外斷開連接后重連,可從該緩沖區(qū)同步期間沒同步到的數(shù)據(jù)。
5.2 溢出場景
不會溢出(想不到吧.jpg)
該緩沖區(qū)本質(zhì)是一個固定長度,先進先出的隊列,默認 1MB。
所以當(dāng)隊列被占滿,不是報錯,也不像上面幾個緩沖區(qū)直接關(guān)閉連接。而是覆蓋最
早進入隊列的數(shù)據(jù)。
因此,如果有從節(jié)點還沒有同步這些舊命令數(shù)據(jù),就會導(dǎo)致主從節(jié)點重新進行全量復(fù)制,而不是增量復(fù)制。
PS:全量復(fù)制性能開銷遠大于增量復(fù)制
5.3 優(yōu)化
調(diào)整復(fù)制積壓緩沖區(qū)的大小,參數(shù)是:repl_backlog_size
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的面试官:Redis中的缓冲区了解吗的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python爬虫实例手机_python爬
- 下一篇: debug内exe文件复制到桌面无法打开