享學課堂特邀作者:老顧

前言

「這個商品不錯,大家來看啊「,每個平臺都有會有些大賣的商品,簡稱為爆品。這些商品會有個特點,就是訪問量特別大。我們專業上面可以稱之為熱點數據,在處理這些熱點商品時,系統需要做一些特殊的處理

緩存化

針對熱點商品這些類型的數據,要考慮到訪問量比較大,大家首先想到的是緩存,上redis緩存,這點肯定沒有錯。系統框架如下:

上圖中,先從緩存中獲取,沒有再到DB獲取,並保存到緩存中。但有個問題會產生,熱點數據的訪問會比較大,如果緩存一旦失效,所有請求同一時刻,會打到DB上面,DB肯定會崩潰。那怎麼辦呢?

分散式鎖

緩存一旦失效,如何重新構建緩存?首先需要避免失效那一刻大量請求同時去重新構建緩存。因為重新構建緩存,需要到資料庫DB中獲取數據,那一個時刻的所有請求到DB上面。方案有兩種,第一個方案是把請求進入隊列中(這個老顧以後會介紹,關於庫存一致性的問題中,有涉及到這個知識點)。還有一個方案就比較簡單,利用分散式鎖,只允許一個請求線程去訪問DB,其他請求阻塞,這樣就避免了很多請求打到DB上。

具體怎麼實現可以看老顧之前的文章【如何利用鎖,防止緩存擊穿?重構思想的重要性

永不過期

這個方案就是利用redis本身的特性,導致的問題是因為緩存失效了,那我們可以讓緩存永不過期就行了。這個方案中需要考慮兩個情況:

1、熱點商品上線前需要預熱,也就是在商品正式發布到前端時,需要提前把商品信息進行緩存,避免跟緩存失效的情況一樣。 2、更新商品信息機制,如何在商品信息更新後,及時更新緩存中的商品信息。這個也比較簡單在更新商品事件中,增加個更新消息,由緩存服務進行消費,更新緩存信息。

遺留問題

上面兩個方案是網上經常提到的方案,其實這兩個方案會存在一個問題,也就是redis達到了負載極限怎麼辦?也就是熱點商品的訪問量,我們的單臺redis扛不住了

小夥伴們會有疑問,redis可以上集羣啊,不就解決了嗎?

我們先了解一下,redis cluster集羣部署方案

上圖是redis經典的三主三從集羣方案,客戶端進行set和get時,都是走的主redis,從redis只是個備份,主要作用是用來做高可用的,如:主redis掛了,從redis頂上

備註:老顧這裡介紹的是redis集羣部署方案,如果是之前的redis主從方案,另外討論

從redis是不負責set和get請求的,即使請求打到從redis節點,從redis也會轉發給主redis。而其他的主redis,是用來做數據擴容的。

即就是商品A的信息,只會存在一個主redis中,其他主redis是沒有此商品A的信息的,這就是redis集羣哈希槽的特點。

也就是小夥伴剛纔想到的做redis集羣這個方案是不行的,因為熱點數據只會在一個主redis中。會存在單臺redis負載不足(達到網卡、網路上限。達到這個瓶頸流量代表非常大了)。那怎麼辦呢?

讀寫分離

上面我們提到從redis只不負責讀和寫請求的,但redis官方提供了一個方法,在操作讀請求時,可以先加上readonly命令,這樣從redis就可以提供讀請求服務了,不需要轉發到主redis。

根據這個特性,我們可以對客戶端工具進行改造,讀請求方法時,加上readonly這個命令,從而實現讀寫分離,提高了從redis的利用率。

即達到了多臺從redis去扛大量請求了,減少了主redis壓力。這個方案需要對客戶端進行改造,而且redis官方推薦沒有必要使用讀寫分離。

本地緩存

這個方案就是多級緩存的方案,把緩存前置,架構圖如下:

改造web應用服務,在獲取到redis緩存後,在web服務本地把熱點的數據進行緩存,因為熱點的商品不會很多,所以保存在本地緩存中,是沒有問題的。這樣請求數據時,如果web本地有緩存數據,就直接返回了。

這樣前端3個web應用就分擔了redis緩存的壓力,如訪問過大就可以增加web應用服務,本來web應用服務就需要集羣化

熱點發現

本地緩存的方案中,有一個問題需要解決,那就是怎麼知道哪些數據是熱點數據?因為本地緩存資源有限,不可能把所有的商品數據進行緩存,它只會緩存熱點的數據。那怎麼知道數據是熱點數據呢?

人為預測

就是人工標記,預測這個商品會成為熱點,打個標記。web應用根據這個標記把此商品保存到本地緩存中

這個方案,是根據運營人員的經驗進行預測,太不靠譜了。

系統推算

這個方案是根據實實在在的數據訪問量進行推算形成,網上也介紹了用訪問日誌的什麼演算法,推算哪些是熱點數據。 老顧這裡分享一個比較簡單的方式,就是利用redis4.x自身特性,LFU機制發現熱點數據。實現很簡單,只要把redis內存淘汰機制設置為allkeys-lfu或者volatile-lfu方式,再執行

./redis-cli --hotkeys

會返回訪問頻率高的key,並從高到底的排序

那就是我們的熱點數據的key了。

備註:在設置key時,需要把商品id帶上,這樣就是知道是哪些商品了

總結

到此為止,老顧就把熱點數據的問題、解決方案以及熱點發現介紹完了,希望能夠幫助小夥伴。當然整個解決方案的搭建,還需要小夥伴結合自身業務去實現。

如果小夥伴們部署到阿里雲上面,阿里雲上面也有類似方案

謝謝大家閱讀!!!

推薦閱讀

你知道怎麼在生產環境下部署tomcat嗎?Java開發多年經驗分享,關於線程數存在的誤區!大型網站演變中的負載均衡場景分析

最後

以後還會更新更多精選的文章分享給大家,大家可以點贊關注下,歡迎大家在評論區留言!

同時我們還提供了許多Java架構進階的學習資料,有需要的朋友可以點開石墨文檔,關注公眾號:享學課堂online 即可免費獲取!

Java進階必備學習資源免費獲取(視頻+面試文檔+學習筆記)?

shimo.im


推薦閱讀:
相關文章