幫助IT團隊快速構建符合jt808協議部標的基于java技術的GPS和視頻平臺(2379423771@qq.com)

          應用層緩存 VS ORM緩存

            最近做一個比較大的電子商務項目,預計每天訂單量將在5萬多單,客服人員需要頻繁的下單、查詢訂單、操作訂單,客人預訂完訂單后,會立即進入處理流程,為了提高服務質量,要求流水化作業,平均要在40分鐘-80分鐘內處理完訂單。所以訂單在創建后,會在短時間內,被頻繁的修改和查看。
            由于在項目中ORM層主要是基于Hibernate框架,所以在調優時,很自然的就想到打開Hibernate的二級緩存,以次來減小由于Load 訂單大對象時N+1次查詢給數據造成的壓力,自己做的測試效果也非常好,也順利通過壓力測試。
            但在上線時,性能卻并不佳,經過分析業務的操作特點,查找原因有以下幾占:,

          ??? 1.但由于中臺每天在工作當中,頻繁的批量分配工單,
          ???
          ??? 因為要批量將訂單分配給某一個工作人員處理,在代碼當中執行了一個bulkUpdate的操作:
            template.bulkUpdate("update order set owner = ? where id in (?, ?,?)");
          ???
          ??? 這時Hibernate會直接將Order對象的二級緩存清楚掉。
          ??? 由于二級緩存,總是被刷掉,再查詢時,需要重新從數據庫Load,所以二級緩存變相直接起的作用很少。

          ??? 2.由于工作人員在處理訂單時,每一次查看之后,都有更新操作,在更新之后,訂單被清除緩存,下一組人在處理訂單時,又得重新LOAD,所以效果并不好。
          ??? 3.無論是白盒測試,還是壓力測試時,所基于的案例太過于簡單,沒有更深入的模仿業務操作,對于壓力測試的腳本,也很難精確的模擬出真實的流程化的業務操作過程。


          ??? 開始想到,直接獲得Session,直接使用JDBC來編寫更新代碼,并在更新后,使用sessionFactory.evict(Order.class, id);來有目標的逐個清除特定的對象,以避免全部清楚緩存。
          ??? 但樣做,會對DAO層,修改過大。

          ??? 由于整個模塊最核心的商業對象就是訂單,最后決定在Service層對訂單開小灶,對訂單緩存的單獨的定制處理。

          ??? 我覺得應用緩存存在以下優點:
          ???  ?。薄K俣纫煊贠RM緩存,
          ???  ?。病τ诰彺娴目刂茩喔?,可以直接控制緩存工具的API進行操作,可以避免一些盲目清除的操作。
          ???  ?。?。更靈活的控制緩存中對象的失效,如根據事件來清除緩存,如訂單的處理流程結束時,將該訂單從緩存中清除掉,
          ???  ?。?。在更新數據庫時,不是直接清除緩存,而是更新緩存(盡管這有風險),當業務層拋出異常時,才去清空緩存,避免由于頻繁更新,而清空緩存。

          ??  缺點:
          ??  ?。?。訂單的更新操作,必須是單點的,只能通過IOrderService提供的接口,進行更新操作,否則數據不一致的風險較大。
          ??  ?。?。有一定的代碼工作量
          ??   3。如果不對第三方緩存包,進行一定的封裝的話,會直接耦合于第三方的緩存包,不能像Hibernate那樣,靈活選擇和配置緩存工具。不容易達到ORM緩存最強大的那種透明化和靈活可配置,你可以使用Ehcache, 也可以選Jboss,有錢的話,可以用Tangosol。
          ??  ?。础I務層代碼有一定的侵入

          ???

          ??? 目前的方案是采用應用層的現代化,同時使用如Proxy模式來提供透明化的設計,

          ???   IOrderService -》? OrderService -》 CacheableOrderService

          ??? 通過Spring的Bean配置,一樣可以實現透明化的操作。


          ??  結論:
          ??  1。緩存的清空與更新,要盡量精確的去操作受到更新影響的對象,而不是全部搞掉。
          ??    在Hibernate當中,也提供了sessionFactory.evict(class, id)這樣細粒度的清空緩存對象的方法。
          ????????? sessionFactory.evice(class)的操作,要看這樣的操作是否頻繁,如果頻繁,對于緩存的作用就會大大的折扣。
            ?。?。如果緩存對象過多,對于失效的算法與處理,要與業務對象的特性緊密的聯合起來,通過事件來驅動對象的失效。
            ?。场τ谏虡I對象的緩存,必須要深刻分析對象的生命周期,業務特性。
            ?。?。對于數據不一致的風險,要有足夠的認識與預防手段。
            ?。?。合理的估計訂單對象的大小,分配足夠的內存
             6。如果只使用中心緩存,只能減小數據庫的壓力,對于網絡帶寬的壓力,還是有的,速度上也遠遠遜于本地緩存的效果,所以要結合本地緩存+中心緩存的策略方案,即提高速度,避免群集復制時的瓶頸。

          posted on 2007-06-02 19:39 Speed 閱讀(2992) 評論(4)  編輯  收藏 所屬分類: 框架設計 、J2EE

          評論

          # re: 應用層緩存 VS ORM緩存 2007-06-02 20:52 CowNew開源團隊

          我對hibernate不太熟悉,不過我的想法是Hibernate這種“一廂情愿”的進行緩存的方式很不好,不知道Hibernate有沒有關閉所有緩存功能的選項。在關鍵性業務系統中還是由系統本身來進行緩存控制比較好。Hibernate應該只做單純的ORM的工作,“緩存”不是應該它多管閑事的地方。  回復  更多評論   

          # re: 應用層緩存 VS ORM緩存 2007-06-02 21:04 OneEyeWolf

          @CowNew開源團隊
          那你就應當多了解Hibernate一下,再評論,也不遲。

          hibernate 當然會提供關閉所有緩存的功能,

          hibernate 做的是ORM的功能,CacheProvider是它非常棒的設計思想的一種體現,通過這個接口,可以交由其它的專業Cache來做。

          在配置文件當中,也可以靈活配置。

          ORM緩存最強大的是它的透明化和靈活可配置,你可以使用Ehcache, 也可以選Jboss,有錢的話,可以用Tangosol。  回復  更多評論   

          # re: 應用層緩存 VS ORM緩存 2007-06-02 22:18 CowNew開源團隊

          我從不懷疑Hibernate有這些強大的功能,但是既然他是一個ORM工具,就應該只做好ORM的分內的工作,不要摻雜太多不屬于它職權范圍之外的東西。  回復  更多評論   

          # re: 應用層緩存 VS ORM緩存 2007-06-04 10:32 yefeng

          我一般是用,IBATIS來做DAO的,這樣對象的可控型更強一點
          對取出來的對象,再做緩存,這樣可以分離DAO和CACHE,這樣我覺得更加清楚,和更加可控  回復  更多評論   

          導航

          留言簿(15)

          隨筆分類

          值得一看的博客

          積分與排名

          最新評論

          閱讀排行榜

          主站蜘蛛池模板: 玉树县| 水城县| 壤塘县| 定远县| 太湖县| 白沙| 京山县| 镇沅| 水富县| 沧州市| 建瓯市| 神木县| 西盟| 金湖县| 四会市| 长垣县| 新津县| 丹凤县| 景洪市| 固始县| 上犹县| 蒙城县| 赣榆县| 德化县| 南宫市| 九龙城区| 泽普县| 张家界市| 公安县| 扎赉特旗| 塔城市| 华安县| 扶绥县| 浑源县| 白玉县| 澳门| 剑河县| 冷水江市| 朔州市| 宣恩县| 霍山县|