天天看點

什麼技能産品經理不會提,但技術人必須懂?1. What——什麼是緩存?2. Why——為什麼需要使用緩存?3. Where——緩存存在鍊路中的哪些地方?4. When——什麼時候需要使用緩存?

阿裡妹導讀:緩存是搭建高性能高并發系統的必備手段之一,通常用來解決性能瓶頸,是程式員的必備知識點,也是面試必備考點。

盡管,産品經理大機率不會關注系統性能,但程式員在實作需求的時候必須思考系統承載的并發量和使用者量。緩存主要用來解決性能瓶頸的問題,一旦錯誤使用反而會令系統崩潰。今天,我們就通過4W的方式系統化地總結緩存相關的理論知識。

随着網際網路業務的快速疊代以及使用者量激增,應用架構需要不斷調整甚至重構以适應這種業務的快速發展。當資料量迅速增長,業務邏輯越複雜,服務鍊路不斷增加等等一系列問題,會導緻RT過長,服務性能需要逐漸提升以滿足更優的使用者體驗。在優化系統架構時通常的所用的兩種方式scale up以及scale out,scale out就是通常所說的水準擴充,将應用服務設計成無狀态性,可以友善水準擴充通過增加硬體的方式分解通路壓力。而scale up則是将單個服務鍊路性能提升,以提升QPS以及系統的吞吐量。在追求更優的性能時,大多數業務場景是讀多寫少的情況,一般會通過引入緩存的方式解決。

1. What——什麼是緩存?

關于緩存的定義,在wiki中為:

a collection of data duplicating original values stored elsewhere on a computer, usually for easier access.

簡單了解就是儲存在計算機裝置中的一個資料副本,以便于後續能夠進行快速通路。

從定義上可以看出所謂緩存一定是針對已有資料的一個副本存在,也可以看出緩存的使用是為了解決快速通路資料(讀資料)的場景。在現有的網際網路應用中,緩存的使用是一種能夠提升服務快速響應的關鍵技術,也是産品經理無暇顧及的非功能需求,需要在設計技術方案時對業務場景,具有一定的前瞻性評估後,決定在技術架構中是否需要引入緩存解決這種這種非功能需求。

緩存在計算機領域中實際案例存在很多,比如CPU的緩存是為了解決CPU的運算速度和記憶體的讀取資料不平衡的問題,CPU的運算速度遠快與記憶體的讀寫速度,為了降低CPU等待資料讀寫的時間,在CPU中引入L1/L2/L3多級緩存。

再比如Linux中的檔案緩存,實際上我們在程式設計時,會談論到資料的記憶體位址,但是我們接觸的都是虛拟位址而不是真實的實體位址,計算機中的記憶體管理單元(MMU)和頁表會将虛拟位址轉換成實體位址。在計算機硬體領域中就已有很多關于緩存的應用案例,實際上在軟體架構中關于緩存的設計會借鑒于很多傳統且成熟的計算機硬體緩存設計的思想。

2. Why——為什麼需要使用緩存?

軟體服務能夠得到使用者的信賴,并将産品的價值帶給使用者,能夠解決目标使用者的痛點問題這是決定使用者會不會一開始決定使用,也就是《增長黑客》中提到了産品能夠帶來給使用者“啊哈時刻”,而決定使用者會不會高頻使用以及持續使用,使用者體驗則是被認為是軟體産品提升使用者黏性的關鍵影響因素。

2.1 什麼是使用者體驗

使用者體驗被專業定義和推廣需要推廣到20世紀90年代,由Donald Norman布道推廣。使用者體驗在人機互動領域上受到了重視,并一度和傳統的三大可用性名額(即效率、效益以及基本滿意度)不相上下。

ISO 9241-210标準将使用者體驗官方定義為:人們對正在使用或者期待使用的産品、系統或者服務的認知印象和回應。可以看出使用者體驗是使用者的對軟體産品的主觀感受,具體包含了使用者在使用之前、使用中以及使用後的情感、喜好、認知印象、心理反應以及情緒表達等等多種主觀感受,每個使用者對産品的主觀感受的視角不同,關注點不同,也就導緻軟體産品讓大多數使用者都能夠獲得很好的使用者體驗本身就是一件很有挑戰性的事情。

在業界大多數,将使用者體驗分為三類:使用者狀态、軟體産品的系統性能以及環境,使用者狀态以及環境(使用者環境以及産品在同類産品中的産品大環境)這兩個因素需要互動設計和用研等多個專業領域同學去攻克,軟體開發者則需要解決系統性能的問題。對使用者而言,最基本的需求就是在使用軟體服務時,軟體産品提供服務内容的及時性,也就是通常所說的在使用過程中持續的Loading(轉菊花)一定會導緻使用者體驗很差,内容的及時性也是系統性能的最低要求。

而系統性能的問題,是産品經理無暇顧及的點,也是非功能性需求,需要開發者去花心思去思考的地方。評估系統性能的名額有很多,在以提升使用者體驗為前提的情況下,我們需要着重關注的性能名額有哪些呢?

2.2 常見的性能名額

在設計軟體架構時需要關注的幾個常見名額:響應時間、延遲時間、吞吐量、并發使用者數和資源使用率。

1)系統響應時間 :響應時間是指系統對使用者請求做出響應的時間,不同的功能的鍊路長短不同,并且同一功能在不同資料量等這些情況都會導緻響應時間的不同。是以,在衡量系統響應時間時,通常會關注軟體産品所有功能的平均響應時間以及最大響應時間。

2)延遲時間 :在讨論系統響應時間時,更細粒度的劃分可以劃分為:

用戶端在接受資料進行渲染的内容“呈現時間”;

服務端在接受使用者請求發送至服務端以及服務端将資料傳回到用戶端這兩個過程中涉及到的:網絡傳輸時間以及應用延遲時間。應用延遲時間即是服務端在執行整個服務鍊路時所花費的時間,也是性能優化首要降低的就是這個時間。

3)吞吐量 :吞吐量指的是機關時間内能夠處理請求的數量,對于無并發的應用來說,吞吐量和請求響應時間成反比,服務延遲更長則系統吞吐量更低。

4)并發使用者數 :并發使用者數指的是系統能夠同時承載正常使用系統功能的使用者數,相較于吞吐量,這個名額更為籠統但是對于非軟體領域的人來說更容易了解。

5)資源使用率 :資源使用率反映的是在一段時間内資源被占用的情況。

2.3 緩存帶來的優勢

在追求更優的優化體驗時,客觀的來說需要不斷提升以上這些性能名額,不斷逼近系統體驗的最優解。緩存到底具有什麼樣的優勢,值得我們花費很大的精力去設計一套能很好的适應現在的業務場景的緩存結構呢?

1)極大的提升軟體使用者體驗

軟體産品主要圍繞兩個核心問題,一是解決目标使用者的痛點問題,二是提升産品黏性。在提供軟體服務時,抽象的來看是解決資料在整個鍊路上的流轉問題,如何讓資料流轉更加高效、更加順暢是在實作時着重關注的地方,事實上,無論是浏覽器、負載均衡、應用伺服器還是資料庫等等各個環節都會應用到緩存,當資料離使用者“更近”,比如資料副本在用戶端上,也就意味着請求能夠很快的進行響應,相應的給使用者進行資料呈現的耗時就更短。現如今使用者爸爸們“日理萬機”,如果一個軟體産品不能在很短時間就擷取使用者的注意力,很大可能性就意味着失敗。是以,使用緩存能夠讓使用者從主觀上擷取更優的使用者體驗。

2)提升吞吐量

試想,如果在服務鍊路上,請求能夠在緩存中擷取服務資料的話,也就意味着很多資料并不需要從源應用伺服器進行擷取,降低了源伺服器網絡傳輸的頻率,在一定IDC帶寬下,系統能夠降低網絡傳輸時間以及應用延遲時間,進而支撐更多的系統通路以提升系統整體吞吐量以及并發使用者數,硬體的使用效率也會明顯提升。

從實際場景下,在系統性能優化時大機率會優先選擇使用緩存進行系統優化,也是一種被證明有效的手段,緩存也被認為是一種“空間換時間”的藝術。

3. Where——緩存存在鍊路中的哪些地方?

3.1 緩存分類

從一個請求到最終擷取響應,會經過很多環節,緩存可以幾乎存在整個鍊路的每個節點。緩存按照不同的次元可以有如下分類:

1)緩存所處鍊路節點的位置:

用戶端緩存

網絡緩存

服務端緩存

2)緩存架構部署方式:

單機緩存

緩存叢集

分布式緩存

3)緩存的記憶體區域

本地緩存/程序内緩存

程序間緩存

遠端緩存

按照緩存在服務鍊路上的位置來劃分,可以系統性的梳理下緩存的不同應用。

3.2 用戶端緩存

用戶端緩存是離使用者“最近”的一種存儲媒體,經常和網絡測和服務端緩存一起配合使用,常見的用戶端緩存有如下幾種:

1)頁面緩存:頁面緩存是指将靜态頁面擷取頁面中的部分元素緩存到本地,以便下次請求不需要重複資源檔案,h5很好的支援的離線緩存的功能,具體實作可通過頁面指定manifest檔案,當浏覽器通路一個帶有manifest屬性的檔案時,會先從應用緩存中擷取加載頁面的資源檔案,并通過檢查機制處理緩存更新的問題。

2)浏覽器緩存:浏覽器緩存通常會專門開辟記憶體空間以存儲資源副本,當使用者後退或者傳回上一步操作時可以通過浏覽器緩存快速的擷取資料,在HTTP 1.1中通過引入e-tag标簽并結合expire、cache-control兩個特性能夠很好的支援浏覽器緩存,關于浏覽器緩存更為細節的知識可以檢視該文章。

3)APP緩存:APP可以将内容緩存到記憶體或者本地資料庫中,例如在一些開源的圖檔庫中都具備緩存的技術特性,當圖檔等資源檔案從遠端伺服器擷取後會進行緩存,以便下一次不再進行重複請求,并可以減少使用者的流量費用。

用戶端緩存是前端性能優化的一個重要方向,畢竟用戶端是距離“使用者”最近的地方,是一個可以充分挖掘優化潛力的地方。

3.3 網絡緩存

網絡緩存位于用戶端以及服務端中間,通過通過代理的方式解決資料請求的響應,降低資料請求的回源率。通常具有如下幾種形式的網路緩存:

1)web代理緩存:常見的代理形式分為分為:正向代理、反向代理以及透明代理。web代理緩存通常是指正向代理,會将資源檔案和熱點資料放在代理伺服器上,當新的請求到來時,如果在代理伺服器上能擷取資料,則不需要重複請求到應用伺服器上;

2)邊緣緩存:和正向代理一樣,反向代理同樣可以用于緩存,例如nginx就提供了緩存的功能。進一步,如果這些反向代理伺服器能夠做到和使用者請求來自同一個網絡,那麼擷取資源的速度進一步提升,這類的反向代理伺服器可以稱之為邊緣緩存。常見的邊緣緩存就是CDN(Content Delivery Network),可以将圖檔等靜态資源檔案放到CDN上。

**3.4 服務端緩存

**

服務端緩存是後端開發中進行性能優化的發力點,常見的後端性能優化也是通過引入緩存來進行解決,常見的有資料庫的查詢緩存、緩存架構以及引入應用級緩存。

3.4.1 資料庫查詢緩存

例如,MySQL的緩存機制是通過将SELECT語句以及相應的ResultSet進行緩存,當後續接受到SELECT請求後,如果MySQL已經開啟了Query Cache功能,會将SELECT語句以字元串的方式進行hash,然後去從緩存中進行查詢,如果查詢出資料,則直接進行傳回,省去了後續的優化器以及存儲引擎IO的操作,能夠極大的提升響應時效。如何優化Query Cache需要從如下幾個名額上進行考慮:

query_cache_size:設定能夠緩存ResultSet的記憶體區域大小

query_cache_type:表示使用緩存的場景。0表示任何場景下都不使用Query Cache,1表示顯式指定不使用Query Cache的查詢都可以使用,2(DEMAND)表示隻有明确訓示使用Query Cache才會生效;

Qcache hits:表示多少次查詢命中Query Cache

Qcache inserts:表示多少次沒有命中Query Cache而插入資料

Qcahce lowmem prunes:表示多少條Query引入空間不足而被清除

Qcache free memory:表示剩餘記憶體大小

Qcache free blocks:該值很大表示記憶體碎片很多,需要及時清理

在進行Qcache優化時,可以對以上名額綜合進行分析,比如了解Qcache的緩存命中率 = Qcache hits/ Qcache hits + Qcache inserts,來判斷目前Qcache的效率。也可以結合Qcahce lowmem prunes、Qcache free memory以及Qcache free blocks來判斷目前Qcache的記憶體使用效率。

另外,如果使用Innodb存儲引擎的話,也需要着重關注innodb_buffer_pool_size參數,該參數決定了innodb的索引以及資料是否有足夠大的空間放入到緩存中。table_cache決定了能夠緩存表的最大數量,也是需要關注的一個參數。

3.4.2 緩存架構

在功能開發時,會常用提供緩存特性的緩存架構或者實作緩存功能的類庫來高效的完成開發,常見的緩存架構有Ehcache、Guava等,這些緩存架構配置簡單,能夠簡單靈活的使用。這些開源的緩存架構不僅支援單機的本地緩存還能配置叢集的方式達到靈活伸縮。

3.4.3 應用級緩存

當緩存架構不能滿足需求的時候,就需要引入應用級緩存,比如Redis、MongoDB等NoSQL資料庫,應用級緩存具備高可用性以及伸縮性的分布式架構能夠支撐業務需求,當然,做好一款應用級緩存産品其中的挑戰也是巨大。

4. When——什麼時候需要使用緩存?

緩存不是架構設計的必選項,也不是業務開發中的必要功能點,隻有在業務出現性能瓶頸,進行優化性能的時候才需要考慮使用緩存來提升系統性能。也不是所有的業務場景都适合使用緩存,讀多寫少且資料時效要求越低的場景越适合使用緩存,緩存并不是所有性能問題的靈丹妙藥,如果濫用緩存反而會成為毒藥,并且會引入維護緩存的操作成本,使得系統複雜度更高不利于維護。

另外把緩存當做存儲來使用是一件極其緻命的做法,這種錯誤的認識,将緩存引入系統的那一刻起就意味着已經讓系統走上了危險的局面,對緩存的使用邊界要有深刻的了解,才能盡可能保證做出引入緩存才是一個正确的決定。

在進行緩存結構設計的時候,需要考慮的點有很多:

1)業務流量量級以及應用規模:對于低并發低流量的應用而言,引入緩存并不會帶來性能的顯著提升,反而會帶來應用的複雜度以及極高的運維成本。也不是任何資料都需要使用緩存,比如圖檔視訊等檔案使用分布式檔案系統更合适而不是緩存。是以,在引入緩存前,需要對目前業務的流量進行評估,在高并發大流量的業務場景中引入緩存相對而言收益會更高;

2)緩存應用的選擇:緩存應用有很多如Redis、Memcached以及tair等等,針對每一種分布式緩存應用的優缺點以及适用範圍、記憶體效率、運維成本甚至團隊開發人員的知識結構都需要了解,才能做好技術選型;

3)緩存影響因素的正确評估:在引入緩存前,需要着重評估value大小、緩存記憶體空間、峰值QPS、過期時間、緩存命中率、讀寫更新政策、key值分布路由政策、過期政策以及資料一緻性方案等等多個因素,要做到心中有數;

4)緩存高可用架構:分布式緩存要高可用,這也是分布式系統追求的三高名額中的一個,緩存的叢集設計,主從同步方案的設計等等,隻有緩存足夠可靠,才能服務于業務系統,為業務帶來價值;

5)完善的監控平台:當緩存投入生産環境後,需要有一套監控系統能夠顯式的觀測緩存系統的運作情況,才能更早的發現問題,同時對于預估不足的非預期熱點資料,也需要熱點發現系統去解決非預期的熱點資料緩存問題。

6)緩存最近原則:将緩存資料放在離使用者最近的地方,無疑會極大的提升響應的速度,這也是多級緩存設計的核心思想。