Redis性能篇(五)Redis緩衝區

Redis被廣泛使用的一個很重要的原因是它的高性能。因此我們必要要重視所有可能影響Redis性能的因素、機制以及應對方案。影響Redis性能的五大方面的潛在因素,分別是:

這一講,我們來學習一下Redis緩衝區的相關知識。

緩衝區的功能是用一塊內存來暫存命令數據,避免出現因為數據和命令的處理速度慢於發送速度而導致的數據丟失和性能問題。但緩衝區的內存空間有限,如果發生溢出,就會丟失數據。

Redis緩衝區有兩個應用場景:

  • 在客戶端和服務器端之間進行通信時,用來暫存客戶端發送的命令數據,或者是服務器端返回給客戶端的數據結果;
  • 主從節點間進行數據同步時,用來暫存主節點接收的寫命令和數據。

客戶端輸入和輸出緩衝區

image

如何應對輸入緩衝區溢出

可能導致溢出的情況有兩種:寫入了bigkey服務器端處理請求的速度過慢

如何查看輸入緩衝區的內存使用情況使用CLIENT LIST命令

CLIENT LIST id=5 addr=127.0.0.1:50487 fd=9 name= age=4 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=26 qbuf-free=32742 obl=0 oll=0 omem=0 events=r cmd=client

  • cmd,表示客戶端最新執行的命令;
  • qbuf,表示輸入緩衝區已經使用的大小;
  • qbuf-free,表示輸入緩衝區尚未使用的大小;

客戶端輸入緩衝區大小=qubf+qbuf-free。

如何避免輸入緩衝區溢出:一是把緩衝區調大;二是從數據命令的發送和處理速度入手。

首先,輸入緩衝區不能通過參數調整,在代碼里設置客戶端輸入緩衝區大小上限閾值為1GB。

其次,避免客戶端寫入bigkey。

如何應對輸出緩衝區溢出

可能導致溢出的情況有三種:

  • 服務器端返回bigkey的大量結果;
  • 執行了MONITOR命令;
  • 緩衝區大小設置得不合理。

首先,避免bigkey操作返回大量數據結果,可以使用SCAN命令。

其次,避免在線上環境中持續使用MONITOR命令。。MONITOR命令是用來監測Redis執行的。執行後,會持續輸出監測到各個命令操作。MONITOR的輸出結果會持續佔用輸出緩衝區,越占越大,最後發生溢出。MONITOR命令主要用在調試環境中,不要在線上生產環境中持續使用MONITOR

最後,使用client-output-buffer-limit設置合理的緩衝區大小上限,或是緩衝區連續寫入時間和寫入量上限

  • 設置緩衝區大小的上限閾值;
  • 設置輸出緩衝區持續寫入數據的數量上限閾值,和持續寫入數據的時間的上限閾值。

按照客戶端類型不同,設置也不同:

  • 普通客戶端:client-output-buffer-limit normal 0 0 0。通常把普通客戶端的緩衝區大小限制,以及持續寫入量限制、持續寫入時間限制都設置為0,也就是不做限制;
  • 訂閱客戶端:client-output-buffer-limit pubsub 8mb 2mb 60
  • 從節點客戶端:在介紹主從集群中的緩衝區時再具體說明。

主從集群中的緩衝區

主從集群間的數據複製包括全量複製和增量複製。無論哪種複製,都會用到緩衝區。

複製緩衝區的溢出問題

全量複製時,從節點接收和加載RDB慢,同時主節點接收到大量的寫命令,複製緩衝區越積越多,最後導致溢出。一旦發生溢出,主節點會關閉從節點的連接,導致全量複製失敗。

如何避免複製緩衝區發生溢出

首先,控制主節點保存的數據量大小,通常控制在2~4GB

其次,通過client-output-buffer-limit配置項來設置合理的複製緩衝區大小

config set client-output-buffer-limit slave 512mb 128mb 60

在實際應用中設置複製緩衝區的大小時,可以根據寫命令數據的大小和應用的實際負載情況來估計緩衝區中累積的寫命令數據量。然後再和所設置的複製緩衝區大小進行比較,判斷設置的緩衝區大小是否足夠支撐累積的寫命令數據量。

關於複製緩衝區的問題,因為複製緩衝區是在主節點上的,如果集群中的從節點非常多,主節點的內存開銷就會非常大。所以,必須得控制和主節點連接的從節點個數

複製積壓緩衝區的溢出問題

增量複製時使用的緩衝區稱為複製積壓緩衝區。在基礎篇第6講中已經學過複製積壓緩衝區了,叫repl_backlog_buffer

首先,複製積壓緩衝區是一個大小有限的環形緩衝區。當寫入速度比讀取速度要快,會導致溢出。主節點會關閉和從節點的連接,要重新進行同步。

為了應對複製積壓緩衝區的溢出問題,可以調用複製積壓緩衝區的大小,通過設置repl_backlog_size這個參數值。

總結

按緩衝區的用途分為:

  • 客戶端的輸入和輸出緩衝區;
  • 主從集群中主節點上的複製緩衝區和複製積壓緩衝區。

從緩衝區溢出對Redis的影響分類:

  • 緩衝區溢出導致網絡連接關閉;
  • 緩衝區溢出導致命令數據丟失。

緩衝區溢出的原因及解決方案:

  • 命令數據發送過快過大。普通客戶端避免使用bigkey,複製緩衝區避免過大的RDB文件;
  • 命令數據處理較慢。減少Redis主線程上的阻塞操作,例如使用異步的刪除操作;
  • 緩衝區空間過小。使用clinet-output-buffer-limit配置項設置合理的輸出緩衝區、複製緩衝區和複製積壓緩衝區大小。

參考資料