這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何確保redis只緩存熱點(diǎn)數(shù)據(jù),文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
成都創(chuàng)新互聯(lián)公司2013年開創(chuàng)至今,先為城中等服務(wù)建站,城中等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為城中企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
緩存雪崩簡單說就是所有請求都從緩存中拿不到數(shù)據(jù),比如大批量數(shù)據(jù)同一時間過期。對于大批量數(shù)據(jù)同時過期的場景,可以為數(shù)據(jù)設(shè)置過期時間指定一個時間范圍內(nèi)的隨機(jī)值,比如一天到一天零一小時之間的隨機(jī)值,但不適用于集合類型,比如hash。
還有小數(shù)場景,比如高峰流量導(dǎo)致Redis集群崩潰;未配置持久化的redis無從節(jié)點(diǎn)Cluster集群重啟、集群遷移。當(dāng)Redis集群發(fā)生故障時,可先啟用內(nèi)存緩存方案,比如Ehcache,同時根據(jù)情況做限流與降級,最后快速重啟集群,必須配置持久化策略,根據(jù)流量情況擴(kuò)展集群。
緩存穿透簡單理解就是數(shù)據(jù)庫中也沒有對應(yīng)的記錄,永遠(yuǎn)都不會命中緩存。比如表中的記錄只有id從1000到100000,請求查詢id為10000000的記錄。一般是惡意攻擊,針對這種情況最好的處理方式就是判斷id的有效范圍,其它情況可以針對查詢的key緩存一個null值,并設(shè)置ttl過期時間。
適用于對實(shí)時性要求不高的業(yè)務(wù)場景;適用于可以容忍獲取到的是過期數(shù)據(jù)的業(yè)務(wù)場景。過期時間會在每次讀寫key時刷新。為確保緩存中不遺留垃圾數(shù)據(jù),一般都會為key設(shè)置過期時間,除了那些不會改變且一直會用到,也不會更新的數(shù)據(jù),比如筆者前幾篇文章提到的IP庫。
選擇淘汰最近最少使用的緩存淘汰策略可以保證緩存中都是熱點(diǎn)數(shù)據(jù),但這個策略只會在內(nèi)存吃緊的情況下起效果,一般要保證緩存的數(shù)據(jù)都是熱點(diǎn)數(shù)據(jù)就是在redis內(nèi)存不夠用的情況下。建議及時做緩存數(shù)據(jù)清理,依靠緩存淘汰策略的時候性能也會有所下降。
比如用Sorted Set緩存key的讀次數(shù),周期性的去刪除訪問次數(shù)小于多少的key。適用于hash等集合類型,計(jì)錄field的讀次數(shù),缺點(diǎn)是每次請求都有統(tǒng)計(jì)次數(shù)的性能開銷。
適用于那種比較少改動的緩存記錄,比如用戶信息;適用于要求數(shù)據(jù)修改及時更新緩存的業(yè)務(wù)場景,如一些配置的修改要求及時生效。但不適用于要求非常實(shí)時的場景,比如商品庫存。
這種方法與前一種方法都可利用AOP方式去更新,區(qū)別在于,前者解決多個服務(wù)之間的耦合問題,用于跨服務(wù)數(shù)據(jù)更新。小公司為考慮成本問題不會為每個服務(wù)使用獨(dú)立的Redis集群,后者只能用于單個服務(wù)內(nèi)的數(shù)據(jù)更新。即便是多個微服務(wù)使用同一個Redis集群,也不要通過共用key的方式共享緩存,否則耦合性太大,容易出問題。
配合ttl使用,ttl的時間設(shè)置比定時任務(wù)周期長一點(diǎn),避免數(shù)據(jù)過期了新的任務(wù)還沒執(zhí)行完成。適用于實(shí)時性要求不是很高,且短時間內(nèi)大量數(shù)據(jù)更新的業(yè)務(wù)場景。比如數(shù)據(jù)庫有10w數(shù)據(jù),每15分鐘都會有百分七八十的數(shù)據(jù)變更,且變更時間只在一分鐘內(nèi)。
如果是集合類型、Hash類型,一般會配合Rename使用,只有所有數(shù)據(jù)寫入到redis成功,才原子性替換舊數(shù)據(jù)。且數(shù)據(jù)量大的情況下使用pipeline批量寫入,避免使用hmset這類批量操作。使用hash這類集合類型時,一定要考慮到臟數(shù)據(jù)的問題。
Cluster分槽會導(dǎo)致緩存數(shù)據(jù)傾斜,從而導(dǎo)致請求傾斜。假設(shè)一個三個小主從的Cluster集群,平均分配槽位,大量的key落到第二個節(jié)點(diǎn)上,導(dǎo)致請求都偏向第二個節(jié)點(diǎn)。導(dǎo)致這個問題的主要原因是,大量key為hash、set、sorted sort類型,且每個集合數(shù)據(jù)量都比較大。其次是HashTag的不合理使用。
解決方案,一是將大hash分段存儲,二是減少HashTag的使用,三是重新分配槽位,將第二個節(jié)點(diǎn)的槽位根據(jù)實(shí)際情況分配一些給其它兩個節(jié)點(diǎn)。
拿我最熟悉的廣告行業(yè),舉幾個簡單例子。
使用hash、bitmap都可實(shí)現(xiàn)。bitmap適用于判斷true or false的業(yè)務(wù)需求。bitmap的讀寫速度都優(yōu)于hash,且內(nèi)存占用少。但出于其它需求,我選擇hash。bitmap用于其它業(yè)務(wù)需求,如快速判斷offer每日展示數(shù)是否達(dá)到上限。
簡單的key-value以及hash都支持incr自增,且操作原子性。為減少緩存中key的數(shù)據(jù),我選擇hash,同時也因?yàn)閔ash支持hgetall,用于實(shí)時統(tǒng)計(jì)以及方便問題排查。
Capacity,即容量,如根據(jù)國家、城市、渠道、廣告主等標(biāo)簽限制廣告的展示次數(shù),一個廣告可能同時會匹配到多個標(biāo)簽,當(dāng)達(dá)到最小Capacity時,即判定為true。通過Sorted Set存儲一個廣告匹配的所有標(biāo)簽,根據(jù)當(dāng)前展示次數(shù)通過zcount獲取匹配的標(biāo)簽總數(shù),判斷zcount結(jié)果是否大于零即可。
如用于過濾短時間內(nèi)重復(fù)點(diǎn)擊廣告的用戶,只是舉個例子。這時就可以利用HyperLogLog存儲IP,HyperLogLog會過濾重復(fù)數(shù)據(jù),準(zhǔn)確率有誤差,但對業(yè)務(wù)影響甚微。
上述就是小編為大家分享的如何確保Redis只緩存熱點(diǎn)數(shù)據(jù)了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。