Redis開發(fā)最佳實踐
點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”
優(yōu)質(zhì)文章,第一時間送達(dá)
功能概述
緩存在我們?nèi)粘i_發(fā)中占據(jù)著舉足輕重的地位,通過緩存組件可以讓我們的系統(tǒng)有著多方位的提升空間。而Redis就一個代表性的緩存組件。正巧最近使用Redis比較頻繁,所以打算通過文章記錄一下在Redis開發(fā)中遇到的問題和一些開發(fā)規(guī)范
原文已放在Github,將持續(xù)跟版本更新,歡迎star
Key的設(shè)計
易于管理
即能通過名稱大概知道所涉及業(yè)務(wù)。通常我們會以service:characteristics來進(jìn)行命名,如pubg_chat:uid:room_id的形式,這樣可以盡可能避免沖突(當(dāng)然,不同業(yè)務(wù)使用不同的Redis是更好的)
盡量簡潔
Redis本質(zhì)上是一個內(nèi)存數(shù)據(jù)庫,而內(nèi)存的大小是遠(yuǎn)小于硬盤的。如果Key過大的話,會導(dǎo)致Redis所能存儲的內(nèi)容變少。所以在日常中推薦Key能夠盡可能的簡介明了,用縮寫來代替完整的單詞
避免特殊字符
如逗號、換行、空格和引號等轉(zhuǎn)義字符都是不應(yīng)該使用的
設(shè)置生命周期
Redis不應(yīng)當(dāng)成為一個永久存儲的組件,為每一個Key都設(shè)置他的過期時間
如果確實需要Redis永久存儲某類內(nèi)容,那么因當(dāng)采用異步“續(xù)命”的方式來進(jìn)行,而不應(yīng)該在一開始就為其設(shè)置永久的生命周期,避免后續(xù)需要變更時帶來的維護(hù)災(zāi)難
Value的使用
規(guī)避大Key!
Redis單線程的,它會在執(zhí)行完一個命令后才會執(zhí)行其他命令
首先大Key在傳輸鍵值對時,會對網(wǎng)絡(luò)造成壓力(帶寬問題),并且有的proxy會將大內(nèi)容分片傳輸,進(jìn)而再次增加了網(wǎng)絡(luò)傳輸時間
其次,如list、hash這類結(jié)構(gòu),如果使用O(n)的指令或者使用del命令,那么會造成嚴(yán)重的阻塞
所以通常而言,string 類型控制在 10KB 以內(nèi),hash、list、set、zset 元素個數(shù)不要超過 5000
ps:通常可采用hash的方式分割大key
value的壓縮
可考慮使用protobuf、MessagePack等方式進(jìn)行序列化,這樣一可以提升redis的利用率,二提高了序列化的效率,三是能提供value跨語言的能力
命令使用
避免頻繁對string做append
可以考慮使用list進(jìn)行替代
集合類操作
O(n)指令應(yīng)注意。對于set,zset,list,hash等集合類,應(yīng)注意O(n)命令對于性能的影響。通常應(yīng)該避免直接使用O(n)指令,可用HSCAN,SSCAN,ZSCAN進(jìn)行漸進(jìn)操作,防止命令的阻塞
漸進(jìn)式刪除。不應(yīng)該直接使用del,而應(yīng)該自己寫腳本一點點的刪除
禁用危險命令
keys、flushall、flushdb…這種不用多說,一來直接Redis就懵圈了,人也楞了
合理利用Pipeline模式
在mget大量數(shù)據(jù)時,proxy會拆包和解包,會導(dǎo)致proxy層的壓力增加,而pipeline模式會直接轉(zhuǎn)發(fā)。所以在批量獲取的情況下,pipeline的效率一般都會優(yōu)于mget
同時應(yīng)該注意兩點:
(1) mget是原子操作,pipeline不是。所以業(yè)務(wù)上不可盲目采用
(2) pipeline是可以發(fā)送不同命令的,當(dāng)然使用lua也可以實現(xiàn)這一點
避免不必要的指令
如部分Redis Client會有TestOnBorrow之類的探測指令,在沒有特殊要求的情況下應(yīng)當(dāng)避免此類指令,以減小redis負(fù)載和網(wǎng)絡(luò)壓力
對Lua應(yīng)當(dāng)做特殊要求
所有key都應(yīng)該由KEYS數(shù)組來傳遞
所有value都應(yīng)該由ARGS數(shù)組來傳遞
所有key,必須在1個slot上
性能查詢指令
slowlog get,查詢慢命令
info commandstats,查詢執(zhí)行過的命令信息,包含用時和次數(shù)等
client list,查詢引起阻塞的命令
客戶端使用
避免混用實例
不同的業(yè)務(wù)線應(yīng)該做到實例的拆分,避免混用導(dǎo)致的連鎖問題:如key重合、命令阻塞等
使用連接池
每次使用都新建連接會有幾個問題:
造成redis的負(fù)擔(dān)增加
浪費網(wǎng)絡(luò)資源
影響執(zhí)行效率
難以維護(hù)
熔斷
Redis本質(zhì)也是一個“服務(wù)”,所以熔斷機制不可少
鑒權(quán)
避免無關(guān)服務(wù)的濫用或?qū)е聰?shù)據(jù)出錯
避免作為消息隊列
Redis其實還能夠支持消息隊列的應(yīng)用,但其讀寫效率是不及其他MQ如Kafka、RabbitMQ等。且由于其結(jié)構(gòu)的設(shè)置,不太能夠支撐MQ的一些主要特性,所以應(yīng)當(dāng)避免使用。
其他
淘汰策略
根據(jù)??業(yè)務(wù)類型,選好maxmemory-policy(最?內(nèi)存淘汰策略),設(shè)置好過期時間
默認(rèn)策略是volatile-lru,即超過最?內(nèi)存后,在過期鍵中使?lru算法進(jìn)?key的剔除,保證不過期數(shù)據(jù)不被 刪除,但是可能會出現(xiàn)OOM問題
allkeys-lru:根據(jù)LRU算法刪除鍵,不管數(shù)據(jù)有沒有設(shè)置超時屬性,直到騰出?夠空間為?
allkeys-random:隨機刪除所有鍵,直到騰出?夠空間為?。
volatile-random:隨機刪除過期鍵,直到騰出?夠空間為?
volatile-ttl:根據(jù)鍵值對象的ttl屬性,刪除最近將要過期數(shù)據(jù)。如果沒有,回退到noeviction策略
noeviction:不會剔除任何數(shù)據(jù),拒絕所有寫?操作并返回客?端錯誤信息"(error) OOM command not allowed when used memory",此時Redis只響應(yīng)讀操作
不濫用Redis事務(wù)
Redis事務(wù)不像DB的事務(wù)這么“安全”,也不支持回滾,所以不應(yīng)當(dāng)過多的使用。因為這塊我沒怎么使用過,詳見官方文檔
————————————————
版權(quán)聲明:本文為CSDN博主「路遙遙丶」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:
https://blog.csdn.net/a417484830/article/details/103642689
鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布
??????
??長按上方微信二維碼 2 秒
感謝點贊支持下哈 
