架構詞典:緩存

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"這篇想討論的緩存不是[[redis]]的全部功能,而僅僅是其緩存部分。redis在架構上其實承擔着兩個角色,一個是緩存,另一個是內存計算服務。比如實現 HyperLogLog 算法的 PFADD 等指令就屬於典型的內存計算服務。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"共享的緩存(而不是直接在業務代碼中緩存)其實出現得比較早,廣泛使用的 [[memcached]] 誕生於 2003年,是 [[LiveJournal]] 公司爲了解決自己的業務問題發明的。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存以及後面出現的[[ES]]等全文搜索引擎很大程度緩解了[[數據庫]]的壓力,甚至改變了數據庫在架構中的一些使用方式。比如之前對數據庫使用推崇讀寫分離,但緩存引入之後,數據庫的讀寫量差異已經不大,所以不少設計又迴歸到在線業務全部使用主庫的設計,這個設計更加簡單,還能規避掉很多因爲數據庫主從不一致導致的幻讀等問題。ES則大幅度解放了對數據庫索引的需求,引入ES後,數據索引一般只用於必要的主鍵、外鍵、唯一性約束等場景。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"緩存的使用其實需要比較謹慎,因爲","attrs":{}},{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"每引入一處緩存就需要解決一處同步問題","attrs":{}},{"type":"text","text":"。我個人比較喜歡在兩端加緩存:API出口以及緊鄰數據庫的區域,這兩種之外一般還會有第三方調用緩存、計算緩存等場景。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於API出口,一般情況下會設計成對於單個實體的緩存週期略長,但在使用緩存時會先校驗關鍵元素(實體本身以及被引用的其他身體)版本是否變更;對於列表則會設計成較低緩存週期(比如1-5分鐘),但查詢時不做任何檢查。","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"對於緊鄰數據庫的場景,則需要嚴肅考慮緩存淘汰機制。一般我緩存的目標會是一個領域對象,而不是簡單的數據庫的一行。更新領域對象時,會先更新數據庫,然後清理緩存。但這種處理方式仍然沒法嚴格保證最終一致性,一般解決方式有三種,a. 設置緩存有效期 b. 用一個延時隊列再清理一次緩存 c. 使用分佈式事務鎖。考慮到 b/c 兩種方式成本高,普通場景下用a的比較多。這種方式對多中心的設計也比較友好,當多中心數據庫同步時,只需要對同步的每一個Entity都清理對應的緩存的即可。對於緊鄰數據庫的列表型緩存,一般也有兩種處理手法,一種是短緩存週期存儲全部內容;另一種是中緩存週期,但只保存ID。","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章