命中:可以直接透過快取取得到所需的資料。
不命中:無法直接透過快取取得到想要的數據,需要再次查詢資料庫或執行其它的操作。原因可能是由於快取中根本不存在,或者快取已經過期。
通常來講,快取的命中率越高則表示使用快取的收益越高,應用的效能越好(回應時間越短、吞吐量越高),抗並發的能力越強。
由此可見,在高並發的網路系統中,快取的命中率是至關重要的指標。
在memcached中,執行state指令可以查看memcached服務的狀態信息,其中cmd_get表示總的get次數,get_hits表示get的總命中次數,命中速率= get_hits/cmd_get。
當然,我們也可以透過一些開源的第三方工具對整個memcached叢集進行監控,顯示會更直覺。比較典型的包括:zabbix、MemAdmin等。
如圖:MemAdmin對memcached服務的命中率情況的監控統計
同理,在redis中可以運行info指令查看redis服務的狀態訊息,其中keyspace_hits為總的命中中次數,keyspace_misses為總的miss次數,命中率=keyspace_hits/(keyspace_hits keyspace_misses)。
開源工具Redis-star能以圖表方式直觀redis服務相關訊息,同時,zabbix也提供了相關的插件對redis服務進行監控。
之前的章節中我們提到了快取命中率的重要性,以下分析下影響快取命中率的幾個因素。
快取適合“讀多寫少”的業務場景,反之,使用快取的意義其實並不大,命中率會很低。
業務需求決定了對時效性的要求,直接影響到快取的過期時間和更新策略。時效性要求越低,就越適合快取。在相同key和相同請求數的情況下,快取時間越長,命中率會越高。
網路應用程式的大多數業務場景下都是很適合使用快取的。
通常情況下,快取的粒度越小,命中率會越高。舉個實際的例子說明:
當快取單一物件的時候(例如:單一使用者資訊),只有當該物件對應的資料發生變化時,我們才需要更新快取或讓移除快取。而當快取一個集合的時候(例如:所有使用者資料),其中任何一個物件對應的資料發生變化時,都需要更新或移除快取。
還有另一種情況,假設其他地方也需要取得該對象對應的資料時(例如其他地方也需要取得單一使用者資訊),如果快取的是單一對象,則可以直接命中緩存,反之,則無法直接命中。這樣比較靈活,快取命中率會更高。
此外,快取的更新/過期策略也直接影響到快取的命中率。當資料變更時,直接更新快取的值會比移除快取(或讓快取過期)的命中率更高,當然,系統複雜度也會更高。
快取的容量有限,則容易造成快取失效和被淘汰(目前多數的快取框架或中間件都採用了LRU演算法)。同時,快取的技術選型也是至關重要的,例如採用應用程式內建的本機快取就比較容易出現單機瓶頸,而採用分散式快取則畢竟容易擴充。所以需要做好系統容量規劃,並考慮是否可擴充。此外,不同的快取框架或中間件,其效率和穩定性也是存在差異的。
當快取節點發生故障時,需要避免快取失效並最大程度降低影響,這種特殊情況也是架構師需要考慮的。業界比較典型的做法就是透過一致性Hash演算法,或是透過節點冗餘的方式。
有些朋友可能會有這樣的理解迷思:既然業務需求對資料時效性要求很高,而快取時間又會影響到快取命中率,那麼系統就別使用緩存了。其實這忽略了一個重要因素--並發。通常來講,在相同快取時間和key的情況下,並發越高,快取的收益會越高,即便快取時間很短。
從架構師的角度,需要應用盡可能的透過快取直接取得數據,並避免快取失效。這也是比較考驗架構師能力的,需要在業務需求,快取粒度,快取策略,技術選用等各方面去通盤考慮並做權衡。盡可能的聚焦在高頻存取且時效性要求不高的熱點業務上,透過快取預載(預熱)、增加儲存容量、調整快取粒度、更新快取等手段來提高命中率。
對於時效性很高(或快取空間有限),內容跨度很大(或訪問很隨機),並且訪問量不高的應用來說緩存命中率可能長期很低,可能預熱後的快取還沒來得被存取就已經過期了。
更多Redis相關技術文章,請造訪Redis教學欄位學習!
以上是怎麼提高redis快取命中率的詳細內容。更多資訊請關注PHP中文網其他相關文章!