1. 程式人生 > 實用技巧 >Redis 優化最佳實踐!

Redis 優化最佳實踐!

點選上方“民工哥技術之路”,選擇“設為星標”

回覆“1024”獲取獨家整理的學習資料!

這篇文章我們就來總結一下,在使用Redis時的最佳實踐方式,主要包含兩個層面:業務層面、運維層面。

由於我之前寫過很多UGC後端服務,在大量場景下用到了Redis,這個過程中也踩過很多坑,所以在使用過程中也總結了一套合理的使用方法。

後來做基礎架構,開發Codis、Redis相關的中介軟體,在這個階段關注領域從使用層面下沉到Redis的開發和運維,更多聚焦在Redis的內部實現和運維過程中產生的各種問題,在這塊也積累了一些經驗。

下面就針對這兩塊,分享一下我認為比較合理的Redis使用和運維方法,不一定最全面,也可能與你使用Redis的方法不同,但以下這些方法都是我在踩坑之後總結的實際經驗,供你參考。關注公眾號Java技術棧回覆redis獲取系列Redis教程。

業務層面主要是開發人員需要關注,也就是開發人員在寫業務程式碼時,如何合理地使用Redis。開發人員需要對Redis有基本的瞭解,才能在合適的業務場景使用Redis,從而避免業務層面導致的延遲問題。

在開發過程中,業務層面的優化建議如下:

  • key的長度儘量要短,在資料量非常大時,過長的key名會佔用更多的記憶體

  • 一定避免儲存過大的資料(大value),過大的資料在分配記憶體和釋放記憶體時耗時嚴重,會阻塞主執行緒

  • Redis 4.0以上建議開啟lazy-free機制,釋放大value時非同步操作,不阻塞主執行緒

  • 建議設定過期時間,把Redis當做快取使用,尤其在數量很大的時,不設定過期時間會導致記憶體的無限增長

  • 不使用複雜度過高的命令,例如SORT、SINTER、SINTERSTORE、ZUNIONSTORE、ZINTERSTORE,使用這些命令耗時較久,會阻塞主執行緒

  • 查詢資料時,一次儘量獲取較少的資料,在不確定容器元素個數的情況下,避免使用LRANGE key 0 -1,ZRANGE key 0 -1這類操作,應該設定具體查詢的元素個數,推薦一次查詢100個以下元素

  • 寫入資料時,一次儘量寫入較少的資料,例如HSET key value1 value2 value3...,-控制一次寫入元素的數量,推薦在100以下,大資料量分多個批次寫入

  • 批量操作資料時,用MGET/MSET替換GET/SET、HMGET/MHSET替換HGET/HSET,減少請求來回的網路IO次數,降低延遲,對於沒有批量操作的命令,推薦使用pipeline,一次性發送多個命令到服務端

  • 禁止使用KEYS命令,需要掃描例項時,建議使用SCAN,線上操作一定要控制掃描的頻率,避免對Redis產生效能抖動

  • 避免某個時間點集中過期大量的key,集中過期時推薦增加一個隨機時間,把過期時間打散,降低集中過期key時Redis的壓力,避免阻塞主執行緒

  • 根據業務場景,選擇合適的淘汰策略,通常隨機過期要比LRU過期淘汰資料更快

  • 使用連線池訪問Redis,並配置合理的連線池引數,避免短連線,TCP三次握手和四次揮手的耗時也很高

  • 只使用db0,不推薦使用多個db,使用多個db會增加Redis的負擔,每次訪問不同的db都需要執行SELECT命令,如果業務線不同,建議拆分多個例項,還能提高單個例項的效能

  • 讀的請求量很大時,推薦使用讀寫分離,前提是可以容忍從節資料更新不及時的問題

  • 寫請求量很大時,推薦使用叢集,部署多個例項分攤寫壓力

運維層面

目的是合理規劃Redis的部署和保障Redis的穩定執行,主要優化如下:

  • 不同業務線部署不同的例項,各自獨立,避免混用,推薦不同業務線使用不同的機器,根據業務重要程度劃分不同的分組來部署,避免某一個業務線出現問題影響其他業務線

  • 保證機器有足夠的CPU、記憶體、頻寬、磁碟資源,防止負載過高影響Redis效能

  • 以master-slave叢集方式部署例項,並分佈在不同機器上,避免單點,slave必須設定為readonly

  • master和slave節點所在機器,各自獨立,不要交叉部署例項,通常備份工作會在slave上做,做備份時會消耗機器資源,交叉部署會影響到master的效能

  • 推薦部署哨兵節點增加可用性,節點數量至少3個,並分佈在不同機器上,實現故障自動故障轉移

  • 提前做好容量規劃,一臺機器部署例項的記憶體上限,最好是機器記憶體的一半,主從全量同步時會佔用最多額外一倍的記憶體空間,防止網路大面積故障引發所有master-slave的全量同步導致機器記憶體被吃光

  • 做好機器的CPU、記憶體、頻寬、磁碟監控,在資源不足時及時報警處理,Redis使用Swap後效能急劇下降,網路頻寬負載過高訪問延遲明顯增大,磁碟IO過高時開啟AOF會拖慢Redis的效能

  • 設定最大連線數上限,防止過多的客戶端連線導致服務負載過高

  • 單個例項的使用記憶體建議控制在20G以下,過大的例項會導致備份時間久、資源消耗多,主從全量同步資料時間阻塞時間更長

  • 設定合理的slowlog閾值,推薦10毫秒,並對其進行監控,產生過多的慢日誌需要及時報警 設定合理的複製緩衝區repl-backlog大小,適當調大repl-backlog可以降低主從全量複製的概率

  • 設定合理的slave節點client-output-buffer-limit大小,對於寫入量很大的例項,適當調大可以避免主從複製中斷問題

  • 備份時推薦在slave節點上做,不影響master效能

  • 不開啟AOF或開啟AOF配置為每秒刷盤,避免磁碟IO消耗降低Redis效能

  • 當例項設定了記憶體上限,需要調大記憶體上限時,先調整slave再調整master,否則會導致主從節點資料不一致

  • 對Redis增加監控,監控採集info資訊時,使用長連線,頻繁的短連線也會影響Redis效能,redis效能監控指標,參考這個文章

  • 線上掃描整個例項數時,記得設定休眠時間,避免掃描時QPS突增對Redis產生效能抖動

  • 做好Redis的執行時監控,尤其是expired_keys、evicted_keys、latest_fork_usec指標,短時間內這些指標值突增可能會阻塞整個例項,引發效能問題

以上就是我在使用Redis和開發Redis相關中介軟體時,總結出來Redis推薦的實踐方法,以上提出的這些方面,都或多或少在實際使用中遇到過。

可見,要想穩定發揮Redis的高效能,需要在各個方面做好工作,但凡某一個方面出現問題,必然會影響到Redis的效能,這對我們使用和運維提出了更高的要求。

如果你在使用Redis過程中,遇到更多的問題或者有更好的使用經驗,可以留言一起探討!

作者:Kaito

出處:kaito-kidd.com/2020/07/04/redis-best-practices/

推薦閱讀點選標題可跳轉

Linux 日誌切割神器 Logrotate 原理和配置詳解(附多生產例項)

寵粉福利:紅包+送書!先到先得

常見網際網路公司職級和薪資一覽!

就是要讓你搞懂Nginx,這篇就夠了!

MySQL 高頻面試題,都在這了

Shell 命令執行視覺化和告警工具

Elasticsearch 最佳實踐!

提升效率!Linux 管理員必用的10個關鍵技巧