一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Redis開發(fā)設(shè)計規(guī)范及案例分析

 xkl135 2018-07-29

redis不是垃圾桶也不是 SUPER MAN,能力和資源都有限,不合理的使用會降低它的健康度,嚴(yán)重時甚至?xí)餽edis抖動、阻塞等進(jìn)而導(dǎo)致服務(wù)不可用,每一個使用redis的開發(fā)人員都應(yīng)當(dāng)掌握規(guī)范的開發(fā)和使用方法。本文整理出redis開發(fā)過程中七個較常出現(xiàn)的使用不合理的場景,并輔以案例進(jìn)行分析說明。



01
合理使用集合類

案例

某活動需求,每天10點對昨天參加某活動的用戶進(jìn)行推送提醒。開發(fā)人員使用redis存儲每天參加活動的用戶,通過ZRANGEBYSCORE命令獲取目標(biāo)用戶進(jìn)行提醒,提醒完后使用ZREMRANGEBYSCORE命令從redis中清除這批用戶。某一天ZRANGEBYSCORE、ZREMRANGEBYSCORE均出現(xiàn)了慢日志報警,排查發(fā)現(xiàn)這一天參加該活動的用戶約有5萬。


 
分析


案例中使用了redis的sortedset來儲存用戶信息,其中value是用戶的賬號、score是用戶參加活動的時間,由于ZRANGEBYSCOREZREMRANGEBYSCORE命令的時間復(fù)雜度是 O(log(N) M),其中M是操作的元素個數(shù),N是集合元素總數(shù),本例中當(dāng)用戶數(shù)量為5萬時出現(xiàn)慢日志??梢酝ㄟ^縮小每次查詢的集合數(shù)量,可以將一天分成多段,分批次查詢,比如把查24小時范圍的用戶改為查4小時范圍的用戶,分別查6次處理即可。


Q

如果用戶參加活動的時間很集中,在某一

時間段比如晚18點到22點查出來

數(shù)量還是特別多怎么辦?

A

可以把粒度分得更細(xì)一些比如1小時或者30分鐘,如果確定用戶參加活動集中某個時間點,可以考慮使用ZSCAN遍歷操作并刪除。另外,對于目標(biāo)時間范圍有確定的首尾元素時,還可以通過ZRANK命令查出元素的位置,通過 ZRANGE ZREMRANGEBYRANK來進(jìn)行查詢和刪除操作,這樣每次操作可以控制操作數(shù)量,有效避免慢日志。



 
小結(jié)


使用 sortedset、set、list、hash等集合類O(N)操作時要評估當(dāng)前元素個數(shù)的規(guī)模以及將來的增長規(guī)模,對于短期就可能變?yōu)榇蠹系膋ey,要預(yù)估O(N)操作的元素數(shù)量,避免全量操作,可以使用HSCANSSCAN、ZSCAN進(jìn)行漸進(jìn)操作。集合元素數(shù)量過大在使用過程中會影響redis的實際性能,元素個數(shù)建議盡量不要超過5000,元素數(shù)量過大可考慮拆分成多個key進(jìn)行處理。



02

合理設(shè)置過期時間

案例1

某投票功能,用于統(tǒng)計今日環(huán)比昨日的增長數(shù)量,開發(fā)人員使用redis存儲每天的投票數(shù),key設(shè)計為vote_count_{date},其中{date}為當(dāng)天的日期,由于沒有設(shè)置過期時間,一年以后產(chǎn)生了360多個key,實際在用的key始終只有2個。


 
分析


該案例中,每個生成的key在2天以后都不會再使用了,可將key加上過期時間。


案例2

某統(tǒng)計功能,用戶會不定期的導(dǎo)入一批數(shù)據(jù)進(jìn) redis,每一批數(shù)據(jù)需要在30分鐘后、1天后、3天后、7天后進(jìn)行計算統(tǒng)計,統(tǒng)計結(jié)果發(fā)給用戶。開發(fā)人員使用redis的同一個sortedset存儲這些導(dǎo)入的數(shù)據(jù),每天定時任務(wù)執(zhí)行計算任務(wù)。由于沒有清理,導(dǎo)致大量結(jié)束計算任務(wù)的廢棄數(shù)據(jù)殘留redis。


 
分析


該案例中,每一批數(shù)據(jù)都有相應(yīng)的生命周期,在導(dǎo)入的第7天執(zhí)行完最后一次計算任務(wù)生命周期結(jié)束,由于集合里的元素不能單獨設(shè)置過期時間,可在代碼邏輯中對最后一次使用這批數(shù)據(jù)后進(jìn)行清理操作。



 
小結(jié)


如果key沒有設(shè)置超時時間,會導(dǎo)致一直占用內(nèi)存。對于可以預(yù)估使用生命周期的key應(yīng)當(dāng)設(shè)置合理的過期時間或在最后一次操作時進(jìn)行清理,避免垃圾數(shù)據(jù)殘留redis。



03

合理利用批操作命令


案例

某運營需求,需要給用戶生成短鏈,短鏈由短鏈前綴 短碼組成,根據(jù)短碼找到用戶對應(yīng)的手機(jī)號,開發(fā)人員使用redis hash結(jié)構(gòu)存儲短碼到手機(jī)號的映射。接口每次會導(dǎo)入5萬個手機(jī)號。


 
分析


下面是開發(fā)人員的三種操作redis方案的偽代碼

方案1直接使用redisHSET逐個設(shè)置

for(50000;)
HSET(key,短碼,手機(jī)號)

結(jié)果:失敗。redis ops飆升,同時接口響應(yīng)超時


方案2:改用redis的 HMSET一次將所有元素設(shè)置到hash中

map<短碼,手機(jī)號> 50000個元素
HMSET(key,map)

結(jié)果:失敗。出現(xiàn)redis慢日志


方案3依然使用 HMSET,只是每次設(shè)置500個,循環(huán)100次

map<短碼,手機(jī)號> 500個元素
for(100;)
HMSET(key,map)

結(jié)果:成功


對于大量頻繁的hset操作可以使用 HMSET替代減少redis操作次數(shù)同時提升處理速度,但是要考慮單次請求操作的數(shù)量,避免慢日志。



 
小結(jié)


在redis使用過程中,要正視網(wǎng)絡(luò)往返時間,合理利用批量操作命令,減少通訊時延和redis訪問頻次。redis為了減少大量小數(shù)據(jù)CMD操作的網(wǎng)絡(luò)通訊時間開銷 RTT (Round Trip Time),支持多種批操作技術(shù):

  • MSET/HMSET等都支持一次輸入多個key,LPUSH/RPUSH/SADD等命令都支持一次輸入多個value,也要注意每次操作數(shù)量不要過多,建議控制在500個以內(nèi);

  • PipeLining 模式 可以一次輸入多個指令。redis提供一個 pipeline 的管道操作模式,將多個指令匯總到隊列中批量執(zhí)行,可以減少tcp交互產(chǎn)生的時間,一般情況下能夠有10%~30%不等的性能提升;

  • 更快的是Lua Script模式,還可以包含邏輯。redis內(nèi)嵌了 lua 解析器,可以執(zhí)行l(wèi)ua 腳本,腳本可以通過eval等命令直接執(zhí)行,也可以使用script load等方式上傳到服務(wù)器端的script cache中重復(fù)使用



04

減少不必要的請求


案例

某業(yè)務(wù)系統(tǒng),當(dāng)用戶進(jìn)入某個頁面時會同時請求多個接口,每個接口都會校驗用戶狀態(tài)是否有效,用戶狀態(tài)存在redis里并設(shè)置有過期時間,對于key未過期但是過期時間大于指定閾值的,需要重新設(shè)置有效時間,否則需要使用del命令刪除掉。但是部分key由于過期其實已經(jīng)不存在了,所以出現(xiàn)部分無效del命令。用戶越多,就會有越多的無效命令。


 
分析


ttl命令對于key不存在的情況會返回-2,若key不存在則不需要再調(diào)用del命令,可減少無效請求。



 
小結(jié)


redis的所有請求對于不存在的key都會有輸出返回,合理利用返回值處理,避免不必要的請求,提升業(yè)務(wù)吞吐量。



05

避免value設(shè)置過大

案例

某開發(fā)人員將一個商品集合信息序列化后用redis的字符串類型存儲,使用的時候再反序列化成對象列表使用,大小超過1MB,在網(wǎng)絡(luò)傳輸?shù)臅r候由于數(shù)據(jù)比較大會觸發(fā)拆包,會降低redis的吞吐量。


 
分析


數(shù)量比較多時可以考慮改用hash結(jié)構(gòu)存儲,每一個field是商品id,value是該商品對象,如果數(shù)量較大可使用hscan獲取。



 
小結(jié)


String類型盡量控制在10KB以內(nèi)。雖然redis對單個key可以緩存的對象長度能夠支持的很大,但是實際使用場合一定要合理拆分過大的緩存項,1k 基本是redis性能的一個拐點。當(dāng)緩存項超過10k、100k、1m性能下降會特別明顯。關(guān)于吞吐量與數(shù)據(jù)大小的關(guān)系可見下面官方網(wǎng)站提供的示意圖。


吞吐量與數(shù)據(jù)大小的關(guān)系


在局域網(wǎng)環(huán)境下只要傳輸?shù)陌怀^一個 MTU(以太網(wǎng)下大約 1500 bytes),那么對于 10、100、1000 bytes不同包大小的處理吞吐能力實際結(jié)果差不多。



06

設(shè)計規(guī)范的key名


 
可讀性

以業(yè)務(wù)名為前綴,用冒號分隔,可使用業(yè)務(wù)名:子業(yè)務(wù)名:id的結(jié)構(gòu)命名,子業(yè)務(wù)下多單詞可再用下劃線分隔

舉例:活動系統(tǒng)-人拉人紅包活動-id,可命名為 ACTIVITY:INVITE_REDPACKET:001



 
簡潔性

保證語義的前提下,控制key的長度,當(dāng)key較多時,內(nèi)存占用也不容忽視



 
不包含轉(zhuǎn)義字符

不包含空格、換行、單雙引號以及其他轉(zhuǎn)義字符



07

留心禁用命令


keys、monitor、flushall、flushdb應(yīng)當(dāng)通過redis的rename機(jī)制禁掉命令,若沒有禁用,開發(fā)人員要謹(jǐn)慎使用。其中flushall、flushdb會清空redis數(shù)據(jù);keys命令可能會引起慢日志;monitor命令在開啟的情況下會降低redis的吞吐量,根據(jù)壓測結(jié)果大概會降低redis50%的吞吐量,越多客戶端開啟該命令,吞吐量下降會越多。


keys和monitor在一些必要的情況下還是有助于排查線上問題的,建議可在重命名后在必要情況下由redis相關(guān)負(fù)責(zé)人員在redis備機(jī)使用,monitor命令可借助redis-faina等腳本工具進(jìn)行輔助分析,能更快排查線上ops飆升等問題。


  總      結(jié)  

本文整理出的幾點redis開發(fā)規(guī)范主要是涉及redis客戶端的使用部分,每個開發(fā)人員在使用redis開發(fā)過程中幾乎都會涉及到上述提到的幾個問題,需要多多留心,提高代碼質(zhì)量,提升redis的健康度。


作者:張家江

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    最近最新中文字幕免费| 丝袜破了有美女肉体免费观看| 超碰在线免费公开中国黄片| 欧美丰满大屁股一区二区三区| 亚洲精品日韩欧美精品| 一区二区三区四区亚洲另类 | 亚洲综合一区二区三区在线| 国产精品推荐在线一区| 国产女性精品一区二区三区| 欧美国产日本免费不卡| 蜜桃av人妻精品一区二区三区| 国产免费一区二区不卡| 欧美日本精品视频在线观看| 亚洲一级在线免费观看| 国产精品视频一级香蕉| 国产成人精品综合久久久看| 日系韩系还是欧美久久| 欧美日韩一区二区午夜| 国产又黄又猛又粗又爽的片| 夜夜嗨激情五月天精品| 日本一本在线免费福利| 久久99国产精品果冻传媒| 日本人妻熟女一区二区三区| 日韩夫妻午夜性生活视频| 亚洲欧美日本国产不卡| 国产日本欧美韩国在线| 99久久精品午夜一区二| 亚洲日本韩国一区二区三区| 午夜国产福利在线播放| 色一情一乱一区二区三区码| 中字幕一区二区三区久久蜜桃| 中文精品人妻一区二区| 国产午夜福利在线免费观看| 台湾综合熟女一区二区| 91人妻人人澡人人人人精品| 日韩欧美第一页在线观看| 午夜小视频成人免费看| 国产午夜福利在线观看精品| 色狠狠一区二区三区香蕉蜜桃| 男人操女人下面国产剧情| 黄色激情视频中文字幕|