亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么Redis數據庫內存不宜過大?

為什么Redis數據庫內存不宜過大?

嗶嗶one 2018-10-09 18:14:34
為什么Redis數據庫內存不宜過大
查看完整描述

1 回答

?
慕桂英3389331

TA貢獻2036條經驗 獲得超8個贊

1 主庫宕機
  先來看一下主庫宕機容災過程:
  在主庫宕機的時候,我們最常見的容災策略為“切主”。具體為從該集群剩余從庫中選出一個從庫并將其升級為主庫,該從庫升級為主庫后再將剩余從庫掛載至其下成為其從庫,最終恢復整個主從集群結構。
  以上是一個完整的容災過程,而代價最大的過程為從庫的重新掛載,而非主庫的切換。
  這是因為redis無法像mysql、mongodb那樣基于同步的點位在主庫發生變化后從新的主庫繼續同步數據。 在redis集群中一旦從庫換主,redis的做法是將更換主庫的從庫清空然后從新主庫完整同步一份數據再進行續傳。
  整個從庫重做流程是這樣的:
  主庫bgsave自身數據到磁盤
  主庫發送rdb文件到從庫
  從庫開始加載
  加載完畢開始續傳,同時開始提供服務
  很明顯,在這個過程中redis的內存體積越大以上每一個步驟的時間都會被拉長,實際測試的數據如下(我們自認我們的機器性能比較好):

  可以看到,當數據達到20G的時候,一個從庫的恢復時間已經被拉長到了將近20分鐘,如果有10個從庫那么如果依次恢復則共需200分鐘,而如果此時該從庫承擔著大量的讀取請求你能夠忍受這么長的恢復時間嗎?
  看到這里你肯定會問:為什么不能同時重做所有從庫?這是因為所有從庫如果同時向主庫請求rdb文件那么主庫的網卡則立即跑滿從而進入一個無法正常提供服務的狀態,此時主庫又死了,簡直是雪上加霜。
  當然,我們可以批量恢復從庫,例如兩兩一組,那么全部從庫的恢復時間也僅僅從200分鐘降低到了100分鐘,這不是五十步笑百步嗎?
  另一個重要問題在于第四點中的標紅位置,續傳可以理解為一個簡化的mongodb的oplog,它是一個體積固定的內存空間,我們稱之為“同步緩沖區”。
  redis主庫的寫入操作都會在該區域存放一份然后發送給從庫,而如果在上文中1,2,3步耗時太久那么很可能這個同步緩沖區就被重寫,此時從庫無法找到對應的續傳位置它會怎么辦?答案是重做1,2,3步!
  但因為我們無法解決1,2,3步的耗時因此該從庫會永遠的進入惡性循環:不停的向主庫請求完整數據,結果對主庫的網卡造成嚴重影響。
  2 擴容問題
  很多時候會出現流量的突發性增長,通常在找到原因之前我們的應急做法就是擴容了。
  而根據場景一中的表格,一個20G的redis擴容一個從庫需要將近20分鐘,在這個緊急的時刻20分鐘業務能夠容忍嗎?可能還沒擴好就死翹翹了。
  3 網絡不好導致從庫重做最終引發雪崩
  該場景的最大問題是主庫與從庫的同步中斷,而此時很可能從庫仍然在接受寫入請求,那么一旦中斷時間過長同步緩沖區就很可能被復寫。此時從庫上一次的同步位置已丟失,在網絡恢復后雖然主庫沒有發生變化但由于從庫的同步位置丟失了從庫必須進行重做,也就是問題一中的1,2,3,4步。如果此時主庫內存體積過大那么從庫重做速度就會很慢,而發送到從庫的讀請求就會受到嚴重影響,同時由于傳輸的rdb文件的體積過大,主庫的網卡在相當長的一段時間內都會受到嚴重影響。
  4 內存越大,觸發持久化的操作阻塞主線程的時間越長
  Redis是單線程的內存數據庫,在redis需要執行耗時的操作時,會fork一個新進程來做,比如bgsave,bgrewriteaof。 Fork新進程時,雖然可共享的數據內容不需要復制,但會復制之前進程空間的內存頁表,這個復制是主線程來做的,會阻塞所有的讀寫操作,并且隨著內存使用量越大耗時越長。例如:內存20G的redis,bgsave復制內存頁表耗時約為750ms,redis主線程也會因為它阻塞750ms。
  解決辦法
  解決辦法當然就是極力減少內存的使用了,一般情況下,我們都是這么做的:
  1 設置過期時間
  對具有時效性的key設置過期時間,通過redis自身的過期key清理策略來降低過期key對于內存的占用,同時也能夠減少業務的麻煩,不需要定期清理了
  2 不存放垃圾到redis中
  這簡直就是廢話,但是,有跟我們同病相憐的人么?
  3 及時清理無用數據
  例如一個redis承載了3個業務的數據,一段時間后有2個業務下線了,那你就把這兩個業務的相關數據清理了唄
  4 盡量對數據進行壓縮
  例如一些長文本形式的數據,壓縮能夠大幅度降低內存占用
  5 關注內存增長并定位大容量key
  不管是DBA還是開發人員,你用redis,你就必須關注內存,否則,你其實就是不稱職的,這里可以分析redis實例中哪些key比較大從而幫助業務快速定位異常key(非預期增長的key,往往是問題之源)
  6 pika
  如果實在不想搞的那么累,那就把業務遷移到新開源的pika上面,這樣就不用太關注內存了,redis內存太大引發的問題,那也都不是問題了。



查看完整回答
反對 回復 2018-11-16
  • 1 回答
  • 0 關注
  • 988 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號