原创精华:剖析亿级请求下的多级缓存
什么是多級緩存
所謂多級緩存,即在整個系統架構的不同系統層級進行數據緩存,以提升訪問效率,這也是應用最廣的方案之一。我們應用的整體架構如圖1所示:
圖1 多級緩存方案
整體流程如上圖所示:
1)首先接入Nginx將請求負載均衡到應用Nginx,此處常用的負載均衡算法是輪詢或者一致性哈希,輪詢可以使服務器的請求更加均衡,而一致性哈希可以提升應用Nginx的緩存命中率,相對于輪詢,一致性哈希會存在單機熱點問題,一種解決辦法是熱點直接推送到接入層Nginx,一種辦法是設置一個閥值,當超過閥值,改為輪詢算法。
2)接著應用Nginx讀取本地緩存(本地緩存可以使用Lua Shared Dict、Nginx Proxy Cache(磁盤/內存)、Local Redis實現),如果本地緩存命中則直接返回,使用應用Nginx本地緩存可以提升整體的吞吐量,降低后端的壓力,尤其應對熱點問題非常有效。
3)如果Nginx本地緩存沒命中,則會讀取相應的分布式緩存(如Redis緩存,另外可以考慮使用主從架構來提升性能和吞吐量),如果分布式緩存命中則直接返回相應數據(并回寫到Nginx本地緩存)。
4)如果分布式緩存也沒有命中,則會回源到Tomcat集群,在回源到Tomcat集群時也可以使用輪詢和一致性哈希作為負載均衡算法。
5)在Tomcat應用中,首先讀取本地堆緩存,如果有則直接返回(并會寫到主Redis集群),為什么要加一層本地堆緩存將在緩存崩潰與快速修復部分細聊。
6)作為可選部分,如果步驟4沒有命中可以再嘗試一次讀主Redis集群操作。目的是防止當從有問題時的流量沖擊。
7)如果所有緩存都沒有命中只能查詢DB或相關服務獲取相關數據并返回。
8)步驟7返回的數據異步寫到主Redis集群,此處可能多個Tomcat實例同時寫主Redis集群,可能造成數據錯亂,如何解決該問題將在更新緩存與原子性部分細聊。
應用整體分了三部分緩存:應用Nginx本地緩存、分布式緩存、Tomcat堆緩存,每一層緩存都用來解決相關的問題,如應用Nginx本地緩存用來解決熱點緩存問題,分布式緩存用來減少訪問回源率、Tomcat堆緩存用于防止相關緩存失效/崩潰之后的沖擊。
雖然就是加緩存,但是怎么加,怎么用細想下來還是有很多問題需要權衡和考量的,接下來部分我們就詳細來討論一些緩存相關的問題。
如何緩存數據
接下來部將從緩存過期、維度化緩存、增量緩存、大Value緩存、熱點緩存幾個方面來詳細介紹如何緩存數據。
過期與不過期
對于緩存的數據我們可以考慮不過期緩存和帶過期時間緩存,什么場景應該選擇哪種模式需要根據業務和數據量等因素來決定。
不過期緩存
場景一般思路如圖2所示:
圖2不過期緩存方案
使用Cache-Aside模式,首先寫數據庫,如果成功,則寫緩存。這種場景下存在事務成功、緩存寫失敗但無法回滾事務的情況。另外,不要把寫緩存放在事務中,尤其寫分布式緩存,因為網絡抖動可能導致寫緩存響應時間很慢,引起數據庫事務阻塞。如果對緩存數據一致性要求不是那么高,數據量也不是很大,則可以考慮定期全量同步緩存。
也有提到如下思路:先刪緩存,然后執行數據庫事務;不過這種操作對于如商品這種查詢非常頻繁的業務不適用,因為在你刪緩存的同時,已經有另一個系統來讀緩存了,此時事務還沒有提交。當然對于如用戶維度的業務是可以考慮的。
不過為了更好地解決以上多個事務的問題,可以考慮使用訂閱數據庫日志的架構,如使用canal訂閱mysql的binlog實現緩存同步。
對于長尾訪問的數據、大多數數據訪問頻率都很高的場景、緩存空間足夠都可以考慮不過期緩存,比如用戶、分類、商品、價格、訂單等,當緩存滿了可以考慮LRU機制驅逐老的緩存數據。
1. 過期緩存機制
即采用懶加載,一般用于緩存別的系統的數據(無法訂閱變更消息、或者成本很高)、緩存空間有限、低頻熱點緩存等場景;常見步驟是:首先讀取緩存如果不命中則查詢數據,然后異步寫入緩存并過期緩存,設置過期時間,下次讀取將命中緩存。熱點數據經常使用即在應用系統上緩存比較短的時間。這種緩存可能存在一段時間的數據不一致情況,需要根據場景來決定如何設置過期時間。如庫存數據可以在前端應用上緩存幾秒鐘,短時間的不一致時可以忍受的。
2.???維度化緩存與增量緩存
對于電商系統,一個商品可能拆成如基礎屬性、圖片列表、上下架、規格參數、商品介紹等;如果商品變更了要把這些數據都更新一遍那么整個更新成本很高:接口調用量和帶寬;因此最好將數據進行維度化并增量更新(只更新變的部分)。尤其如上下架這種只是一個狀態變更,但是每天頻繁調用的,維度化后能減少服務很大的壓力。
圖3 維度化緩存方案
按照不同維度接收MQ進行更新。
3. ??大Value 緩存
要警惕緩存中的大Value,尤其是使用Redis時。遇到這種情況時可以考慮使用多線程實現的緩存,如Memcached,來緩存大Value;或者對Value進行壓縮;或者將Value拆分為多個小Value,客戶端再進行查詢、聚合。
4.???熱點緩存
對于那些訪問非常頻繁的熱點緩存,如果每次都去遠程緩存系統中獲取,可能會因為訪問量太大導致遠程緩存系統請求過多、負載過高或者帶寬過高等問題,最終可能導致緩存響應慢,使客戶端請求超時。一種解決方案是通過掛更多的從緩存,客戶端通過負載均衡機制讀取從緩存系統數據。不過也可以在客戶端所在的應用/?代理層本地存儲一份,從而避免訪問遠程緩存,即使像庫存這種數據,在有些應用系統中也可以進行幾秒鐘的本地緩存,從而降低遠程系統的壓力。
本書節選自中生代技術社區圖書《深入分布式緩存》
往期推薦歐創新:深度解析DDD中臺和微服務設計領域驅動專家張逸文字脫口秀:簡單工廠不簡單DDD專家張逸:《解構領域驅動設計》前言Hacker News熱文:請停止學習框架,學習領域驅動設計(DDD)(獲500個點贊)京東平臺研發朱志國:領域驅動設計(DDD)理論啟示DDD專家張逸:構建領域驅動設計知識體系領域驅動設計(DDD)在美團點評業務系統的實踐當DDD遇上微服務DDD戰略篇:架構設計的響應力可視化與領域驅動設計領域驅動設計(DDD)前夜:面向對象思想領域驅動設計(DDD):領域和子域DDD專家張逸:復雜與架構演進的關系滕云:DDD實現之路百度十億級流量的搜索前端,是怎么做架構升級的?Francisco: 構建前瞻性應用架構的優秀實踐這 3 種 DDD 分層架構的模式,你掌握了么?END ? ?? #技術人必備#點個在看,讓更多人看見總結
以上是生活随笔為你收集整理的原创精华:剖析亿级请求下的多级缓存的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: NYOJ 37 回文字符串
- 下一篇: NYOJ 44 字串和