系統架構設計 程序快取和快取服務,如何抉擇?

2022-06-07 13:09:17 字數 4979 閱讀 3141

我們所說的快取分為程序內部快取(系統內部快取)和 快取服務(如redis/memcache)。計算機服務從原來的單體結構,到多例項,到現在流行的微服務,快取服務變得原來越流行了。  

先說說程序快取,它將資料儲存在站點、服務的程序內。在web的發展歷史上,這樣的方式備受歡迎。比如早期常用的.net的  system.web.caching.

這種實現載體很簡單,比如乙個帶鎖的hastable,或者乙個list物件。 使用簡單便捷,能儲存資料、html頁面片段、檔案,甚至任何物件。

在單體結構的web模式下,程序內快取被開發到極致,大概流程如下圖:

與原先沒有快取相比,程序內快取的好處是,資料讀取不再直接訪問資料庫,先判斷快取中是否存在,如果存在,則直接讀取,不存在則再去資料庫中取,同時寫入快取。

這樣避免了每次的請求都走資料庫,減少網路開銷和資料請求次數,提高了資料獲取效率,基本等同在記憶體中執行。

判斷是否需要建立快取需要一定的依據,以下是我的團隊的策略,不一定適用,可以參考:

快取的必要性:資料的變更是否過於頻繁,過於頻繁則可能導致快取不斷重建,反而降低效率。 評估方式:快取的過期時間內沒被主動更新的量值應該超過60%。

假設同一種型別快取資料基數:6000個

6000 * 60% = 3600 的資料在乙個小時內事務未更新,這樣的快取價值更大。 

在網際網路大潮下,隨著使用者量的激增,原來單體結構逐漸的向web服務集**展,在多例項目標下,程序快取的弊端越來越明顯。

比如快取無法統一的問題。

如果站點和服務中的多個節點訪問統一的快取服務(比如redis 或者 memerche),資料統一儲存,資料的一致性就比較容易保障。

但如果是程序快取,資料儲存在站點和服務的多個節點內,每個節點乙個快取,儲存多份,一致性就比較難保障。 

如上圖,但是有個問題,cache1、cache1、cache3一致性難以保障,如果想保持快取的一致性時,該怎麼辦呢?

一般有以下幾種方法:

1、單一服務節點通知其他服務節點,如果我們只是web service1 在執行業務操作的時候修改資料庫,更新快取,同時通知其他web service

服務,其他web service 接收到資訊的時候,進行快取更新。 

2、 啟動mq通知其他節點:如下圖,可以通過mq通知其他節點。寫請求發生在server1,在修改完自己快取資料與資料庫中的資料之後,給mq生產資料變化通知,

server2和server1訂閱mq訊息,當消費到mq資訊的時候,也修改快取資料。

3、有一種簡單的方式,也可以解耦與web server的關係,就是直接放棄了「實時一致性」,啟動乙個獨立的程序服務,定時從後端拉取最新的資料,更新記憶體快取。

另一方面實際上違背了快取的原則:冷熱資料隔絕,有效的利用冷資料,減輕資料庫壓力,提公升效率。如果快取被頻繁修改或者同步,那快取的價值就不大了。 

補充:1、2 兩種方式,例項越多,快取冗餘越多,各快取節點資料同步的原子性越難保證,一致性也就越難保證。

第3種方式:採用定時拉取本身已經放棄了資料的實時一致性。

所以我們在以下這幾種情況下拋棄程序快取,選用快取服務:

1、web集群下,包含多個例項,並且不允許業務資料的不一致性(我相信大部分業務不允許)

2、程序內快取資料量較大,快取記憶體空間不足,影響web效能,可以考慮走快取服務(快取服務如redis,一般獨立服務甚至集群配置,支援超大量級)。

3、評估value大小、快取記憶體空間、峰值qps、過期時間、快取命中率、讀寫更新策略、key值分布路由策略、過期策略以及資料一致性方案,根據實際需要判斷是否走快取服務。 

在網際網路分層架構中,最常用的kv結構的快取是redis。他有如下特點:

1、它支援複雜資料結構

2、支援持久化

首先,redis的所有資料都是儲存在記憶體中,然後不定期的通過非同步方式儲存到磁碟上(這稱為「半持久化模式」);

但是我們盡量不要把redis當作資料庫用,如果真的需要持久化資料,建議可以走mysql:

2.1、redis的定期快照不能保證資料不丟失

2.2、redis的aof會降低效率,並且不能支援太大的資料量  

3、具備高可用特性

redis天然支援集群功能,可以實現主動複製,讀寫分離。 官方也提供了sentinel集群管理工具,能夠實現主從服務監控,故障自動轉移。 

4、儲存的內容比較大

string型別:乙個string型別的value最大可以儲存512m,list、set、hash型別:list的元素個數最多為2^32-1個,也就是4294967295個。 

5、 支援事務

操作都是原子性,對資料的更改要麼全部執行,要麼全部不執行。避免業務資料的不一致性。

1、web服務 單體模式轉為多例項之後,我們將程序快取公升級為快取服務(redis),清清理了所有的快取使用,都改成了對接redis。但是有一些地方漏掉,因為我們有3個例項,所以漏掉的那幾個地方,一旦修改某個資料之後,一會兒是新值,一會兒舊值,很神奇。

2、謹防快取擊穿、雪崩的產生,這個我們有慘痛的教訓。

我們所說的快取分為程序內部快取(系統內部快取)和 快取服務(如redis/memcache)。計算機服務從原來的單體結構,到多例項,到現在流行的微服務,快取服務變得原來越流行了。  

先說說程序快取,它將資料儲存在站點、服務的程序內。在web的發展歷史上,這樣的方式備受歡迎。比如早期常用的.net的  system.web.caching.

這種實現載體很簡單,比如乙個帶鎖的hastable,或者乙個list物件。 使用簡單便捷,能儲存資料、html頁面片段、檔案,甚至任何物件。

在單體結構的web模式下,程序內快取被開發到極致,大概流程如下圖:

與原先沒有快取相比,程序內快取的好處是,資料讀取不再直接訪問資料庫,先判斷快取中是否存在,如果存在,則直接讀取,不存在則再去資料庫中取,同時寫入快取。

這樣避免了每次的請求都走資料庫,減少網路開銷和資料請求次數,提高了資料獲取效率,基本等同在記憶體中執行。

判斷是否需要建立快取需要一定的依據,以下是我的團隊的策略,不一定適用,可以參考:

快取的必要性:資料的變更是否過於頻繁,過於頻繁則可能導致快取不斷重建,反而降低效率。 評估方式:快取的過期時間內沒被主動更新的量值應該超過60%。

假設同一種型別快取資料基數:6000個

6000 * 60% = 3600 的資料在乙個小時內事務未更新,這樣的快取價值更大。 

在網際網路大潮下,隨著使用者量的激增,原來單體結構逐漸的向web服務集**展,在多例項目標下,程序快取的弊端越來越明顯。

比如快取無法統一的問題。

如果站點和服務中的多個節點訪問統一的快取服務(比如redis 或者 memerche),資料統一儲存,資料的一致性就比較容易保障。

但如果是程序快取,資料儲存在站點和服務的多個節點內,每個節點乙個快取,儲存多份,一致性就比較難保障。 

如上圖,但是有個問題,cache1、cache1、cache3一致性難以保障,如果想保持快取的一致性時,該怎麼辦呢?

一般有以下幾種方法:

1、單一服務節點通知其他服務節點,如果我們只是web service1 在執行業務操作的時候修改資料庫,更新快取,同時通知其他web service

服務,其他web service 接收到資訊的時候,進行快取更新。 

2、 啟動mq通知其他節點:如下圖,可以通過mq通知其他節點。寫請求發生在server1,在修改完自己快取資料與資料庫中的資料之後,給mq生產資料變化通知,

server2和server1訂閱mq訊息,當消費到mq資訊的時候,也修改快取資料。

3、有一種簡單的方式,也可以解耦與web server的關係,就是直接放棄了「實時一致性」,啟動乙個獨立的程序服務,定時從後端拉取最新的資料,更新記憶體快取。

另一方面實際上違背了快取的原則:冷熱資料隔絕,有效的利用冷資料,減輕資料庫壓力,提公升效率。如果快取被頻繁修改或者同步,那快取的價值就不大了。 

補充:1、2 兩種方式,例項越多,快取冗餘越多,各快取節點資料同步的原子性越難保證,一致性也就越難保證。

第3種方式:採用定時拉取本身已經放棄了資料的實時一致性。

所以我們在以下這幾種情況下拋棄程序快取,選用快取服務:

1、web集群下,包含多個例項,並且不允許業務資料的不一致性(我相信大部分業務不允許)

2、程序內快取資料量較大,快取記憶體空間不足,影響web效能,可以考慮走快取服務(快取服務如redis,一般獨立服務甚至集群配置,支援超大量級)。

3、評估value大小、快取記憶體空間、峰值qps、過期時間、快取命中率、讀寫更新策略、key值分布路由策略、過期策略以及資料一致性方案,根據實際需要判斷是否走快取服務。 

在網際網路分層架構中,最常用的kv結構的快取是redis。他有如下特點:

1、它支援複雜資料結構

2、支援持久化

首先,redis的所有資料都是儲存在記憶體中,然後不定期的通過非同步方式儲存到磁碟上(這稱為「半持久化模式」);

但是我們盡量不要把redis當作資料庫用,如果真的需要持久化資料,建議可以走mysql:

2.1、redis的定期快照不能保證資料不丟失

2.2、redis的aof會降低效率,並且不能支援太大的資料量  

3、具備高可用特性

redis天然支援集群功能,可以實現主動複製,讀寫分離。 官方也提供了sentinel集群管理工具,能夠實現主從服務監控,故障自動轉移。 

4、儲存的內容比較大

string型別:乙個string型別的value最大可以儲存512m,list、set、hash型別:list的元素個數最多為2^32-1個,也就是4294967295個。 

5、 支援事務

操作都是原子性,對資料的更改要麼全部執行,要麼全部不執行。避免業務資料的不一致性。

1、web服務 單體模式轉為多例項之後,我們將程序快取公升級為快取服務(redis),清清理了所有的快取使用,都改成了對接redis。但是有一些地方漏掉,因為我們有3個例項,所以漏掉的那幾個地方,一旦修改某個資料之後,一會兒是新值,一會兒舊值,很神奇。

2、謹防快取擊穿、雪崩的產生,這個我們有慘痛的教訓。

快取架構設計

快取架構設計 需求分析 快取是一種提高系統讀效能的常見技術,對於讀多寫少的應用場景,我們經常使用快取來進行優化。例如對於使用者的餘額資訊表account uid,money 業務上的需求是 查詢使用者的餘額,select money from account where uid 佔99 的請求 更改...

快取架構設計

1 快取技術和框架的重要性 網際網路的一些高併發,高效能的專案和系統中,快取技術是起著功不可沒的作用。快取不僅僅是key value的簡單訪問,它在具體的業務場景中,還是很複雜的,需要很強的架構設計能力。我曾經就遇到過因為快取架構設計不到位,導致了系統崩潰的案例。2 快取的技術方案分類 1 是做實時...

架構設計 快取 快取的原理與應用

訪問特點和現實世界的財富分配一樣遵循二八定律 80 的業務訪問集中在20 的資料上。既然大部分的業務訪問集中在一小部分資料上,那麼就可以把這一小部分資料快取在記憶體中,可以減少資料庫的訪問壓力,提高整個 的資料訪問速度,改善資料的寫入效能。在整個 應用中,快取幾乎無處不在,既存在於瀏覽器,也存在於應...