Redis被廣泛使用的一個很重要的原因是它的高性能。因此我們必要要重視所有可能影響Redis性能的因素、機制以及應對方案。影響Redis性能的五大方面的潛在因素,分別是:
這一講,我們來學習一下Redis緩沖區的相關知識。
緩沖區的功能是用一塊內存來暫存命令數據,避免出現因為數據和命令的處理速度慢於發送速度而導致的數據丟失和性能問題。但緩沖區的內存空間有限,如果發生溢出,就會丟失數據。
Redis緩沖區有兩個應用場景:
- 在客戶端和服務器端之間進行通信時,用來暫存客戶端發送的命令數據,或者是服務器端返回給客戶端的數據結果;
- 主從節點間進行數據同步時,用來暫存主節點接收的寫命令和數據。
客戶端輸入和輸出緩沖區
如何應對輸入緩沖區溢出
可能導致溢出的情況有兩種:寫入了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配置項設置合理的輸出緩沖區、復制緩沖區和復制積壓緩沖區大小。