Redis性能篇(三)Redis關鍵系統配置:如何應對Redis變慢

Redis被普遍使用的一個很重要的緣由是它的高性能。所以咱們必要要重視全部可能影響Redis性能的因素、機制以及應對方案。影響Redis性能的五大方面的潛在因素,分別是:html

在前面的2講中,學習了會致使Redis變慢的潛在阻塞點以及相應的解決方案,即異步線程機制和CPU綁核。除此以外,還有一些因素會致使Redis變慢。redis

這一講,介紹如何系統性應對Redis變慢這個問題。從問題認定、系統性排查和應對方案這3個方面來說解。服務器

判斷Redis是否變慢?

最直接的方法,查看Redis的響應延遲。經過絕對值來判斷,好比執行時間忽然增加到幾秒。網絡

可是這個方法在不一樣配置的機器上的偏差比較大。第二個方法是基於當前環境下的Redis基線性能作判斷。架構

基線性能指一個系統在低壓力、無干擾下的基本性能。app

怎麼肯定基線性能?從2.8.7版本開始,redis-cli命令提供了-intrinsic-latency選項,能夠用來監測和統計測試期間內的最大延遲,這個延遲能夠做爲Redis的基線性能。其中,測試時長能夠用-intrinsic-latency選項的參數來指定。異步

通常來講,運行時延和基線性能對比,若是運行時延是基線性能的2倍及以上時,就能夠認定Redis變慢了。爲了不網絡對基線性能的影響,直接在服務器端運行。工具

如何應對Redis變慢?

影響Redis的關鍵因素有三個:Redis自身的操做特性、文件系統和操做系統。性能

Redis自身操做特性的影響

Redis有兩個操做會對性能形成較大影響,分別是慢查詢命令和過時key操做。學習

慢查詢命令

慢查詢命令,就是指在Redis中執行速度慢的命令,這會致使Redis延遲增長。

排查:經過Redis日誌、或者是latency monitor工具。

解決方法

  • 用其餘高效命令代替。好比不要使用SMEMBERS命令,而是用SSCAN屢次迭代返回;
  • 當須要執行排序、交集、並集操做時,能夠在客戶端完成,而不要用SORT、SUNION、SINTER這些命令

還有一個比較容易遺漏的慢查詢命令是KEYS命令,它用於返回和輸入模式的全部key。由於KEYS命令須要遍歷存儲的鍵值對,因此操做延時高。KEYS命令通常不被建議用於生產環境中

過時key操做

過時key的自動刪除機制,它是Redis用來回收內存空間的經常使用機制,自己會引發Redis操做阻塞,致使性能變慢。

排查:檢查業務代碼在使用EXPIREAT命令設置key過時時間時,是否使用了相同的UNIX時間戳。由於這會形成大量key在同一時間過時,致使性能變慢。

解決方法

  • 根據實際業務需求來決定EXPIREAT和EXPIRE的過時時間參數。
  • 若是一批key的確是同時過時,能夠在EXPIREAT和EXPIRE的過時時間參數上,加上一個必定大小範圍內的隨機參數

文件系統的影響

在基礎篇講過,爲了保證數據可靠性,Redis會採用AOF日誌或者RDB快照。其中,AOF日誌提供了三種日誌寫回策略:no、everysec、always。這三種寫回策略依賴文件系統的兩個系統調用完成:write和fsync。

  • write只要把日誌記錄寫到內核緩衝區便可;
  • fsync須要把日誌記錄寫回磁盤,時間較長。

image

排查

  • 首先,檢查Redis配置文件中的appendfsync配置項;
  • 其次,確認業務對數據可靠性的要求是否須要每一秒或每個操做都記日誌。

解決方法

若是業務應用對延遲很是敏感,但同時容許必定量的數據丟失,把配置項no-appendfsync-on-rewrite設置爲yes:

no-appendfsync-on-rewrite yes

若是的確須要高性能,同時也須要高可靠數據保證,考慮採用高速的固態硬盤做爲AOF日誌的寫入設備。

操做系統的影響

swap

一個潛在的瓶頸:操做系統的內存swap。

內存swap是操做系統裏將內存數據在內存和磁盤間來回換入和換出的機制,涉及到磁盤的讀寫。

Redis一旦swap被觸發,Redis的請求操做須要等到磁盤數據讀寫完成。而且swap觸發後影響的是Redis主IO線程,這會極大地增長Redis的響應時間。

一般觸發swap的緣由主要是物理機器內存不足

排查

首先,查找Redis的進程號:

$ redis-cli info | grep process_id process_id: 5332

其次,進入Redis所在機器的/proc目錄下的該進程目錄中:

$ cd /proc/5332

最後,運行下面命令,查看Redis進程的使用狀況:

$cat smaps | egrep '^(Swap|Size)'
Size: 584 kB
Swap: 0 kB
Size: 4 kB
Swap: 4 kB
Size: 4 kB
Swap: 0 kB
Size: 462044 kB
Swap: 462008 kB
Size: 21392 kB
Swap: 0 kB

解決方法:增長機器的內存或者使用Redis集羣。

內存大頁

還有一個和內存相關的因素,即內存大頁機制(Transparent Huge Page,THP),也會影響Redis性能。

排查

首先,在Redis實例運行的機器上執行:

cat /sys/kernel/mm/transparent_hugepage/enabled

若是,執行結果是always,表示內存大頁機制啓動了;若是是never,表示禁止了。

解決方法:關閉內存大頁。

echo never /sys/kernel/mm/transparent_hugepage/enabled

總結

總結一份關於Redis變慢的Checklist:

  1. 獲取Redis實例在當前環境下的基線性能。
  2. 是否用了慢查詢命令?若是是的話,就使用其餘命令替代慢查詢命令,或者把聚合計算命令放在客戶端作。
  3. 是否對過時key設置了相同的過時時間?對於批量刪除的key,能夠在每一個key的過時時間上加一個隨機數,避免同時刪除。
  4. 是否存在bigkey? 對於bigkey的刪除操做,若是你的Redis是4.0及以上的版本,能夠直接利用異步線程機制減小主線程阻塞;若是是Redis 4.0之前的版本,可使用SCAN命令迭代刪除;對於bigkey的集合查詢和聚合操做,可使用SCAN命令在客戶端完成。
  5. Redis AOF配置級別是什麼?業務層面是否的確須要這一可靠性級別?若是咱們須要高性能,同時也容許數據丟失,能夠將配置項no-appendfsync-on-rewrite設置爲yes,避免AOF重寫和fsync競爭磁盤IO資源,致使Redis延遲增長。固然, 若是既須要高性能又須要高可靠性,最好使用高速固態盤做爲AOF日誌的寫入盤。
  6. Redis實例的內存使用是否過大?發生swap了嗎?若是是的話,就增長機器內存,或者是使用Redis集羣,分攤單機Redis的鍵值對數量和內存壓力。同時,要避免出現Redis和其餘內存需求大的應用共享機器的狀況。
  7. 在Redis實例的運行環境中,是否啓用了透明大頁機制?若是是的話,直接關閉內存大頁機制就好了。
  8. 是否運行了Redis主從集羣?若是是的話,把主庫實例的數據量大小控制在2~4GB,以避免主從複製時,從庫因加載大的RDB文件而阻塞。
  9. 是否使用了多核CPU或NUMA架構的機器運行Redis實例?使用多核CPU時,能夠給Redis實例綁定物理核;使用NUMA架構時,注意把Redis實例和網絡中斷處理程序運行在同一個CPU Socket上。

參考資料

相關文章
相關標籤/搜索