億級流量的商品詳情頁架構分析

對於每天上億流量,擁有上億頁面的大型電商網站來說,能夠支撐高併發訪問,同時能夠秒級讓最新模板生效的商品詳情頁系統的架構是如何設計的?接下來咱們就剖析一下這些電商網站的商品詳情頁的整體架構。

那就按照商品詳情頁的架構演化過程來進行一一的說明:

架構1.0:大概2012年的時候,某大型電商網站還在用spring mvc的模板渲染(freemarker等)方式,動態生成商品詳情頁面。某些數據也進行了緩存。隨著流量的激增,性能逐漸出現了很大的問題。

架構2.0:niginx+java的全量靜態化頁面方式:

優點很明顯,性能得到了很大的增加。對於一些中小型電商網站,已經滿足了需求。但是對於大型電商網站,缺點也是有的,主要以下兩點:1)如果頁面規模很大,幾億級別,niginx的資源明顯不夠用。2)如果頁面模板修改了,那所有的頁面都得重新靜態化一遍,那是不切實際的。

架構3.0:2014年採用了異步多級緩存架構+nginx本地化緩存+動態模板渲染的架構

主要思路是通過多級緩存來實現。首先大量請求來的時候,80%的請求通過nginx本地的緩存數據進行模板渲染後,直接返回了html。剩下的20%中的80%(16%)通過redis中的緩存數據進行模板渲染。最後4%的數據中大部分走緩存數據服務的本地緩存,只有很少量的請求會直接打到數據庫。這樣就大大提高了頁面的性能,也減少了數據庫的壓力。當然這樣的架構優點是明顯的,缺點就是架構複雜,會涉及到很多複雜的問題,需要一一去想辦法解決。說點題外話,世上任何東西都具有兩面性,沒有一個是隻有優點沒缺點的,做架構設計也是如此,得懂得有舍有得。

這個架構設計到幾個主要的技術點:

1)nignx的本地緩存(HttpLuaModule模塊的shared_dict)的使用和lua腳本的模板渲染。Lua中也有許多模板引擎,如目前的lua-resty-templat。

2)redis集群的使用。

3)nignx的緩存容量有限,要考慮多臺nignx的路由策略。每臺nginx不可能都放相同的商品模板,所以可以用商品的id進行hash路由。

4)畢竟緩存空間是有限的,所有的緩存(三級緩存)要考慮失效策略。比如LRU。

5)三級緩存隨著緩存級別,容量是逐漸減少的,一級緩存(nignx緩存)容量最小也就200M左右,所以不可能上億的商品頁面都放到一級緩存,需要考慮一些什麼樣的商品數據存入一級緩存。比如秒殺的商品可以放入一級緩存。二級緩存的存放規則可以參考二八原則,也就是80%的請求只訪問20%的商品。所以將熱點商品數據存放如二級緩存即可。當然這個也不是固定不變的,假如當某個事件導致某個冷數據商品突然變成爆款,也是需要動態推送到一級緩存的。這個可以設定一個訪問請求上限,達到上限後可以自動推送至一級緩存。