緩存(1):三級緩存

三級緩存是指什么

我們常說的三級緩存如下:

  • CPU三級緩存
  • Spring三級緩存
  • 應用架構(JVM、分布式緩存、db)三級緩存

CPU

基本概念

CPU 的訪問速度每 18 個月就會翻 倍,相當于每年增? 60% 左右,內存的速度當然也會不斷增?,但是增?的速度遠小于 CPU,平均每年 只增? 7% 左右。于是,CPU 與內存的訪問性能的差距不斷拉大。

為了彌補 CPU 與內存兩者之間的性能差異,就在 CPU 內部引入了 CPU Cache,也稱高速緩存

CPU Cache 通常分為大小不等的三級緩存,分別是 L1 Cache、L2 Cache 和 L3 Cache。其中L3是多個核心共享的

離 CPU 核心越近,緩存的讀寫速度就越快
但 CPU 的空間很狹小,離 CPU 越近緩存大小受到的限制也越大

所以,綜合硬件布局、性能等因素,CPU 緩存通常分為大小不等的三級緩存。

三級緩存要比一、二級緩存大許多倍,這是因為當下的 CPU 都是多核心的,

  • 每個核心都有自己的一、二級緩存
  • 三級緩存卻是一顆 CPU 上所有核心共享的
  • 緩存一致性:在多核CPU時代,CPU有“緩存一致性”原則,也就是說每個處理器(核)都會通過嗅探在總線上傳播的數據來檢查自己的緩存值是不是過期了。如果過期了,則失效。
    • 比如聲明volitate,當變量被修改,則會立即要求寫入系統內存。

程序執行數據流向

順序如下

  • 先將內存中的數據加載到共享的 L3 Cache 中,
  • 再加載到每個核心獨有的 L2 Cache,
  • 最后 進入到最快的 L1 Cache,之后才會被 CPU 讀取。
  • 之間的層級關系,如下圖。

在這里插入圖片描述

Spring三級緩存

概述

三級緩存就是在Bean生成流程中保存Bean對象三種形態的三個Map集合
]
這個三級緩存就是為了解決循環依賴

  • 當創建相互依賴的對象時,會形成死循環,例如下圖無緩存中的情況。
    在這里插入圖片描述
  • 而Spring通過增加緩存,將未完全創建好的A提前暴露在緩存中,當相互依賴的對象B對屬性A賦值時,可以直接從緩存中獲取A,而不需要再創建A。如下所示

哪三個緩存

Spring三級緩存機制包括以下三個緩存:

  1. singletonObjects:一級緩存,緩存中的bean是已經創建完成的該bean經歷過實例化->屬性填充->初始化以及各種的后置處理。因此,一旦需要獲取bean時,會優先尋找一級緩存
  2. earlySingletonObjects:二級緩存,該緩存跟一級緩存的區別在于,該緩存所獲取到的bean是提前曝光出來的,是還沒創建完成的。也就是說獲取到的bean只能確保已經進行了實例化,但是屬性填充跟初始化還沒有做完,因此該bean還沒創建完成,時半成品,僅僅能作為指針提前曝光,被其他bean所引用
  3. singletonFactories:三級緩存,在bean實例化完之后,屬性填充以及初始化之前如果允許提前曝光,spring會將實例化后的bean提前曝光,也就是把該bean轉換成beanFactory并加入到三級緩存在需要引用提前曝光對象時再通過singletonFactory.getObject()獲取
// 一級緩存Map 存放完整的Bean(流程跑完的)
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);// 二級緩存Map 存放不完整的Bean(只實例化完,還沒屬性賦值、初始化)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);// 三級緩存Map 存放一個Bean的lambda表達式(也是剛實例化完)
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);

發現兩個Bean循環依賴時

當Spring發現兩個或更多個bean之間存在循環依賴關系時

  • 它會先將其中一個beanA創建的過程中尚未完成的實例放入earlySingletonObjects緩存中,
  • 然后將創建該beanA的工廠對象放入singletonFactories緩存中
  • 接著,Spring會暫停當前bean的創建過程,去創建它所依賴的bean
  • 依賴的bean創建完成后,Spring會將其放入singletonObjects緩存中,并使用它來完成當前bean的創建過程
  • 在創建當前bean的過程中,如果發現它還依賴其他的bean,Spring會重復上述過程,直到所有bean的創建過程都完成為止
  • 注意:當使用構造函數注入方式時,循環依賴是無法解決的
    • 因為在創建bean時,必須先創建它所依賴的bean實例,而構造函數注入方式需要在創建bean實例時就將依賴的bean實例傳入構造函數中
    • 如果依賴的bean實例尚未創建完成,就無法將其傳入構造函數中,從而導致循環依賴無法解決
    • 此時,可以考慮使用setter注入方式來解決循環依賴問題。

當A和B相互依賴時,若先創建實例A,則整個調用過程如下:
在這里插入圖片描述
簡化圖如下

應用架構三級緩存

概述

應用架構三級緩存的時候,一般說JVM級別的、分布式緩存級別的、數據庫級別

  • JVM級別:一般常見本地緩存框架有Guava Cache和Caffeine Cache
  • 分布式緩存級別:一般用的Redis
  • 數據庫級別mysql等數據庫

眾所周知 MySQL 數據庫會將數據存儲在硬盤以防止掉電丟失,但是受制于硬盤的物理設計,即便是目前性能最好的企業級 SSD 硬盤,也比內存的這種高速設備 IO 層面差一個數量級
典型的 “讀多寫少” 的場景,需要在設計上進行數據的讀寫分離,數據寫入時直接落盤處理,
占比超過 90% 的數據讀取操作時則從以 Redis 為代表的內存 NoSQL 數據庫提取數據,利用內存的高吞吐瞬間完成數據提取,這里 Redis 的作用就是我們常說的緩存。

二級緩存架構

二級緩存架構

  • 1級為本地緩存,或者進程內的緩存(如 Ehcache) —— 速度快,進程內可用
  • 2級為集中式緩存(如 Redis)—— 可同時為多節點提供服務

Java 的應用端多級緩存

在 Java 的應用端也要設計多級緩存,我們將進程內緩存與分布式緩存服務結合,有效分攤應用壓力。

  • Java 應用層面,只有 本地緩存(EhCache、Caffeine Cache) 的緩存不存在時,再去 Redis 分布式緩存獲取
  • 果 Redis 也沒有此數據再去數據庫查詢數據查詢成功后對 Redis 與 本地緩存 同時進行雙寫更新
  • 這樣 Java 應用下一次再查詢相同數據時便直接從本地緩存提取,不再產生新的網絡通信,應用查詢性能得到顯著提高。
  • 為了保證緩存一致性,利用 通知(MQ、發布訂閱模式等) 向其他服務實例以及 Redis 緩存服務發起變更通知

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/79967.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/79967.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/79967.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android setContentView()源碼分析

文章目錄 Android setContentView()源碼分析前提setContentView() 源碼分析總結 Android setContentView()源碼分析 前提 Activity 的生命周期與 ActivityThread 相關&#xff0c;調用 startActivity() 時&#xff0c;會調用 ActivityThread#performLaunchActivity()&#xf…

uniapp自定義步驟條(可二開進行調試)

前言 有一個業務需求是需要一個步驟條&#xff0c;但是發現開源的都不太合適&#xff0c;所以就自己寫了一個。 開始 test.vue <template><view class"authenticateRecordDetails_container"><!-- 進度 --><view class"authenticateSte…

22、近端策略優化算法(PPO)論文筆記

近端策略優化算法&#xff08;PPO&#xff09;論文筆記 一、研究背景與目標二、**方法****3.1 策略梯度基礎****3.2 信任區域方法&#xff08;TRPO&#xff09;****3.3 剪切代理目標函數&#xff08;LCLIP&#xff09;****3.4 自適應KL懲罰系數****3.5 算法實現** 三、 L CLIP…

web 自動化之 Selenium 元素定位和瀏覽器操作

文章目錄 一、元素定位的八大方法1、基于 id/name/class/tag_name 定位2、基于 a 標簽元素的鏈接文本定位3、基于xpath定位4、css定位 二、瀏覽器操作1、信息獲取2、 瀏覽器關閉3、 瀏覽器控制 一、元素定位的八大方法 web 自動化測試就是通過代碼對網頁進行測試&#xff0c;在…

前端面經 作用域和作用域鏈

含義&#xff1a;JS中變量生效的區域 分類&#xff1a;全局作用域 或者 局部作用域 局部作用域&#xff1a;函數作用域 和 塊級作用域ES6 全局作用域:在代碼中任何地方都生效 函數中定義函數中生效&#xff0c;函數結束失效 塊級作用域 使用let或const 聲明 作用域鏈:JS查…

【C/C++】RPC與線程間通信:高效設計的關鍵選擇

文章目錄 RPC與線程間通信&#xff1a;高效設計的關鍵選擇1 RPC 的核心用途2 線程間通信的常規方法3 RPC 用于線程間通信的潛在意義4 主要缺點與限制4.1 缺點列表4.2 展開 5 替代方案6 結論 RPC與線程間通信&#xff1a;高效設計的關鍵選擇 在C或分布式系統設計中&#xff0c;…

兩種方法求解最長公共子序列問題并輸出所有解

最長公共子序列&#xff08;Longest Common Subsequence, LCS&#xff09;是動態規劃領域的經典問題&#xff0c;廣泛應用于生物信息學&#xff08;如DNA序列比對&#xff09;、文本差異比對&#xff08;如Git版本控制&#xff09;等領域。本文將通過??自頂向下遞歸記憶化??…

SpringBoot應急知識學習系統開發實現

概述 一個基于SpringBoot開發的應急知識學習系統&#xff0c;該系統提供了完整的用戶注冊、登錄、知識學習與測評功能。對于開發者而言&#xff0c;這是一個值得參考的免費Java源碼項目&#xff0c;可以幫助您快速構建類似的教育平臺。 主要內容 5.2 注冊模塊的實現 系統采…

【Python 字符串】

Python 中的字符串&#xff08;str&#xff09;是用于處理文本數據的基礎類型&#xff0c;具有不可變性、豐富的內置方法和靈活的操作方式。以下是 Python 字符串的核心知識點&#xff1a; 一、基礎特性 定義方式&#xff1a; s1 單引號字符串 s2 "雙引號字符串" s…

第十六屆藍橋杯大賽軟件賽C/C++大學B組部分題解

第十六屆藍橋杯大賽軟件賽C/C大學B組題解 試題A: 移動距離 問題描述 小明初始在二維平面的原點&#xff0c;他想前往坐標(233,666)。在移動過程中&#xff0c;他只能采用以下兩種移動方式&#xff0c;并且這兩種移動方式可以交替、不限次數地使用&#xff1a; 水平向右移動…

如何使用極狐GitLab 軟件包倉庫功能托管 npm?

極狐GitLab 是 GitLab 在中國的發行版&#xff0c;關于中文參考文檔和資料有&#xff1a; 極狐GitLab 中文文檔極狐GitLab 中文論壇極狐GitLab 官網 軟件包庫中的 npm 包 (BASIC ALL) npm 是 JavaScript 和 Node.js 的默認包管理器。開發者使用 npm 共享和重用代碼&#xff…

Matlab 基于Hough變換的人眼虹膜定位方法

1、內容簡介 Matlab220-基于Hough變換的人眼虹膜定位方法 可以交流、咨詢、答疑 2、內容說明 略 3、仿真分析 略 4、參考論文 略

chili調試筆記14 畫線 頁面布置 線條導出dxf

2025-05-08 09-05-06 llm畫線 頁面布置 expand有自己的格式 刪了就會按照子元素格式 不加px無效 沒有指定尺寸設置100%無效 怎么把線條導出dxf command({name: "file.export",display: "command.export",icon: "icon-export", }) export class…

藍綠發布與金絲雀發布

藍綠發布與金絲雀發布 一、藍綠發布&#xff1a;像「搬家」一樣安全上線1. 生活化故事2. 技術步驟拆解步驟①&#xff1a;初始狀態步驟②&#xff1a;部署新版本到綠環境步驟③&#xff1a;內部驗證綠環境步驟④&#xff1a;一鍵切換流量步驟⑤&#xff1a;監控與回滾 3. 藍綠發…

【2025五一數學建模競賽B題】 礦山數據處理問題|建模過程+完整代碼論文全解全析

你是否在尋找數學建模比賽的突破點&#xff1f;數學建模進階思路&#xff01; 作為經驗豐富的美賽O獎、國賽國一的數學建模團隊&#xff0c;我們將為你帶來本次數學建模競賽的全面解析。這個解決方案包不僅包括完整的代碼實現&#xff0c;還有詳盡的建模過程和解析&#xff0c…

JavaSE核心知識點02面向對象編程02-02(封裝、繼承、多態)

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點睡覺 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 文章目錄 JavaSE核心知識點02面向對象編程02-02&#…

Yolo遷移訓練-帶訓練源碼

目錄 下載Git 拉下yolo模型 下載labelimg 準備訓練集 遷移訓練 繼續訓練 下載Git Git - Downloading Package 拉下yolo模型 然后用克隆腳本拉下yolo模型 python clone_yolo.py import os import subprocess import sys import shutildef check_git_installed():"…

LangChain框架-PromptTemplate 詳解

摘要 本文聚焦于 LangChain 框架中PromptTemplate提示詞模板模塊的深度解析,主要參考langchain_core.prompts源碼模塊與官方文檔。系統梳理 LangChain 對提示詞模板的封裝邏輯與設計思路,旨在幫助讀者構建全面、深入的知識體系,為高效運用LangChain 框架的提示詞模板開發應用…

中小企業設備預測性維護三步構建法:從零到精的技術躍遷與中訊燭龍實踐

在工業4.0浪潮中&#xff0c;中小企業常陷入"設備故障頻發"與"數字化成本高企"的雙重困境。本文基于半導體、食品加工等行業實證數據&#xff0c;結合中訊燭龍系統技術突破&#xff0c;為中小企業提供一套零基礎、低門檻、可擴展的預測性維護實施框架&…

C30-函數

一 函數的優點 避免代碼冗長模塊化的設計思路(十分類似組裝電腦)按功能劃分,每個函數代表一個功能 二 函數的三要素 函數要先定義再使用(就像是變量一樣)三要素: 函數名→體現功能參數列表 比如yf(x)→x就是參數又如yf(x,y)→x,y就是參數→參數的個數取決于需求 返回值:比如…