日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

开发中常见的十种对缓存的错误使用

發(fā)布時間:2023/12/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 开发中常见的十种对缓存的错误使用 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

簡介

緩存那些頻繁使用的很耗費資源的對象,就可以通過更加快速地加載使應用程序獲得更快的響應。在并發(fā)請求時,緩存能夠更好地擴展應用程序。但一些難以覺察的錯誤,可能讓應用程序處于高負荷下,更不用說想讓緩存有更好的表現(xiàn)了,特別是當你正在使用分布式緩存并且將緩存項存儲在不同的緩存服務器或緩存應用程序中時。另外,當緩存在進程外被構(gòu)建時使用進程內(nèi)緩存工作地很好的代碼可能會失敗。這里我將向你展示一些通常的分布式緩存錯誤,它將幫助你做更好的決定——是否使用緩存。

這里列出了我見過的前十種錯誤:

1、 依賴.net默認的序列化器

2、 在一個單獨的緩存項中存儲大對象

3、 在線程間使用緩存共享對象

4、 假設(shè)存儲那些項之后,它們就會立即被緩存

5、 使用嵌套對象存儲整個集合

6、 將父-子對象存儲在一起或者分開

7、 緩存配置項

8、 緩存已打開的流、文件、注冊表或者網(wǎng)絡(luò)句柄的活動對象

9、 使用多個鍵存儲相同的值

10、在更新或者刪除緩存項到持久存儲介質(zhì)之后,沒有同步更新或刪除緩存

讓我們看看這些錯誤是怎么回事,并且看看如何避免它們。

我假設(shè)你已經(jīng)使用asp.net緩存或者企業(yè)庫的緩存模塊一段時間了,你很滿意,現(xiàn)在你需要更好的可擴展性并且想將緩存移動到進程外的實現(xiàn)或者像Velocity、Memcache這樣的分布式緩存上去。在這以后,一切都開始土崩瓦解,因此下面列出的錯誤可能很適合你。


依賴.net默認的序列化器

當你使用一個像Velocity、Memcached這樣的進程外緩存的解決方案時,那些緩存項被存儲的地方在一個單獨的進程上,而不是在你正在運行的應用程序上。每次你向緩存中增加一項,該項都會被序列化到一個字節(jié)數(shù)組然后將該字節(jié)數(shù)組發(fā)送到緩存服務器并存儲它。簡單地說,當你從緩存中獲得一項時,緩存服務器將這些字節(jié)數(shù)組發(fā)送回你的應用程序,然后客戶端庫反序列化該字節(jié)數(shù)組得到目標對象。現(xiàn)在,.net的默認序列化不是最佳的選擇,因為它依賴于反射,而反射是一種CPU密集型操作。結(jié)果是,在緩存中存儲項以及從緩存中獲取項,增加了序列化和反序列化的開銷,進而導致了CPU的開銷,特別是當你緩存復雜類型時。這種高CPU的消耗發(fā)生在你的應用程序中,而不是在緩存服務器上。所以你總是應該使用一個更好的解決方案來讓CPU在序列化以及反序列化時的開銷最小。我個人比較喜歡的方式是自己去序列化和反序列化所有的屬性,通過實現(xiàn)Iserializable接口,并實現(xiàn)反序列化構(gòu)造器。


這可以防止反射格式化器。當你在存儲大對象時,使用這種方案,你獲得的性能提升可能是默認序列化的100倍。所以,我強烈建議你至少為了那些被緩存的對象,你應該總是實現(xiàn)你自己的序列化和反序列化代碼,而不是讓.net使用反射去決定應該序列化什么。


在一個單獨的緩存項中存儲大對象

有時我們覺得大對象應該被緩存起來,因為得到它們要花費很大的代價。例如,也許你覺得緩存一個1MB的圖像對象,可以比從文件系統(tǒng)或者數(shù)據(jù)庫加載圖片對象給你帶來更好的性能。你可能會奇怪為什么這不具有可擴展性。當你一次只有一個請求時這確實會比從數(shù)據(jù)庫加載相同的東西更快。但在并發(fā)加載的時候,頻繁地訪問大的圖片對象將降低服務器的CPU效率。這是因為總得來說,緩存時的序列化和反序列化開銷很大。每次你將嘗試從一個外部進程緩存中獲取一個1MB的圖片對象,在內(nèi)存中構(gòu)建這樣一個圖片對象對CPU來說是一個很明顯的耗時操作。


解決方案是不在緩存中使用一個單獨的鍵來緩存大的圖片對象為一個單獨的項。取而代之的是,你應該將這個大的圖片對象拆分為一些更小的項,然后個別地緩存那些更小的項。你應該只從緩存中檢索那些你需要的最小的項。


這種想法是,看看從大對象中拆出來的那些項中,哪些是你最需要頻繁訪問的(比如說從配置中獲取的圖片對象的連接字符串),并且在緩存中單獨存儲那些項。總是記住那些你從緩存中檢索的項應該盡可能地小,比如最大為8KB。


在線程間使用緩存共享對象

既然你能夠從多個線程中訪問緩存對象,那么有時你就可能在多個線程之間共享數(shù)據(jù)。但是緩存,就像靜態(tài)變量一樣,可能導致競爭條件。當緩存是分布式,并且一旦存儲和讀取一項需要線程外的通信,這種情況就更為常見,并且你的線程彼此之間將獲得更多的機會重疊。接下來的示例展示了進程內(nèi)緩存很少產(chǎn)生競爭條件但進程外緩存總是出現(xiàn)這種情況:


上面的代碼大部分時間都在演示絕大部分會出現(xiàn)的正確的行為,當你正在使用一個進程內(nèi)緩存。但,當你走到進程外或者分布式時,它將一直不會成功地演示大部分情況下的正確行為。你需要在這里實現(xiàn)某種形式的鎖,某些緩存提供程序允許你鎖住一項。例如,Velocity就具有鎖這一特性,但是memcache就沒有。在Velocity,你可以鎖住一項:


你可以使用鎖來可靠地將那些被多線程改變的項從緩存中讀取和寫入。


假設(shè)存儲那些項之后,它們就會立即被緩存

有時你在點擊一個提交按鈕并且假設(shè)頁面被提交之后,你認為緩存中就存儲了一項,并且該項能夠被從緩存中讀取,因為它剛剛被存儲了。你錯了!


你永遠都不能假設(shè)你確信一項被存儲在緩存中。甚至你在第一行存儲了一項,并且在第三行讀取了該項。當你的應用程序處在很大的壓力之下并且缺乏物理內(nèi)存,那些不是很頻繁被訪問的緩存項將被清除。所以,代碼到達第三行的時候,緩存有可能被清除了。永遠都不要假設(shè)你總是能夠從緩存中獲得某一項。你總是應該使用一個“非空”檢測,并且從持久存儲器檢索。


當從緩存中讀取一項時,你應該總是使用這種格式。


使用嵌套對象存儲整個集合

有時你會在一個單獨的緩存項中存儲一個完整的集合,因為你需要頻繁地訪問集合中的項。因此每一次你嘗試讀取集合中的某一項,你不得不首先加載整個集合,然后像通常地那樣讀取。有點像這樣的做法:


這種做法是低效的。你沒有必要加載整個集合而僅僅是讀取其中的一項。當緩存早進程內(nèi)的時候,這絕對沒任何問題,因為在緩存中僅僅存儲著該集合的一個引用。但是,在一個分布式的緩存中,任何時候你訪問它,整個集合都是分離存儲的,這將導致很差的性能。代替緩存整個集合,你應該緩存分離開來的單個的項。


這種想法很簡單,你使用一個鍵來獨立地存儲集合中的每一項。可以想象這種做法很簡單,例如使用索引來區(qū)分。


將父-子對象存儲在一起或者分開

有時,你在緩存中存儲的一項有一個子對象,而該子對象也被你單獨地存儲在另一個緩存項中。例如,你有一個customer對象,它有一個order集合。所以,當你緩存customer,order集合也被緩存了。但是,然后你又單獨地存儲了order集合。所以,當一個單獨的order在緩存中被更新時,在customer內(nèi)部包含相同order項的order集合沒有被更新,并且因此給你造成了不一致的結(jié)果。又一次,當你使用進程內(nèi)緩存的方式,它工作地很好;但是當你的緩存被構(gòu)建在進程外或分布式架構(gòu)上時,它將會失敗。


這是一個很難解決的問題。它要求清晰的設(shè)計,以至于你永遠都不會在緩存中存儲一個對象兩次。一個通常的解決方案是不在緩存中存儲子對象,而是存儲子對象的Key,來讓它們可以被獨立地檢索。所以在上面的場景中,你將不在緩存中存儲customer的order集合。取而代之的是,你將隨著Customer存儲OrderID集合,然后當你需要讀取customer的訂單集合時,你可以使用OrderID來加載單獨的oder對象。


這種方案能夠確保一個實體的實例在緩存中只會被存儲一次,無論它多少次出現(xiàn)在集合或者父對象中。


緩存配置項

有時你緩存配置項。你使用某些緩存過期策略來確保配置被及時刷新,或者當配置文件、數(shù)據(jù)庫表改變的時候被刷新。你認為既然配置項會被頻繁地訪問,從緩存中讀取可以很明顯地減小CPU的壓力。但其實,取而代之的是,你應該使用靜態(tài)變量來存儲配置。


你不應該采用這樣的方案。從緩存中獲得一項并不“廉價”。它可能沒有比從文件或者直接讀取開銷大。但是,它也有一定的消耗,特別是如果該項是一個自定義的類,并且加入了某些序列化的操作。所以,應該用存儲靜態(tài)變量來存儲它。但你也許會為問,當我們將配置項存儲在靜態(tài)變量中,我們?nèi)绾嗡⑿滤恢貑贸绦?#xff1f;你可以使用某些失效邏輯,當配置文件改變時,例如采用文件監(jiān)聽器來重新加載配置。或者使用某些數(shù)據(jù)庫輪詢來檢查數(shù)據(jù)庫的更新。


緩存已打開的流、文件、注冊表或者網(wǎng)絡(luò)句柄的活動對象

我看到過一些開發(fā)者緩存某些類的實例,這些實例持有打開的文件,注冊表或者外部網(wǎng)絡(luò)連接。這種做法很危險。當這些項從緩存中移除的時候,它們無法自動銷毀。除非你手動銷毀這些對象,否則你就會泄露系統(tǒng)資源。

你永遠都不應該僅僅為了在你需要打開的流、文件句柄、注冊表句柄或者網(wǎng)絡(luò)連接的時候,保存那些打開的資源,而緩存持它們。取而代之的是,你應該使用某些靜態(tài)變量或者某些基于內(nèi)存的緩存,這些緩存保證給你一個在失效時的回調(diào),能夠讓你正確地釋放它們。進程外的緩存或者用Session存儲,不能給你失效時的回調(diào)。所以永遠都不要用它們存儲活動對象。


使用多個鍵存儲相同的值

有時你使用Key并且也使用index來在緩存中存儲對象,因為你不僅需要基于key的檢索,同時也需要通過索引來枚舉它們。例如,


如果你正在使用線程內(nèi)緩存,接下來的代碼將工作地很好


上面的這段代碼在進程內(nèi)緩存時,緩存中的兩項都指向了相同的對象實例。所以,不管你如何從緩存中獲得某項,它總是返回相同的對象實例。但是在一個進程外緩存中,特別是在一個分布式緩存中,那些對象都是被序列化后存儲的。而且存儲并不是基于對象引用的,你存儲的是緩存項的一份拷貝,你永遠都無法存儲對象本身。所以,如果你是基于一個Key來檢索一項,當一項被反序列化后或者剛剛被創(chuàng)建后,你從緩存中獲取它,也只是獲取了那一項的最新副本。結(jié)果,該對象的任何改變將無法反映給緩存,除非你在對象狀態(tài)發(fā)生改變之后,覆寫這些緩存中的項。所以,在一個分布式的緩存中,你將不得不像下面這么做:


一旦你使用更改過的項來更新緩存實體,它看起來就像緩存中的項接受了一個該項的新拷貝一樣。


在更新或者刪除緩存項到持久存儲介質(zhì)之后,沒有同步更新或刪除緩存

它仍然能在進程內(nèi)緩存中工作地很好,但是當你采用進程外緩存或者分布式緩存時同樣將會失敗。下面是一個例子:


其原因就是你改變了對象,但是卻沒有將最新的對象更新到緩存內(nèi)。緩存中的項被作為一份拷貝而存儲,不是原本的對象。

另一個錯誤是當該項已經(jīng)從數(shù)據(jù)庫中刪除了,卻沒有在緩存中被刪除。


當你從數(shù)據(jù)庫、文件或者一些持久化存儲中刪除一項時,不要忘記從緩存中刪除該項,刪除所有訪問它的可能性。


總結(jié)

緩存要求謹慎的計劃和對緩存數(shù)據(jù)的清晰理解。否則,當你的緩存構(gòu)建在分布式上時,它不僅會表現(xiàn)糟糕,甚至能夠產(chǎn)生異常。將這些常見的錯誤記住吧!



原文發(fā)布時間為:2011-10-24



本文來自云棲社區(qū)合作伙伴CSDN博客,了解相關(guān)信息可以關(guān)注CSDN博客。

總結(jié)

以上是生活随笔為你收集整理的开发中常见的十种对缓存的错误使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 天天插av| 日韩精品视频在线观看免费 | av在线免费播放网址 | 国产精品无码免费专区午夜 | 四色成人 | 天天综合亚洲 | 色91精品久久久久久久久 | 97国产高清| 99久久综合网 | 色吧视频 | 国产精品人成在线观看免费 | 欧美一区二区三区免 | 久久精品国产一区二区电影 | 91久久精品www人人做人人爽 | 精品国产18久久久久久 | 国产乱视频 | www.麻豆av.com| 老司机在线精品视频 | 亚洲精品国产精品乱码 | 18黄暴禁片在线观看 | 欧美第一夜 | 黄色三级免费 | 玉女心经 在线 | 国内自拍偷拍网 | 欧美日韩在线高清 | 国产成人主播 | 夫の上司に犯波多野结衣853 | 99成人在线| 天天影视综合 | 亚洲网址在线观看 | 强开乳罩摸双乳吃奶羞羞www | 免费观看黄色网址 | 亚洲av无一区二区三区怡春院 | 高潮在线视频 | 国产麻豆91 | 国产在线视频网站 | 亚洲国产日韩在线观看 | 日韩av在线看 | 国产欧美熟妇另类久久久 | 伊人福利在线 | 亚洲第一二三区 | 蜜桃成人无码区免费视频网站 | 成人动漫视频在线观看 | 日本高清视频免费看 | 西西久久| 色xxxx| xxx一区| 国产精品va在线 | 网站免费黄色 | 91小视频| 草草影院国产 | www.av在线免费观看 | 岛国av网址 | 草久av| 肉丝袜脚交视频一区二区 | 亚洲成av人片一区二区梦乃 | 五月婷婷天堂 | 99久久综合国产精品二区 | 国产情侣第一页 | 高潮毛片 | 国内自拍视频在线播放 | 欧美性aaa | 日日躁夜夜躁狠狠久久av | 男人天堂社区 | av中文字幕一区二区 | 欧美黑人多人双交 | 岳乳丰满一区二区三区 | 午夜视频福利在线 | 国产精品一区二区三区在线免费观看 | 亚洲热视频 | 欧美另类videos | 国产chinasex麻豆videos | 蜜桃一区二区三区 | 国产精品伦理一区 | 成人h片在线观看 | 免费观看成人毛片 | 黄色片久久 | 日本一区二区在线免费 | 伊人久久一区二区三区 | 琪琪色视频| 人人操日日干 | 人人草人人爱 | av一区不卡| 高清一二三区 | 欧美性猛交xxxx乱大交俱乐部 | 中文字幕电影一区 | 亚洲欧美中文字幕5发布 | 奇米色婷婷 | 91国语对白 | 看免费的毛片 | 午夜视频91| 国产一区二区不卡在线 | www.亚洲天堂| 国产成人在线看 | 69re视频| a级片免费看 | 综合在线播放 | 99久久久无码国产精品 | 九九午夜 |