NetCore踩坑記3、還是EFCore吃內存的問題,有時候最簡單的方法便是最好的方法


距離上一次分享已經過去了三個月;情況並沒有預想中的樂觀。

上篇:https://www.cnblogs.com/for-example/p/12955788.html

1、出現了什么狀況

還是上一次分享的問題,EFCore多租戶模式吃內存。

按照上一次我們分享的處理方式,我們進行了以下處理

  1. 增大MemoryCache實例的[空間?]最大值(使用新的MemoryCache實例替換掉原本的實現)
  2. 減小每個Model在MemoryCache中的[空間?]占用
  3. 設置緩存存活時間
  4. 配置緩存刷新時間

情況並沒有得到好轉,它依舊吃掉了很多內存,因為即使經過了這樣的處理,對於我們來說,也沒有任何的幫助,設置緩存存活時間,配置緩存的刷新時間確實是能有效的利用緩存,但在所有客戶蜂擁而至的時候,依舊是每個客戶都需要為其緩存Model,如果客戶是錯峰而來,這樣確實有用,但每個客戶都是三餐高頻訪問,總不能讓人不吃飯吧。

2、我們如何設計解決方案

  • 回想起我們的應用還在單體的時候,一個DBHelp,不去緩存Model,手寫sql直達DB,從未遇到過內存的問題
  • EFCore是因為需要緩存映射關系(Model)才吃掉很多內存。

EFCore有錯嗎?它沒有。緩存映射關系,就是合理的設計方案,因為確實是在映射上存在差異。

我們能不能把差異點變更呢?這使我們找到了解決的靈感,我們可以通過一些處理,讓原本存在的映射差異前移或者后移。

3、我們如何解決

  1. 我們取消了Model的緩存,讓所有租戶使用同一Model
  2. 我們在ToTable的時候使用占位符取代表名差異部位
  3. 我們向EFCore的上下文添加了攔截器(EFCore3x重新回歸),在攔截器內截獲將要執行的sql,替換掉表名里的占位符

通過以上方式,我們對EFCore屏蔽了租戶差異,截獲其執行的sql之后還原了租戶差異,替換表名的過程是實時進行的,是簡單的字符串Replace,雖然會消耗一點算力,但相比刷新緩存消耗的算力和內存,所付出的代價幾乎微乎其微。

4、變更后的成效

內存和CPU都降下來了,現在我們每個服務的內存控制在180Mb左右,調用最密集的服務,內存消耗在600Mb左右(並不是EF吃掉的)

總結

預留占位符,然后替換占位符,這是最簡單的方式,然而卻也是最有效的方式,有時候最簡單的方法便最好的辦法。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM