緩存命中率的介紹
命中:可以直接通過緩存獲取到需要的數(shù)據(jù)。
不命中:無法直接通過緩存獲取到想要的數(shù)據(jù),需要再次查詢數(shù)據(jù)庫或者執(zhí)行其它的操作。原因可能是由于緩存中根本不存在,或者緩存已經(jīng)過期。
通常來講,緩存的命中率越高則表示使用緩存的收益越高,應(yīng)用的性能越好(響應(yīng)時(shí)間越短、吞吐量越高),抗并發(fā)的能力越強(qiáng)。
由此可見,在高并發(fā)的互聯(lián)網(wǎng)系統(tǒng)中,緩存的命中率是至關(guān)重要的指標(biāo)。
如何監(jiān)控緩存的命中率
在memcached中,運(yùn)行state命令可以查看memcached服務(wù)的狀態(tài)信息,其中cmd_get表示總的get次數(shù),get_hits表示get的總命中次數(shù),命中率 = get_hits/cmd_get。
當(dāng)然,我們也可以通過一些開源的第三方工具對整個(gè)memcached集群進(jìn)行監(jiān)控,顯示會(huì)更直觀。比較典型的包括:zabbix、MemAdmin等。
如圖:MemAdmin對memcached服務(wù)的命中率情況的監(jiān)控統(tǒng)計(jì)
同理,在redis中可以運(yùn)行info命令查看redis服務(wù)的狀態(tài)信息,其中keyspace_hits為總的命中中次數(shù),keyspace_misses為總的miss次數(shù),命中率=keyspace_hits/(keyspace_hits+keyspace_misses)。
開源工具Redis-star能以圖表方式直觀redis服務(wù)相關(guān)信息,同時(shí),zabbix也提供了相關(guān)的插件對redis服務(wù)進(jìn)行監(jiān)控。
影響緩存命中率的幾個(gè)因素
之前的章節(jié)中我們提到了緩存命中率的重要性,下面分析下影響緩存命中率的幾個(gè)因素。
業(yè)務(wù)場景和業(yè)務(wù)需求
緩存適合ldquo;讀多寫少rdquo;的業(yè)務(wù)場景,反之,使用緩存的意義其實(shí)并不大,命中率會(huì)很低。
業(yè)務(wù)需求決定了對時(shí)效性的要求,直接影響到緩存的過期時(shí)間和更新策略。時(shí)效性要求越低,就越適合緩存。在相同key和相同請求數(shù)的情況下,緩存時(shí)間越長,命中率會(huì)越高。
互聯(lián)網(wǎng)應(yīng)用的大多數(shù)業(yè)務(wù)場景下都是很適合使用緩存的。
緩存的設(shè)計(jì)(粒度和策略)
通常情況下,緩存的粒度越小,命中率會(huì)越高。舉個(gè)實(shí)際的例子說明:
當(dāng)緩存單個(gè)對象的時(shí)候(例如:單個(gè)用戶信息),只有當(dāng)該對象對應(yīng)的數(shù)據(jù)發(fā)生變化時(shí),我們才需要更新緩存或者讓移除緩存。而當(dāng)緩存一個(gè)集合的時(shí)候(例如:所有用戶數(shù)據(jù)),其中任何一個(gè)對象對應(yīng)的數(shù)據(jù)發(fā)生變化時(shí),都需要更新或移除緩存。
還有另一種情況,假設(shè)其他地方也需要獲取該對象對應(yīng)的數(shù)據(jù)時(shí)(比如其他地方也需要獲取單個(gè)用戶信息),如果緩存的是單個(gè)對象,則可以直接命中緩存,反之,則無法直接命中。這樣更加靈活,緩存命中率會(huì)更高。
此外,緩存的更新/過期策略也直接影響到緩存的命中率。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),直接更新緩存的值會(huì)比移除緩存(或者讓緩存過期)的命中率更高,當(dāng)然,系統(tǒng)復(fù)雜度也會(huì)更高。
緩存容量和基礎(chǔ)設(shè)施
緩存的容量有限,則容易引起緩存失效和被淘汰(目前多數(shù)的緩存框架或中間件都采用了LRU算法)。同時(shí),緩存的技術(shù)選型也是至關(guān)重要的,比如采用應(yīng)用內(nèi)置的本地緩存就比較容易出現(xiàn)單機(jī)瓶頸,而采用分布式緩存則畢竟容易擴(kuò)展。所以需要做好系統(tǒng)容量規(guī)劃,并考慮是否可擴(kuò)展。此外,不同的緩存框架或中間件,其效率和穩(wěn)定性也是存在差異的。
其他因素
當(dāng)緩存節(jié)點(diǎn)發(fā)生故障時(shí),需要避免緩存失效并最大程度降低影響,這種特殊情況也是架構(gòu)師需要考慮的。業(yè)內(nèi)比較典型的做法就是通過一致性Hash算法,或者通過節(jié)點(diǎn)冗余的方式。
有些朋友可能會(huì)有這樣的理解誤區(qū):既然業(yè)務(wù)需求對數(shù)據(jù)時(shí)效性要求很高,而緩存時(shí)間又會(huì)影響到緩存命中率,那么系統(tǒng)就別使用緩存了。其實(shí)這忽略了一個(gè)重要因素--并發(fā)。通常來講,在相同緩存時(shí)間和key的情況下,并發(fā)越高,緩存的收益會(huì)越高,即便緩存時(shí)間很短。
提高緩存命中率的方法
從架構(gòu)師的角度,需要應(yīng)用盡可能的通過緩存直接獲取數(shù)據(jù),并避免緩存失效。這也是比較考驗(yàn)架構(gòu)師能力的,需要在業(yè)務(wù)需求,緩存粒度,緩存策略,技術(shù)選型等各個(gè)方面去通盤考慮并做權(quán)衡。盡可能的聚焦在高頻訪問且時(shí)效性要求不高的熱點(diǎn)業(yè)務(wù)上,通過緩存預(yù)加載(預(yù)熱)、增加存儲(chǔ)容量、調(diào)整緩存粒度、更新緩存等手段來提高命中率。
對于時(shí)效性很高(或緩存空間有限),內(nèi)容跨度很大(或訪問很隨機(jī)),并且訪問量不高的應(yīng)用來說緩存命中率可能長期很低,可能預(yù)熱后的緩存還沒來得被訪問就已經(jīng)過期了。
您可能感興趣的文章:- Redis緩存穿透出現(xiàn)原因及解決方案
- java操作Redis緩存設(shè)置過期時(shí)間的方法
- SpringBoot2整合Redis緩存三步驟代碼詳解
- Spring Cache手動(dòng)清理Redis緩存
- SpringBoot redis分布式緩存實(shí)現(xiàn)過程解析
- mybatis plus使用redis作為二級(jí)緩存的方法
- window手動(dòng)操作清理redis緩存的技巧總結(jié)
- Redis緩存常用4種策略原理詳解