C#MemoryCache的坑怎么解決

本篇內(nèi)容主要講解“C# Memory Cache的坑怎么解決”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“C# Memory Cache的坑怎么解決”吧!

從事四川雅安電信機(jī)房,服務(wù)器租用,云主機(jī),虛擬空間,域名注冊,CDN,網(wǎng)絡(luò)代維等服務(wù)。

背景

前些天公司服務(wù)器數(shù)據(jù)庫訪問量偏高,運(yùn)維人員收到告警推送,安排我團(tuán)隊(duì)小伙伴排查原因.

我們發(fā)現(xiàn)原來系統(tǒng)定期會(huì)跑一個(gè)回歸測試,該測運(yùn)行的任務(wù)較多,每處理一條任務(wù)都會(huì)到數(shù)據(jù)庫中取相關(guān)數(shù)據(jù),高速地回歸測試也帶來了高頻率的數(shù)據(jù)庫讀取.

解決方案1

我們認(rèn)為每個(gè)任務(wù)要取的數(shù)據(jù)大相徑庭,因此我們考慮對這個(gè)過程進(jìn)行修改,加入MemoryCache把數(shù)據(jù)庫中讀取到的數(shù)據(jù)進(jìn)行緩存.

整個(gè)修改非常簡單,相信對常年混跡在博客園中的各位大佬來說小菜一碟,因此小弟不再敘述添加緩存的步驟細(xì)節(jié).

從緩存的添加,代碼提交,Teamcity 編譯通過,到測試環(huán)境,QA環(huán)境的安裝無比流暢,一切顯得如手到擒來.

嗯,優(yōu)秀是一種習(xí)慣, 沒有一點(diǎn)辦法.

人生如戲,當(dāng)我們還沉浸在"我加的Cache不可能又BUG"的自信中時(shí),QA傳來噩耗,回歸測試大量未通過 ....

故障排查

之前習(xí)慣了使用redis緩存,因此,常識告訴我們 ---  在數(shù)據(jù)庫中數(shù)據(jù)沒有改動(dòng)的前提下,加了緩存后讀取的數(shù)據(jù)的效果和從數(shù)據(jù)庫中讀取的效果是一模一樣的.

除非  ,,,   除非  這個(gè)常識是錯(cuò)誤的....

因此我們加了日志,對寫入緩存前后讀取出來的數(shù)據(jù)進(jìn)行了對比,結(jié)果出人意料.

C# Memory Cache的坑怎么解決

該死 MemoryCache 毀我老臉,丟我精度,拿命來!!!!!

從日志中看到,第一行是從數(shù)據(jù)庫中讀取的結(jié)果,第二行是從cache中讀取的,前兩條數(shù)據(jù)完全一致,到了第三條,第四條,第五條,仔細(xì)觀察發(fā)現(xiàn),在小數(shù)點(diǎn)后面,居然有些小數(shù)點(diǎn)后比較微小的變化,不管變化的大小但數(shù)據(jù)確實(shí)發(fā)生改變了,所以MemoryCache會(huì)影響數(shù)據(jù)精度??這樣會(huì)改變數(shù)據(jù)精度的MemoryCache又有何用?? 

機(jī)智的我,似乎早已看穿了一切,這肯定不是MenoryCache的鍋!!!

不一樣的MemoryCache

我從https://referencesource.microsoft.com 中扒出了MemoryCache的源碼一探究竟.

定位到MemoryCache中的AddOrGetExisting方法,我們看到,其實(shí)我們把數(shù)據(jù)存儲(chǔ)到該緩存的過程本質(zhì)是把該對象存到一個(gè)名為_entries的         Hashtable 中,同樣,取數(shù)據(jù)也是通過Key到該Hashtable中取出來,整個(gè)過程并沒有對該對象進(jìn)行序列化反序列等,也沒有對該對象進(jìn)行clone操作.這就意味著我們之前存入的,和后面取出的(不管我們從MemoryCache中取數(shù)據(jù)取多少次),永遠(yuǎn)只取出同一個(gè)對象.

這一點(diǎn),和我之前使用的RedisCache是有很大區(qū)別的.我們在Redis中存入數(shù)據(jù),是把對象序列化后存到Redis中,取數(shù)據(jù)是把Redis中的字節(jié)數(shù)據(jù)反序列成對象,意味著前一次存入的,和后一次取出的,已經(jīng)不是同一個(gè)對象了,因此Redis中的數(shù)據(jù)是安全的.

猜想

我做出了一個(gè)大膽的猜想,之前從MemoryCache中取出來的數(shù)據(jù)之所以變化了,可能是取出對象后,復(fù)雜的處理過程中對該對象進(jìn)行了什么修改操作,所以后期,再次從數(shù)據(jù)庫中讀取數(shù)據(jù),讀出來的已經(jīng)已經(jīng)不是最初存入的數(shù)據(jù),而是前一次修改之后的數(shù)據(jù).帶著這個(gè)猜想,我對代碼進(jìn)行了修改.

解決方案2

從MenoryCache中取到數(shù)據(jù)后對結(jié)果進(jìn)行clone(),這樣即使程序?qū)θ〕鰜淼慕Y(jié)果進(jìn)行了修改也不會(huì)影響Cache中的數(shù)據(jù)了.

又是一次提心掉到的提交,編譯,安裝后, 回歸測試順利通過.

到此,相信大家對“C# Memory Cache的坑怎么解決”有了更深的了解,不妨來實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

本文題目:C#MemoryCache的坑怎么解決
網(wǎng)站路徑:http://bm7419.com/article30/igcipo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供電子商務(wù)、微信小程序網(wǎng)站設(shè)計(jì)、網(wǎng)站營銷、外貿(mào)網(wǎng)站建設(shè)、App開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司