高併發存儲優化篇:諸多策略,緩存爲王

{"type":"doc","content":[{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文內容概述","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存是什麼","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 1.1. 存儲宕機的致命代價","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 1.2. 數據庫性能爲什麼會下降","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":" 1.3. 緩存的類型","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一線研發最頭疼的緩存問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.1. 緩存穿透","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.2. 緩存擊穿","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.3. 緩存雪崩","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.4. 數據漂移","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.5. 緩存踩踏","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.6. 緩存污染","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2.7. 熱點key","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"頂級緩存架構一覽","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3.1. 微博緩存架構演進","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3.2. 知乎首頁已讀過濾緩存設計","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"總結","attrs":{}}]}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/47/47b8a9b3bf8b4aea7d834b174aff057f.png","alt":null,"title":"更多高併發系列文章,歡迎關注公衆號查看","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Part1 緩存是什麼","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1.1存儲宕機的致命代價[1]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2015年5月28號,攜程網站和APP全面癱瘓持續12小時,數據庫被物理刪除的消息在朋友圈風傳。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"按上季度財報估算,此次宕機直接影響攜程營收大約1200w美元,攜程股價也大跌11%。這還只是發生在互聯網剛剛普及的2015年。如果發生在現在。。。據公司公告是由於員工操作失誤導致。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"雖然這不在我們想討論的性能原因導致異常的範圍內,但不妨礙我們得出結論,數據庫宕機對一個系統的影響是災難性的。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1.2結構化數據庫性能爲什麼會下降","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"以Mysql爲例,我們知道,爲了調和CPU和磁盤的速度不匹配,MySQL 用buffer pool來加載磁盤數據到一段連續的內存中,供讀寫使用。一般情況下,如果緩衝池足夠大,能夠放下所有數據頁,那mysql操作基本不會產生讀IO,而寫IO是異步的,不會影響讀寫操作。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"Buffer pool 不夠大,數據頁不在裏面該怎麼辦?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"去磁盤中讀取,將磁盤文件中的數據頁加載到buffer pool中,那麼就需要等待物理IO的同步讀操作完成,如果此時IO沒有及時響應,則會被堵塞。因爲讀寫操作需要數據頁在buffer中才能進行,所以必須等待操作系統完成IO,否則該線程無法繼續後續的步驟。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"熱點數據,當新的會話線程也需要去訪問相同的數據頁怎麼辦?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"會等待上面的線程將這個數據頁讀入到緩存中buffer pool。如果第一個請求該數據頁的線程因爲磁盤IO瓶頸,遲遲沒有將物理數據頁讀入buffer pool, 這個時間區間拖得越長,則造成等待該數據塊的用戶線程就越多。對高併發的系統來說,將造成大量的等待。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"高併發,大量請求的訪問行爲被阻塞,會造成什麼後果?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於服務來說,大量超時會使服務器處於不可用的狀態。該臺機器會觸發熔斷。熔斷觸發後,該機器的流量會打到其他機器,其他機器發生類似的情況的可能性會提高,極端情況會引起所有服務宕機,曲線掉底。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"上面是由於磁盤IO導致服務異常的分析邏輯,也是我們生產中最常遇到的一種數據庫性能異常的場景。除此之外,還有鎖競爭緩存命中率等異常場景也會導致服務異常。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"如果單庫單表的極限存在,分庫分表等優化策略也只能緩解,不會根除","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"爲了避免上述情況,緩存的使用就非常有必要了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1.3緩存的類型","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存的存在,是爲了調和差異。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"差異有多種,比如處理器和存儲之間的速度差異、用戶對產品的使用體驗和服務處理效率的差異等等。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1.3.1 客戶端緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"離用戶最近的web頁面緩存&app緩存。web頁面因爲技術成熟所以問題不是太多,但app因爲設備的限制,在使用緩存時要多加註意。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"之前經歷的某個業務,因爲客戶端緩存出現問題,發生兩次請求訂單號串單,導致業務異常。串單吶,猜是因爲緩存發生了混亂,至今比較奇怪會發生這種情況,需要對客戶端相關加深認識了。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1.3.2 單機緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"strong","attrs":{}}],"text":"CPU緩存","attrs":{}},{"type":"text","text":"[2]。爲了調和CPU和內存之間巨大的速度差異,設置了L1/L2/L3三級緩存,離CPU越近,速度越快。後面章節中介紹的知乎首頁已讀過濾的緩存架構,其靈感就是來源於此。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/b5/b56ba148227be4cc5ea9c7605c20bbf5.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"L1緩存行示例","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"strong","attrs":{}}],"text":"Ehcache","attrs":{}},{"type":"text","text":"[3]。是最流行了Java緩存框架之一。因爲其開源屬性,在spring/Hibernate等框架上被廣泛使用。支持磁盤持久化和堆外內存。緩存功能齊全。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/79/793d79d48173c76aa7bb27cdcb6b74cc.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Ehcache架構圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"值得一說的是ehcache具備堆外緩存的能力,因爲堆外緩存不受JVM限制,所以不會引發更多的GC停頓,對某些場景下的GC停頓調優有不小的意義。但是需要注意的是堆外內存需要用byte來操作,要實現序列化和反序列化,並且在速度上,也要比堆內存要慢不少,所以,如果不是GC停頓有較大問題,且對業務影響較大,沒必要非用不可。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}},{"type":"strong","attrs":{}}],"text":"Guava cache","attrs":{}},{"type":"text","text":"。靈感來源於ConcurrentHashMap,但具有更豐富的元素失效策略,功能沒有ehcache齊全,如只支持jvm內存,但比較輕量簡潔。之前曾用guava cache來緩存網關的一些配置信息,定時過期自動加載的功能還比較方便。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1.3.3 數據庫緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Query cache即將查詢的結果緩存起來,開啓後生效。其可以降低查詢的執行時間,對需要消耗大量資源的查詢效果明顯。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/63/632f217f23c62fdc4bea547496056f6b.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Query cache 的合理性檢驗 [4]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1.3.4 分佈式緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"memcached。[5]","attrs":{}},{"type":"text","text":"  memcached是一個高效的分佈式內存cache,搭建與操作使用都比較簡單,整個緩存都是基於內存的,因此響應時間很快,但是沒有持久化的能力。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ca/ca9174a17615dde24fb7d48d7321ab1a.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"memcached存儲核心","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"Redis。","attrs":{}},{"type":"text","text":" Redis以優秀的性能和豐富的數據結構,以及穩定性和數據一致性的支持,被業內越來越普遍的使用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/be/be8be1f64933b38de2a0850b43c1016c.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Redis核心對象示意","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在使用redis的都有誰?","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e0/e015239279af832c4b7c52825ff858f8.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"redis官網羅列的redis用戶","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"看到了那個熟悉的公司--微博。微博算是redis的重度用戶,相傳redis的新特性好多都是爲了微博定製的。有關微博的存儲架構在後面章節另做詳述。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文後續的大部分內容也會基於Redis來敘述。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"1.3.5 網絡緩存","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1e/1ed4405ca1d71ab564b7745924382988.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一個簡單請求中的各緩存位置示意","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"CDN服務器是建立在網絡上的內容分發網絡。佈置在各地的邊緣服務器,用戶可以經過中央渠道的負載平衡、內容分發、調度等功用模塊獲取附近所需的內容,減少網絡擁塞,提高響應速度和命中率。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Nginx基於Proxy Store實現,使用Nginx的http_proxy模塊可以實現類似於squid的緩存功能。當啓用緩存時,Nginx會將相應數據保存在磁盤緩存中,只要緩存數據尚未過期,就會使用緩存數據來響應客戶端的請求。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Part2 一線研發最頭疼的緩存問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"下面這些問題其實大家在很多地方都應該見過了,不過爲了內容的完整,還是羅列說明一下。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.1 緩存穿透","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"查詢的是數據庫中不存在的數據,沒有命中緩存而數據庫查詢爲空,也不會更新緩存。導致每次都查庫,如果不加處理,遇到惡意攻擊,會導致數據庫承受巨大壓力,直至崩潰。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"解決方案","attrs":{}},{"type":"text","text":"有兩種:一種是遇到查詢爲空的,就緩存一個空值到緩存,不至於每次都進數據庫。二是布隆過濾器,提前判斷是否是數據庫中存在的數據,若不在則攔截。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ab/abad00f74c88d62797bcdb9c66940611.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"布隆過濾器利用多個hash函數標識數據是否存在,該方法讓較小的空間容納較多的數據,且衝突可控。其工作原則是,過濾器判斷不存在的數據則一定不存在。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f4/f4e5675abc975403b0d97f74f06dded1.gif","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"我是動圖,請等一秒---布隆過濾器原理原理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"如上圖,左側爲添加元素時的hash槽變化,右邊爲判斷某數據是否存在時校驗的hash槽,可以看到,添加了1、2 後hash槽位某些被佔用,判斷2 、3 是否存在時,校驗對應hash槽即可。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.2 緩存擊穿","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從字面意思看,緩存起初時起作用的。發生的場景是某些熱點key的緩存失效導致大量熱點請求打到數據庫,導致數據庫壓力陡增,甚至宕機。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"解決方案","attrs":{}},{"type":"text","text":"有兩種:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一種是熱點key不過期。有的同學在這裏提出了邏輯過期的方案,即物理上不設置過期時間,將期望的過期時間存在value中,在查詢到value時,通過異步線程進行緩存重建。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"第二種是從執行邏輯上進行限制,比如,起一個單一線程的線程池讓熱點key排隊訪問底層存儲,以損失系統吞吐量的代價來維護系統穩定。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.3 緩存雪崩","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"鑑於緩存的作用,一般在數據存入時,會設置一個失效時間,如果插入操作是和用戶操作同步進行,則該問題出現的可能性不大,因爲用戶的操作天然就是散列均勻的。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"而另一些例如緩存預熱的情況,依賴離線任務,","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"定時批量的進行數據更新或存儲","attrs":{}},{"type":"text","text":",過期時間問題則要特別關注。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"因爲離線任務會在短時間內將大批數據操作完成,如果過期時間設置的一樣,會在同一時間過期失效,後果則是上游請求會在同一時間將大量失效請求打到下游數據庫,從而造成底層存儲壓力。同樣的情況還發生在緩存宕機的時候。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"解決方案","attrs":{}},{"type":"text","text":":","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"一是考慮熱點數據不過期獲取用上一節提到的邏輯過期。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"二是讓過期時間離散化,如,在固定的過期時間上額外增加一個隨機數,這樣會讓緩存失效的時間分散在不同時間點,底層存儲不至於瞬間飆升。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"三是用集羣主從的方式,保障緩存服務的高可用。防止全面崩潰。當然也要有相應的熔斷和限流機制來應對可能的緩存宕機。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.4 數據漂移","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據漂移多發生在分佈式緩存使用一致性hash集羣模式下,當某一節點宕機,原本路由在此節點的數據,將被映射到下一個節點。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1f/1f3734bc8c1598585d8cbc8a80ad0453.jpeg","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"圖片來源:知乎用戶Java架構師","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,當宕機的節點恢復之後,剛纔原本從新hash到下一個節點的數據,就全部失效,因爲hash路由已經恢復到了此節點上,所以,下一個節點的數據變成冗餘數據,且,請求當前節點發現數據不存在,則會增加底層存儲調用。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這個問題,是我們使用一致性hash來保證緩存集羣機器宕機時不會造成緩存大量失效方案帶來的一些附加問題。因此需要保證一致性hash儘量的均勻(一致性hash虛擬節點的運用),防止數據傾斜的節點的宕機和恢復對其他節點造成衝擊。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.5 緩存踩踏[6]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存踩踏其實只是一種緩存失效場景的提法,底層原因是緩存爲空或還未生效。關鍵是因爲上游調用超時後喚起重試,引發惡性循環。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"比如,當某一名人新發布了圖片,而他們粉絲都會收到通知,大量的粉絲爭先搶後的想去看發佈了什麼,但是,因爲是新發布的圖片,服務端還沒有進行緩存,就會發生大量請求被打到底層存儲,超過服務處理能力導致超時後,粉絲又會不停的刷新,造成惡性循環。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"解決方案","attrs":{}},{"type":"text","text":":鎖 和 Promise。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"發生這種踩踏的底層原因是對緩存這類公共資源拼搶,那麼,就把公共資源加鎖,消除併發拼搶。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"但是,加鎖在解決公共資源拼搶的同時,引發了另一個問題,即沒有搶佔到鎖的線程會阻塞等待喚醒,當鎖被釋放時,所有線程被一同喚醒,大量線程的阻塞和喚醒是對服務器資源極大的消耗和浪費,即_驚羣效應_。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/e8/e8cc84c3a66cc114c21ade4ee4764783.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"promise的工作原理","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"promise的原理其實是一種_代理模式_,實際的緩存值被promise代替,所有的線程獲取promise 並等待promise返回給他們結果 , 而promise負責去底層存儲獲取數據,通過異步通知方式,最終將結果返回給各工作線程。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這樣,就不會發生大量併發請求同時操作底層存儲的情況。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.6 緩存污染","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存污染的主要表現是,正常的緩存數據總是被其他非主線操作影響,導致被替換失效,之前的一篇敘述消息隊列的文章","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001031&idx=1&sn=75b0eea86788b7b59c61875745b38c4c&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"《BAT實際案例看消息中間件的妙用》","attrs":{}}]},{"type":"text","text":" 中對kafka的緩存污染及其解決方案做了詳述,有興趣的可以看下。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"解決緩存污染的基本出發點,是要拆解不同消費速度的任務(實時消費/定時消費)、或不同的數據生產來源(主流程/follower),分而治之的思路避免相互間緩存的影響。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2.7 熱點key","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/cd/cd14d3be57161bcf53f1a51b3df6491d.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"熱點key的處理邏輯示意圖","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"熱點key的影響不再敘述,而解決熱點key的方法,主要在熱點key的發現和應對上:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以通過監控nginx日誌對用戶請求進行時間窗計數、建立多級緩存、服務器本地利用LRU緩存熱點key、根據業務預估熱點key提前預熱等等;","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以通過分散存儲來降低單個緩存節點應對熱點的壓力。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Part3頂級緩存架構一覽","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3.1微博緩存架構演進","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"微博有100T+存儲,1000+臺物理機,10000+Redis實例,那他的緩存方案是怎麼演變發展到可以抗N個明星同時離婚的呢?","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"緩存的架構演進[7]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/ad/adb7b791ea6495b18de749d950ae2592.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d9/d9451cd5770c4ab52083696693de0dbe.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f9/f944360bbb56453fde465e237be1914c.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/23/23812877e78ae1e6a92193277f6d54bc.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"<<< 左右滑動見更多 >>>","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從上面的幾張緩存演進的架構圖中可以看到,微博的緩存架構其實大部分都是在應對熱點數據,比如,用HA層而不用一致性hash,是因爲微博有典型的跟隨者踩踏效應,一致性hash在踩踏效應下某節點的宕機,會引發下游一系列節點的異常。在比如L1緩存的引入,則是因爲微博的流量在時間上存在一些衰減規律,越新的一段越熱,所以,用小的熱點分片來擋住發生的少但流量大的情況。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"只是上面這些還不夠,一些系統化的問題不容忽視:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"某組資源請求量過大導致需要過多的節點","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Cache 的伸縮容和節點的替換動靜太大","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"過多資源帶來的運維問題","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Cache的易用性問題","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"CacheService緩存服務[8]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了解決上述問題資源微博對緩存進行了服務化,提供一個分佈式的 CacheService 架構,簡化業務開發方的使用,實現系統的動態伸縮容、容災、多層 Cache 等相關功能。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/f2/f2395c103d4c54492184c064f499478f.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"可以看到,在cache池上層,被封裝了一層proxy邏輯,包括異步事件處理器用來管理數據連接、接收數據請求,processer用來進行數據解析,Adapter用來適配底層存儲協議,Router用來路由請求到對應的資源分片,LRU_cache用來優化性能、緩解proxy性能損耗,Timer用來進行健康狀態探測。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"某次機緣巧合和微博架構組的總監簡單聊了幾句瞭解到,現在的整個cacheService服務的易用性已經非常高,服務器節點的彈性伸縮依賴檢測體系全部自動進行,極大的減少了運維和維護成本,可能微博同學們曾經哪些加班喫瓜的歡樂日子已經一去不復返了。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"Redis在微博的極致運用[9][10]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從2010年引入redis,至今已有十多個年頭。有非常多的使用經驗和定製化需求,不然也不會被redis官網列在使用者名單前三的位置。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ 單線程下bgsave重操作卡頓問題","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"bgsave因爲是非常重的操作,發生時會出現明顯的卡頓,造成業務波動;在故障宕機後恢復時主從速度慢,經常出現帶寬洪峯","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"從主線程中獨立出來Bio thread,專門執行Bgsave等操作,避免干擾;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Redis中內置Cronsave功能,控制備份時間;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"放棄bgaofrewrite。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ redis完全替代mysql實現存儲落地","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在Redis替代MySQL存儲落地的過程中,微博對Redis也進行很多定製化改造:","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"修改了AOF機制,增加原本不存在的POS位;","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"修改了Replication機制,實現基於AOF+POS位置的數據同步","attrs":{}}]}]},{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"修改落地機制,改爲RDB+AOF滾動機制,保障數據持久化存儲。","attrs":{}}]}]}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ longset定製化數據結構","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"針對千億級別的關係類存儲,爲了減少成本,放棄了原生的Hash結構(比較佔內存),內存降爲原來的1/10。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/07/077129f9c4a928c1ba729081484e43d7.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ 計數功能優化","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"爲了方便計數,將redis的KV改成了定長的KV ,通過預先分配內存,知道了總數,會極大的降低計數的操作開銷。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"10年的深度依賴,微博在redis的使用上積累了大量的經驗和技巧,值得我們學習參考。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3.2知乎首頁已讀過濾緩存設計[11]","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"知乎社區擁有2.2億用戶、38萬的話題量、2800萬問題、1.3億回答,而個性化的首頁,需要過濾已讀並長期存儲以展示豐富的內容,對系統的性能和穩定性有着極高的要求。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ 早期方案","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/1b/1bf6ac23956e3a355d69a163923d50bc.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/d7/d7ad178d48dfc30e0893e988edeae69e.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"<<< 左右滑動見更多 >>>","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"$ 優化方案","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/5f/5fd3c641b9e67952b7d0bb412cc256f7.png","alt":"圖片","title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"來源見參考文獻","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"大家有沒有發現這個架構思路很熟,是的,就是CPU的多級緩存架構。通過緩存攔截、副本擴展、壓縮降壓的方式,其實基本都是對前面章節敘述的緩存問題的整體應對,以達到低延遲且穩定的緩存服務效果。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":1},"content":[{"type":"text","text":"Part4總結","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本篇文章,通過底層存儲的極限理論,論證了緩存存在的必要性;對緩存場景的一些典型問題做了分析了闡述,最後,用微博和知乎兩個頂級的緩存架構實例,對上面的內容進行了呼應。原創不易,如有感覺有所幫助,歡迎讀者朋友的幫助轉發分享,畢竟,匯仁牌腎寶,大家好纔是真的好~","attrs":{}}]},{"type":"blockquote","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"高併發系列歷史文章微信鏈接文檔","attrs":{}}]},{"type":"numberedlist","attrs":{"start":1,"normalizeStart":1},"content":[{"type":"listitem","attrs":{"listStyle":null},"content":[{"type":"paragraph","attrs":{"indent":0,"number":1,"align":null,"origin":null},"content":[{"type":"text","text":"垂直性能提升","attrs":{}}]}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.1. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650000954&idx=1&sn=a9ee98310e583b1712e1e64988d2a796&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"架構優化:集羣部署,負載均衡","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.2. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650000991&idx=1&sn=4cd73cc5aa4ccb97d9823db82737d14b&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"萬億流量下負載均衡的實現","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.3. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001031&idx=1&sn=75b0eea86788b7b59c61875745b38c4c&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"架構優化:消息中間件的妙用","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.4. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001031&idx=1&sn=75b0eea86788b7b59c61875745b38c4c&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"架構優化:用消息隊列實現存儲降級","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.5. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001071&idx=1&sn=fe00cfd25ae6c8595bcc2aef84ed102f&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"存儲優化:mysql的索引原理和優化","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.6. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001136&idx=1&sn=2585d7dcf8b0e4328fe07eca4e7fe085&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"存儲優化:explain索引優化實戰","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.7. ","attrs":{}},{"type":"link","attrs":{"href":"https://mp.weixin.qq.com/s?__biz=MzA4ODUzMDg5NQ==&mid=2650001108&idx=1&sn=5c246e6888438575f74147892671c2d1&scene=21#wechat_redirect","title":null,"type":null},"content":[{"type":"text","text":"存儲優化:詳解分庫分表","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1.8. 本篇:存儲優化:緩存爲王","attrs":{}}]}],"attrs":{}},{"type":"image","attrs":{"src":"https://static001.geekbang.org/infoq/47/47b8a9b3bf8b4aea7d834b174aff057f.png","alt":null,"title":"更多高併發系列文章,歡迎關注公衆號查看","style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":"","fromPaste":false,"pastePass":false}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"參考資料","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[1]環球旅訊: ","attrs":{}},{"type":"link","attrs":{"href":"https://www.traveldaily.cn/article/92559","title":null,"type":null},"content":[{"type":"text","text":"https://www.traveldaily.cn/article/92559","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[2]cpu緩存: ","attrs":{}},{"type":"link","attrs":{"href":"https://manybutfinite.com/post/intel-cpu-caches/","title":null,"type":null},"content":[{"type":"text","text":"https://manybutfinite.com/post/intel-cpu-caches/","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[3]ehcache官網: ","attrs":{}},{"type":"link","attrs":{"href":"https://www.ehcache.org/","title":null,"type":null},"content":[{"type":"text","text":"https://www.ehcache.org/","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[4]深入分佈式緩存: ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"機械工業出版社","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[5]memcached官網: ","attrs":{}},{"type":"link","attrs":{"href":"https://memcached.org/","title":null,"type":null},"content":[{"type":"text","text":"https://memcached.org/","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[6]Facebook 史上最嚴重的宕機事件分析: ","attrs":{}},{"type":"link","attrs":{"href":"https://www.infoq.cn/article/Bb2YC0yHVSz4qVwdgZmO","title":null,"type":null},"content":[{"type":"text","text":"https://www.infoq.cn/article/Bb2YC0yHVSz4qVwdgZmO","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[7]百億級日訪問量的應用如何做緩存架構設計: ","attrs":{}},{"type":"link","attrs":{"href":"https://my.oschina.net/JKOPERA/blog/1921089","title":null,"type":null},"content":[{"type":"text","text":"https://my.oschina.net/JKOPERA/blog/1921089","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[8]微博 CacheService 架構淺析: ","attrs":{}},{"type":"link","attrs":{"href":"https://www.infoq.cn/article/weibo-cacheservice-architecture","title":null,"type":null},"content":[{"type":"text","text":"https://www.infoq.cn/article/weibo-cacheservice-architecture","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[9]萬億級日訪問量下Redis在微博的9年優化歷程: ","attrs":{}},{"type":"link","attrs":{"href":"https://cloud.tencent.com/developer/news/462944","title":null,"type":null},"content":[{"type":"text","text":"https://cloud.tencent.com/developer/news/462944","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[10]微博Redis定製化之路: ","attrs":{}},{"type":"link","attrs":{"href":"https://developer.aliyun.com/article/62598","title":null,"type":null},"content":[{"type":"text","text":"https://developer.aliyun.com/article/62598","attrs":{}}],"marks":[{"type":"italic"}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"[11]知乎首頁已讀數據萬億規模下的查詢系統架構設計: ","attrs":{}},{"type":"text","marks":[{"type":"italic","attrs":{}}],"text":"Qcon大會分享","attrs":{}}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章