扛并發主力軍,引入應用層緩存
1.背景
緩存的使用一定是今后開發中100%會用到的技術,尤其是Redis相關的問題,如果面試官不問我我幾個緩存相關的問題,那我覺得我可能是去了個假的互聯網公司。
這里考慮到有些初學者剛剛出校園或者自學中,準許我多費口舌介紹下關于緩存的基礎知識,我們買電腦的時候關心三個比較重要的參數:1.CPU or GPU 型號。2.內存大小。3.硬盤大小。這三個硬件直接決定你電腦性能的好壞。
兩個最關鍵的因素就是 CPU 和 內存,如何衡量一個CPU的好壞?
這是我日常開發用的電腦,我們發現有三個關于內存的參數:
- L2 緩存:每個核心 256 KB
- L3 緩存:6 M
- 內存:16 G
緩存和內存的大小是決定你電腦性能的重要參數,我們都知道內存價格遠高于磁盤,高速緩存(L2/L3)價格高于內存。
速度:寄存器 > 高速緩存(SRCM) > 內存(DRAM) > 磁盤(SSD > HDD)
畫圖工具:VisualParadigm
緩存概念
“Cache一詞來源于1967年的一篇電子工程期刊論文。其作者將法語詞“cache”賦予“safekeeping storage”的涵義,用于計算機工程領域。當CPU處理數據時,它會先到Cache中去尋找,如果數據因之前的操作已經讀取而被暫存其中,就不需要再從隨機存取存儲器(Random Access Memory)中讀取數據——由于CPU的運行速度一般比主內存的讀取速度快,主存儲器周期(訪問主存儲器所需要的時間)為數個時鐘周期。因此若要訪問主內存的話,就必須等待數個CPU周期從而造成浪費。提供“緩存”的目的是為了讓數據訪問的速度適應CPU的處理速度,其基于的原理是內存中“程序執行與數據訪問的局域性行為”,即一定程序執行時間和空間內,被訪問的代碼集中于一部分。為了充分發揮緩存的作用,不僅依靠“暫存剛剛訪問過的數據”,還要使用硬件實現的指令預測與數據預取技術——盡可能把將要使用的數據預先從內存中取到緩存里。CPU的緩存曾經是用在超級計算機上的一種高級技術,不過現今計算機上使用的的AMD或Intel微處理器都在芯片內部集成了大小不等的數據緩存和指令緩存,通稱為L1緩存(L1 Cache即Level 1 On-die Cache,第一級片上高速緩沖存儲器);而比L1更大容量的L2緩存曾經被放在CPU外部(主板或者CPU接口卡上),但是現在已經成為CPU內部的標準組件;更昂貴的CPU會配備比L2緩存還要大的L3緩存(level 3 On-die Cache第三級高速緩沖存儲器)。
面試官:你過去的項目中使用了緩存技術嗎?哪些業務場景使用了?
分析:不管是C端還是B端業務場景,都會使用緩存,如果系統設計不會使用緩存,那實在是無法說服面試官發offer出來,使用緩存優勢就是快,缺點是速度越快價格越昂貴,傳統的基于硬盤存儲的Mysql已經無法滿足現有互聯網公司的流量,為了提高系統的性能,應對大流量高并發,cache 在企業里也有也會廣泛應用。
我:
項目中我主要在4個地方使用到緩存
- CDN:
- 代理
- 本地緩存
- 分布式緩存
CDN 廣泛應用于網站與應用加速、游戲加速、音視頻點播、文件等場景,通過高性能緩存機制,靜態加速,靜態資源如各類型圖片、css、js小文件等,提高訪問效率和資源可用性。
代理在前面的小節講到 《Nginx下的負載均衡》 ,Nginx 可作為 http 緩存工具。
后面的章節主要圍繞“本地緩存”和“分布式緩存”重點介紹應用層緩存的使用,因為作為開發工程師,應用層你接觸相對比較多。
緩存分布圖
緩存使用場景
使用緩存,通??紤]兩種情況:
- 短時間內相同數據重復查詢多次且數據更新不頻繁,這個時候可以選擇先從緩存查詢,查詢不到再從數據庫加載并回設到緩存的方式。此種場景較適合用單機緩存。
- 高并發查詢熱點數據,后端數據庫不堪重負,可以用緩存來扛。
具體應用場景:
- 排行榜相關的問題,如新浪微博熱門話題榜,百度當前熱搜榜,一定是在緩存了。
- 熱門商品列表
- 計數問題的功能,比如記錄網站訪問次數或用戶訪問ip個數。
4.常用緩存框架
在應用服務器本地緩存著熱點數據,應用程序可以在本機內存中直接訪問數據,而無需訪問數據庫。在Java里,本地緩存就是緩存在JVM所在主機的內存中,常規設計中,本地緩存處于分布式緩存上一層,客戶端請求優先查詢本地緩存,如果本地緩存未命中,再去查找 Redis,如果 Redis 依舊沒命中,最后查找數據庫。也可以直接設計分布式緩存+數據庫兩層架構。
本地緩存流行框架
- Guavn Cache :Google開源的Java重用工具集庫Guava里的一款緩存工具。
- Ehcache:非常流行的純Java開源緩存框架,使用簡單,高速,實現線程安全的緩存管理類庫。
- 編程語言自帶數據結構:如 Java 的 HashMap,CurrentHashMap 等。
- Spring 緩存:Spring 全家桶無所不能,如果你的項目組人少事兒多,Spring Cache 或許是不錯的選擇。
分布式緩存流行框架
- Reids:一個遠程非關系型內存數據庫
- Memcached:應用較廣的開源分布式緩存產品之一
- 阿里Tair:阿里開源產品
Redis 是當前最流行的分布式緩存框架,企業廣泛使用,也是面試中要求較高的,每個程序員都必須了解掌握,后面會針對 Redis 詳細介紹。
為什么要使用緩存
在高并發請求時,為何我們頻繁提到緩存技術?最直接的原因是,磁盤IO及網絡開銷是直接請求內存IO千百上千倍,做個簡單計算,如果我們需要某個數據,該數據從數據庫磁盤讀出來需要0.0045S,經過網絡請求傳輸需要0.0005S,那么每個請求完成最少需要0.005S,該數據服務器每秒最多只能響應200個請求,而如果該數據存于本機內存里,讀出來只需要100us,那么每秒能夠響應10000個請求。通過將數據存儲到離CPU更近的位置,減少數據傳輸時間,提高處理效率,這就是緩存的意義。
下圖是小編工作中負責過的一個風控系統在日常24H中 Redis集群 QPS 曲線圖,從業務低峰期幾千或晚高峰最高30W,一個 Redis 集群都可輕松應對,30W QPS 在大型系統中流量并不算高,且不是核心系統,如果在多幾倍幾十倍多流量,一個結構優良的 Redis 集群都可輕松應對,這充分說明了我們為什么要使用緩存,緩存可以把系統系統響應能力提高N個數量級,遠高于傳統基于硬盤的關系型數據庫。所以學會在系統中設計使用緩存也是企業招聘時要求工程師必會的技能。
5.關于緩存的一些算法
常用緩存數據淘汰策略
緩存是非常寶貴的資源,不能把所有數據都放入緩存,只能把最重要的或者要求查詢速度最快的數據緩存起來,比如微博熱門話題排行榜功能,通常使用緩存查詢,而不是數據庫。
- FIFO(First In First Out): 先進先出算法,即先放入緩存的先被移除。
- LRU(Least Recently Used): 最近最少使用算法,使用時間距離現在最久的那個被移除。
- LFU(Least Frequently Used): 最不常用算法,一定時間段內使用次數(頻率)最少的那個被移除。
緩存數據更新策略
- 定時任務從數據庫直接更新緩存:適用于對時間不敏感的數據。
- 查詢時寫緩存,即查詢優先查詢緩存,若緩存未命中,查詢數據庫,將返回結果寫入緩存,數據更新時先 delete 緩存,再更新緩存。
- MQ 消息異步更新緩存,后文中會針對MQ的應用做單獨講解。
6.總結
思考:關于緩存淘汰策略和更新策略,各自有什么優點?有什么缺點?讀者可以作為延伸學習。
為什么要了解每種策略的優缺點,工作中業務場景千差萬別,只有知道不同策略的優缺點才能知道哪種策略最適合當前的業務場景。
高并發網站后臺一定離不開緩存的使用,所以面試中要求工程師必須掌握。
關于緩存常見面試題舉例:
- 為什么使用緩存,有什么優點?
- Redis 與 Memcached 區別。
- 緩存更新策略 & 淘汰策略。
- 關于 Redis 的知識點,如 Redis 常用數據結構,持久化策略,線程模型等。
參考資料
- 維基百科:https://zh.wikipedia.org/wiki/緩存
- 美團點評技術博客:https://tech.meituan.com/
本文轉載自微信公眾號「轉行程序員」,可以通過以下二維碼關注。轉載本文請聯系轉行程序員公眾號。