redis中兩種持久化缺陷介紹

一、RDB持久化模式缺陷

1、問(wèn)題描述:

并發(fā)200路,模擬不斷寫(xiě)Redis,持續(xù)4小時(shí)后,接口調(diào)用開(kāi)始出現(xiàn)大量失敗,錯(cuò)誤信息如下:

{"data":{"sendResult":null},"base":{"returncode":"99999","returndesc":"系統(tǒng)異常:MISCONF?Redis?is?configured?to?save?RDB?snapshots,?but?is?currently?not?able?to?persist?on?disk.?Commands?that?may?modify?the?data?set?are?disabled.?Please?check?Redis?logs?for?details?about?the?error."},"qrybase":{"total":0,"count":0,"start":0}}

2、原因分析:

解讀錯(cuò)誤信息,以為是磁盤(pán)不夠用引起,結(jié)果發(fā)現(xiàn)磁盤(pán)還剩余42%,如下所示:

于是根據(jù)錯(cuò)誤信息提示開(kāi)啟Redis日志,繼續(xù)壓測(cè),接口依然報(bào)錯(cuò),但可從Redis日志信息中

Can’t save in background: fork: Cannot allocate memory

進(jìn)程使用內(nèi)存不當(dāng)有關(guān),查看Redis主進(jìn)程占用內(nèi)存如下:占用近55%*4G內(nèi)存

具體原因:Redis在保存數(shù)據(jù)到硬盤(pán)時(shí)為了避免主進(jìn)程假死,需要Fork一份主進(jìn)程,然后在Fork進(jìn)程內(nèi)完成數(shù)據(jù)保存到硬盤(pán)的操作,如果主進(jìn)程使用了2.2GB的內(nèi)存,F(xiàn)ork子進(jìn)程的時(shí)候需要額外的2.2GB,此時(shí)內(nèi)存就不夠了,F(xiàn)ork失敗,進(jìn)而數(shù)據(jù)保存硬盤(pán)也失敗了。

3、緩解方案(不能根本解決問(wèn)題):

3.1 修改redis.conf文件中配置項(xiàng)stop-writes-on-bgsave-error no (默認(rèn)值為yes),即當(dāng)bgsave快照操作出錯(cuò)時(shí)停止寫(xiě)數(shù)據(jù)到磁盤(pán),這樣后面寫(xiě)錯(cuò)做均會(huì)失敗,為了不影響后續(xù)寫(xiě)操作,故需將該項(xiàng)值改為no

3.2 修改內(nèi)核參數(shù)(如下3種方式),但需要root權(quán)限:

(1)編輯/etc/sysctl.conf?,改vm.overcommit_memory=1,然后sysctl?-p?使配置文件生效

(2)sysctl?vm.overcommit_memory=1

(3)echo?1?>?/proc/sys/vm/overcommit_memory

二、AOF持久化模式缺陷

1、問(wèn)題1描述:

Redis主從節(jié)點(diǎn)均開(kāi)啟AOF模式,并發(fā)200路,模擬不斷寫(xiě)Redis,持續(xù)15分鐘后,接口調(diào)用開(kāi)始出現(xiàn)大量失敗,且Redis所在的Linux虛擬服務(wù)器掛起。

接口報(bào)錯(cuò)如下:

{"data":null,"base":{"returndesc":"系統(tǒng)異常","returncode":"999999"},"qrybase":null}

Biz(dubbo)接口報(bào)錯(cuò)如下:

2015-06-05?11:28:28.760?[DubboServerHandler-X.X.X.X:20882-thread-173]?ERROR??-?error?while?validate?jedis!

redis.clients.jedis.exceptions.JedisConnectionException:?java.net.SocketTimeoutException:?Read?timed?out

原因分析:

從dubbo接口報(bào)錯(cuò)信息來(lái)看,是由于接口API操作Redis超時(shí)導(dǎo)致。從系統(tǒng)日志和IO監(jiān)控來(lái)看,均說(shuō)明上述問(wèn)題是由于IO瓶頸(系統(tǒng)IO過(guò)于繁忙)所致,如下所示:

從系統(tǒng)日志也能看出,IO阻塞時(shí)間超過(guò)了120秒,由于系統(tǒng)安全機(jī)制導(dǎo)致機(jī)器掛起。

總結(jié)

測(cè)試結(jié)果證明AOF模式存在最明顯缺陷,即訪(fǎng)問(wèn)壓力大時(shí)IO會(huì)成為性能瓶頸,進(jìn)而導(dǎo)致服務(wù)不可用。

3、緩解方案(不能根本解決問(wèn)題)

編輯/etc/sysctl.conf ,添加如下配置:

vm.dirty_background_ratio?=?5

vm.dirty_ratio?=?10

然后sysctl -p 使配置文件生效。

問(wèn)題2描述:

無(wú)論采用AOF模式還是RDB(快照模式),當(dāng)兩文件(.aof或.rdb)大小超過(guò)系統(tǒng)內(nèi)存80%,Redis進(jìn)程會(huì)被系統(tǒng)Kill掉,導(dǎo)致服務(wù)不可用。

總結(jié)

上述問(wèn)題說(shuō)明我們?cè)谑褂肦edis時(shí)需要事先做好系統(tǒng)內(nèi)存的容量規(guī)劃,因?yàn)橐坏㏑edis宕掉會(huì)導(dǎo)致大量數(shù)據(jù)丟失且是不可恢復(fù)的。

本文來(lái)自PHP中文網(wǎng)的redis教程?欄目:https://www.php.cn/redis/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容