国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

緩存使用的常見問題及解決方法

2013-08-15 00:45劉澤波
關(guān)鍵詞:序列化內(nèi)存應(yīng)用程序

劉澤波

(黃岡職業(yè)技術(shù)學(xué)院成人繼續(xù)教育學(xué)院,湖北黃岡438002)

為提高站點(diǎn)和Web應(yīng)用程序的響應(yīng)速度,改善客戶端用戶體驗(yàn),運(yùn)用緩存是最常見的方式,改善效果也是明顯的。通常是將一些使用頻繁的、需要花費(fèi)大量計算機(jī)資源或時間而形成的數(shù)據(jù)進(jìn)行緩存,從而加快后續(xù)的數(shù)據(jù)訪問速度。這是以空間換取時間的設(shè)計方式,所以合理使用緩存在網(wǎng)站和應(yīng)用程序的設(shè)計中是十分重要的。

1 緩存的基本形式

1.1 本地緩存是將需要緩存的數(shù)據(jù)緩存在服務(wù)器的內(nèi)存中,當(dāng)需要讀取數(shù)據(jù)時首先在緩存中查找,如在緩存中存在需要的數(shù)據(jù)則直接讀取,如緩存中沒有數(shù)據(jù)或數(shù)據(jù)過期,則到數(shù)據(jù)存儲設(shè)備中讀取,可明顯提高數(shù)據(jù)的讀取速度。

1.2 分布式緩存是將需要緩存的數(shù)據(jù)存放在緩存服務(wù)器中,訪問緩存數(shù)據(jù)時應(yīng)用程序需要跨進(jìn)程去讀寫分布式緩存服務(wù)器上的數(shù)據(jù)。這種方式要求數(shù)據(jù)緩存時必須對數(shù)據(jù)進(jìn)行序列化,然后跨進(jìn)程緩存在緩存服務(wù)器中;讀取時則首先跨進(jìn)程返回要讀取的數(shù)據(jù),然后對返回的緩存數(shù)據(jù)進(jìn)行反序列化,最后程序中方能使用數(shù)據(jù)。序列化與反序列化過程會大量占用CPU操作,這往往是問題所在。另外當(dāng)在應(yīng)用程序中修改了獲取到的數(shù)據(jù),緩存服務(wù)器中原先的數(shù)據(jù)是沒有修改的,除非再次將數(shù)據(jù)保存到緩存服務(wù)器。

2 常見緩存使用問題及解決方法

2.1 默認(rèn)的序列化機(jī)制過于依賴問題

使用跨進(jìn)程的緩存機(jī)制需要注意問題主要有:

(1)序列化與反序列化過程全部在應(yīng)用程序服務(wù)器上完成,而緩存服務(wù)器的任務(wù)僅僅是保存緩存數(shù)據(jù)。

(2)NET中默認(rèn)使用的序列化機(jī)制需要使用反射機(jī)制,而反射機(jī)制也會大量占用計算機(jī)資源。

解決方法是選擇其他序列化方法,實(shí)現(xiàn)盡可能減少對資源的占用,通常方法就是讓緩存對象實(shí)現(xiàn)ISerializable接口。這種自實(shí)現(xiàn)的序列化方式比.NET默認(rèn)的序列化機(jī)制的速度可提高上百倍,其原因就是自實(shí)現(xiàn)的序列化方式?jīng)]有使用反射。

2.2 大對象緩存和緩存數(shù)據(jù)利用效率問題

緩存大對象的代價很大,如確因需求需要產(chǎn)生一次,應(yīng)盡可能的多次使用。在.NET中大對象就是指的其占用服務(wù)器內(nèi)存超過85K的數(shù)據(jù)對象,大對象是分配在大對象托管堆上面的,其對象分配機(jī)制與小堆不相同。在大堆上分配對象空間必須要尋找合適的內(nèi)存空間,分配結(jié)果會導(dǎo)致內(nèi)存碎片出現(xiàn),最終也會導(dǎo)致內(nèi)存不足的問題!因?yàn)槔厥諜C(jī)制不會壓縮有對象回收的大堆,同時分配對象時需要通過遍歷大堆查找合適的空間,而遍歷也要占用成本。所以出現(xiàn)內(nèi)存中小于85K的空間不能分配,結(jié)果造成資源浪費(fèi),也導(dǎo)致內(nèi)存碎片的存在。在實(shí)際應(yīng)用中對大對象的緩存通常應(yīng)該考慮它使用的頻繁度、數(shù)據(jù)對象是否共享、每個用戶是否都要產(chǎn)生等因素。如果使用不頻繁,則數(shù)據(jù)不必緩存;如果是共享數(shù)據(jù),則要考慮進(jìn)行性能測試,將生產(chǎn)大對象的成本與緩存它時占用的計算機(jī)資源成本進(jìn)行比較,原則上選擇成本小的;如果每個用戶都要產(chǎn)生,考慮是否可進(jìn)一步分解,實(shí)在不能分解時,確保緩存后要及時的釋放。

緩存一個對象的集合是很正常的,但讀取數(shù)據(jù)時只獲取其中一小部分也造成資源浪費(fèi)。例如在購物商務(wù)站點(diǎn)中客戶查看自己需要的產(chǎn)品信息時在后臺查詢數(shù)據(jù)庫時可能找到很多符合客戶要求的數(shù)據(jù)并作為一個緩存項(xiàng)緩存起來,同時對找出的產(chǎn)品每次5條進(jìn)行分頁展示,在每次分頁時是根據(jù)緩存鍵去獲取緩存數(shù)據(jù),然后選擇后5條數(shù)據(jù)進(jìn)行顯示。在使用本地緩存的情況下,這可能不會產(chǎn)生較大問題,但采用分布式緩存時問題也隨之而來。因每次獲取數(shù)據(jù)時都是按緩存鍵獲取所有數(shù)據(jù),然后在應(yīng)用服務(wù)器上反序列化所有數(shù)據(jù),而實(shí)際只是利用其中5條數(shù)據(jù),這樣的使用效率很低。解決辦法是將數(shù)據(jù)集合按每次所需的數(shù)據(jù)再次細(xì)分,例可分別為products-1-5、products-2-5等的緩存項(xiàng),這樣就可以直接獲取需要的數(shù)據(jù),效率也很高。

2.3 緩存中已經(jīng)過期或失效的數(shù)據(jù)的及時更新或者刪除問題

這種情況應(yīng)該是使用緩存最常見的問題,例如現(xiàn)在獲取了一個客戶所有沒有處理的訂單的信息,然后緩存起來,接下來又對客戶的某個訂單進(jìn)行了處理,而緩存又沒有及時更新,導(dǎo)致緩存中的數(shù)據(jù)出現(xiàn)過期問題,最終會出現(xiàn)緩存中的數(shù)據(jù)和實(shí)際數(shù)據(jù)庫中的實(shí)際數(shù)據(jù)不一致。當(dāng)然在應(yīng)用中可以容忍這種短暫的數(shù)據(jù)不一致現(xiàn)象,時間太長則堅(jiān)決不允許。對于這種情況,有多種解決方案可以實(shí)現(xiàn),如每次修改或者刪除數(shù)據(jù)后,立即遍歷緩存中的相應(yīng)數(shù)據(jù)并進(jìn)行同步更新,但這樣往往造成性能下降;另外一個方法就是盡可能將緩時間縮短同時使用緩存依賴機(jī)制。

2.4 調(diào)用緩存API后數(shù)據(jù)緩存產(chǎn)生的問題

設(shè)計者通常認(rèn)為調(diào)用緩存的API之后數(shù)據(jù)立即緩存,后面讀取緩存數(shù)據(jù)操作就應(yīng)該沒問題,但問題沒有絕對的,很多莫名其妙的問題的產(chǎn)生就很正常。例如在.NET應(yīng)用中經(jīng)常出現(xiàn)的問題是設(shè)計者在某個控件的單擊事件中調(diào)用了緩存API,然后在頁面呈現(xiàn)時立刻去讀取緩存,照道理來說結(jié)果應(yīng)該是對的,因?yàn)榭紤]到流程設(shè)計沒有問題,但忽略了一旦服務(wù)器內(nèi)存資源緊張,可能導(dǎo)致服務(wù)器內(nèi)存回收了剛才緩存的數(shù)據(jù),當(dāng)然緩存的數(shù)據(jù)就不存在了,讀取數(shù)據(jù)也不正確。通常內(nèi)存回收主要看緩存的設(shè)置和處理。如緩存絕對過期時間設(shè)置為30秒,由于頁面處理時間超過了30秒,等到呈現(xiàn)的時候出現(xiàn)數(shù)據(jù)錯誤也就很正常了;另外即使在程序中第一行代碼中緩存了數(shù)據(jù),也許在第三行代碼中立刻讀取緩存數(shù)據(jù)時,數(shù)據(jù)也可能不存在。這可能因?yàn)榉?wù)器資源有限,緩存機(jī)制直接將最少訪問的數(shù)據(jù)進(jìn)行清理;或因?yàn)榉?wù)器太忙和網(wǎng)絡(luò)性能又差極端情況下,緩存數(shù)據(jù)根本沒有被立刻序列化并保存到緩存服務(wù)器上,這樣,你還能讀取緩存數(shù)據(jù)嗎?所以建議每次在使用緩存數(shù)據(jù)的時候,要判斷是否存在,否則一些認(rèn)為是“奇怪而又合理的現(xiàn)象”的產(chǎn)生也就不足為奇了。

2.5 緩存大量重復(fù)數(shù)據(jù)導(dǎo)致內(nèi)存浪費(fèi)問題

在使用Linq To SQL技術(shù)時緩存實(shí)體對象數(shù)據(jù)可能會出現(xiàn)由于實(shí)體關(guān)聯(lián)特性導(dǎo)致原本不需要緩存的數(shù)據(jù)也緩存。在使用分布式緩存來緩存一些實(shí)體對象的信息時,如果沒實(shí)現(xiàn)自己的實(shí)體對象序列化機(jī)制而采用默認(rèn)的,那么在序列化實(shí)體對象時,會將實(shí)體對象所引用的關(guān)聯(lián)實(shí)體對象同時序列化(包括被序列化對象中的其他引用對象),也就是實(shí)體對象和其所有關(guān)聯(lián)實(shí)體對象都被序列化了。如果這是設(shè)計要求實(shí)現(xiàn)的,也沒有問題;反之就不能接受,因?yàn)槔速M(fèi)了很多的資源。解決的方法是要么自己實(shí)現(xiàn)序列化以實(shí)現(xiàn)完全控制需要序列化的對象,要么在使用默認(rèn)的序列化機(jī)制時就在不需要序列化的對象上面加上[NonSerialized]標(biāo)記,也可達(dá)到相同的效果。另外將某實(shí)體對象緩存的同時為了更快的獲取其關(guān)聯(lián)實(shí)體對象信息,額外將關(guān)聯(lián)實(shí)體對象信息緩存在另一個緩存項(xiàng)中,結(jié)果是同一份數(shù)據(jù)緩存兩次。因?yàn)楹芏嗟募夹g(shù)人員不了解在緩存實(shí)體對象的時候已經(jīng)將實(shí)體對象的其他信息(例如其關(guān)聯(lián)實(shí)體對象)已經(jīng)緩存,然后又再次把其關(guān)聯(lián)實(shí)體對象信息緩存在其他的緩存項(xiàng)中,這也導(dǎo)致對象緩存重復(fù)。

在實(shí)際應(yīng)用中還可能出現(xiàn)不同的鍵指向相同的緩存項(xiàng)的使用問題。經(jīng)常在緩存對象時用標(biāo)識鍵作為緩存鍵來獲取這個數(shù)據(jù),同時又因?yàn)闀云渌绞絹韽木彺嬷凶x取數(shù)據(jù),例如循環(huán)遍歷可通過一個索引作為緩存鍵來獲取這個數(shù)據(jù)。在這樣的情況下最好將這些鍵組合起來使用。還有個常見的問題就是相同的數(shù)據(jù)被緩存在不同的緩存項(xiàng)中,例如用戶查詢特定產(chǎn)品信息并將結(jié)果緩存,另外用戶又查找某類型產(chǎn)品,恰好剛才特定產(chǎn)品又出現(xiàn)在結(jié)果中,同時結(jié)果又緩存在另外一個緩存項(xiàng)中,這時也明顯出現(xiàn)內(nèi)存的浪費(fèi),解決方法是在緩存中創(chuàng)建一個索引列表避免重復(fù)。

2.6 利用緩存配置應(yīng)用程序的問題

由于緩存本身具有數(shù)據(jù)失效檢測機(jī)制,所以設(shè)計員喜歡將動態(tài)變化的信息保存在緩存中以充分利用緩存失效檢測機(jī)制。在應(yīng)用中的一些配置可能會發(fā)生變化,可以利用緩存來配置應(yīng)用程序,應(yīng)用配置設(shè)置后,可在定期緩存失效后重新讀取配置文件(可能此時的配置和之前不同),同時任何其他地方都可以重新讀取緩存進(jìn)行配置更新。特別適合在多臺服務(wù)器上部署同一個站點(diǎn)的情況,可能沒有及時去更新每個服務(wù)器的站點(diǎn)配置文件,這時使用分布式緩存緩存配置信息確實(shí)看起來是個不錯的方法,因?yàn)橹灰乱粋€站點(diǎn)的配置文件,其他站點(diǎn)就實(shí)現(xiàn)同步修改,但要考慮是不是所有的配置信息都要保持一致?還要考慮另一個情況是如果緩存服務(wù)器出了問題——宕機(jī)了,則所有使用這個配置信息的站點(diǎn)可能都會出現(xiàn)問題。解決方法是配置文件的信息采用監(jiān)控的機(jī)制,一旦文件內(nèi)容發(fā)生變化就重新加載配置信息。

2.7 在線程間共享使用緩存數(shù)據(jù)問題

當(dāng)數(shù)據(jù)放在緩存中時,通常程序的多個線程都可以訪問這個共享區(qū)域,但多個線程在訪問緩存數(shù)據(jù)時肯定會產(chǎn)生訪問競爭,特別對于分布式緩存,因?yàn)閿?shù)據(jù)的修改不是立刻發(fā)生在本機(jī)的內(nèi)存中,而是經(jīng)一個跨進(jìn)程的過程,這會導(dǎo)致數(shù)據(jù)具有不確定性,這個問題可通過實(shí)現(xiàn)線程加鎖的方式來解決。

對于網(wǎng)站和應(yīng)用程序設(shè)計過程中緩存的使用,設(shè)計者要充分考慮網(wǎng)站和應(yīng)用程序中的各種因素,熟悉使用緩存時應(yīng)注意的細(xì)節(jié),讓緩存在網(wǎng)站和應(yīng)用程序中發(fā)揮其應(yīng)有的作用,網(wǎng)站和Web應(yīng)用程序的響應(yīng)才真正地顯著提高。

[1][美]Joseph C.Rattz LINQ技術(shù)詳解 C#2008版[M].人民郵電出版社,2009(07).

[2]陳輪,劉蕾ASP.NET 3.5網(wǎng)絡(luò)數(shù)據(jù)庫開發(fā)實(shí)例自學(xué)手冊[M].電子工業(yè)出版社,2008.

[3]汪洋 .NET應(yīng)用架構(gòu)設(shè)計:原則、模式與實(shí)踐[M].機(jī)械工業(yè)出版社,2012.

猜你喜歡
序列化內(nèi)存應(yīng)用程序
外部高速緩存與非易失內(nèi)存結(jié)合的混合內(nèi)存體系結(jié)構(gòu)特性評測
如何建構(gòu)序列化閱讀教學(xué)
刪除Win10中自帶的應(yīng)用程序
“春夏秋冬”的內(nèi)存
谷歌禁止加密貨幣應(yīng)用程序
Java反序列化漏洞探析及其修復(fù)方法研究
Java 反序列化漏洞研究
作文訓(xùn)練微格化、序列化初探
基于內(nèi)存的地理信息訪問技術(shù)
三星電子將開設(shè)應(yīng)用程序下載商店
泉州市| 镇巴县| 浦县| 增城市| 长沙市| 安仁县| 阜宁县| 汉源县| 大田县| 稻城县| 石嘴山市| 凤台县| 吉安市| 烟台市| 宣恩县| 平江县| 湘乡市| 灵宝市| 南漳县| 周宁县| 焉耆| 辽阳市| 黑河市| 囊谦县| 英山县| 通榆县| 绥宁县| 阜平县| 武冈市| 临城县| 铁力市| 百色市| 河西区| 盐亭县| 彰武县| 岳阳县| 贞丰县| 通辽市| 游戏| 西吉县| 永兴县|