放翁(文初)的一畝三分地

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            210 隨筆 :: 1 文章 :: 320 評論 :: 0 Trackbacks

          Author: wenchu.cenwc

          Email: wenchu.cenwc@alibaba-inc.com

          Memcached 介紹與分析

                 Memcached是一種集中式Cache,支持分布式橫向擴展。總結幾個它的特點來理解一下它的優點和限制。

                 Memory:內存存儲,不言而喻,速度快,對于內存的要求高,不指出的話所緩存的內容非持久化。對于CPU要求很低,所以常常采用將Memcached服務端和一些CPU高消耗Memory低消耗應用部屬在一起。(作為我們AEP正好有這樣的環境,我們的接口服務器有多臺,接口服務器對于CPU要求很高(由于WS-Security),但是對于Memory要求很低,因此可以用作Memcached的服務端部屬機器)

                 集中式Cache:避開了分布式Cache的傳播問題,但是需要非單點保證其可靠性,這個就是后面集成中所作的cluster的工作,可以將多個Memcached作為一個虛擬的cluster,同時對于cluster的讀寫和普通的memcached的讀寫性能沒有差別。

                 分布式擴展:Memcached的很突出一個優點,就是采用了可分布式擴展的模式。可以將部屬在一臺機器上的多個Memcached服務端或者部署在多個機器上的Memcached服務端組成一個虛擬的服務端,對于調用者來說完全屏蔽和透明。提高的單機器的內存利用率,也提供了scale out的方式。

                 Socket通信:傳輸內容的大小以及序列化的問題需要注意,雖然Memcached通常會被放置到內網作為CacheSocket傳輸速率應該比較高(當前支持Tcpudp兩種模式,同時根據客戶端的不同可以選擇使用nio的同步或者異步調用方式),但是序列化成本和帶寬成本還是需要注意。這里也提一下序列化,對于對象序列化的性能往往讓大家頭痛,但是如果對于同一類的Class對象序列化傳輸,第一次序列化時間比較長,后續就會優化,其實也就是說序列化最大的消耗不是對象序列化,而是類的序列化。如果穿過去的只是字符串,那么是最好的,省去了序列化的操作,因此在Memcached中保存的往往是較小的內容。

                 特殊的內存分配機制:首先要說明的是Memcached支持最大的存儲對象為1M。它的內存分配比較特殊,但是這樣的分配方式其實也是對于性能考慮的,簡單的分配機制可以更容易回收再分配,節省對于CPU的使用。這里用一個酒窖比喻來說明這種內存分配機制,首先在Memcached起來的時候可以通過參數設置使用的總共的Memory,這個就是建造一個酒窖,然后在有酒進入的時候,首先申請(通常是1M)的空間,用來建酒架,酒架根據這個酒瓶的大小分割酒架為多個小格子安放酒瓶,將同樣大小范圍內的酒瓶都放置在一類酒架上面。例如20cm半徑的酒瓶放置在可以容納20-25cm的酒架A上,30cm半徑的酒瓶就放置在容納25-30cm的酒架B上。回收機制也很簡單,首先新酒入庫,看看酒架是否有可以回收的地方,如果有直接使用,如果沒有申請新的地方,如果申請不到,采用配置的過期策略。這個特點來看,如果要放的內容大小十分離散,同時大小比例相差梯度很明顯,那么可能對于使用空間來說不好,可能在酒架A上就放了一瓶酒,但占用掉了一個酒架的位置。

                 Cache機制簡單:有時候很多開源的項目做的面面俱到,但是最后也就是因為過于注重一些非必要性的功能而拖累了性能,這里要提到的就是Memcached的簡單性。首先它沒有什么同步,消息分發,兩階段提交等等,它就是一個很簡單的Cache,把東西放進去,然后可以取出來,如果發現所提供的Key沒有命中,那么就很直白的告訴你,你這個key沒有任何對應的東西在緩存里,去數據庫或者其他地方取,當你在外部數據源取到的時候,可以直接將內容置入到Cache中,這樣下次就可以命中了。這里會提到怎么去同步這些數據,兩種方式,一種就是在你修改了以后立刻更新Cache內容,這樣就會即時生效。另一種是說容許有失效時間,到了失效時間,自然就會將內容刪除,此時再去去的時候就會命中不了,然后再次將內容置入Cache,用來更新內容。后者用在一些時時性要求不高,寫入不頻繁的情況。

                 客戶端的重要性:Memcached是用C寫的一個服務端,客戶端沒有規定,反正是Socket傳輸,只要語言支持Socket通信,通過Command的簡單協議就可以通信,但是客戶端設計的合理十分重要,同時也給使用者提供了很大的空間去擴展和設計客戶端來滿足各種場景的需要,包括容錯,權重,效率,特殊的功能性需求,嵌入框架等等。

                 幾個應用點:小對象的緩存(用戶的token,權限信息,資源信息)。小的靜態資源緩存。Sql結果的緩存(這部分用的好,性能提高相當大,同時由于Memcached自身提供scale out,那么對于db scale out的老大難問題無疑是一劑好藥)。ESB消息緩存。

          集成設計

                 為什么需要集成?直接使用現有的兩個Java實現Memcached是否就可以了?

                 當前集成主要為了兩方面考慮,首先是方便的配置使用,如何將Memcached內嵌到類似于ASF以及其他框架中去,并且通過配置文件方便使用,這就需要作部分的集成工作,這部分工作主要是定義了配置文件以及通過Stax去解析配置的功能。然后是如何管理Memcached,這部分內容包括了初始化,運行期檢測,資源回收的工作。最后是擴展,這里的擴展分成兩部分(功能的擴展以及框架實現的擴展),功能擴展例如當前擴展了虛擬的cluster,可以讓多個memcached Client組成一個虛擬的cluster,如果通過放入cluster的方式放入到其中一個Cache Client中的話,那么就可以在整個cluster都作好備份,這樣其實可以根據memcached的單機多實例以及多機多實例作交互備份,提高可靠性。當然后續還有很多可以擴展的內容,這里只是一個開頭。框架實現的擴展指的是這里采用了類似于JdkJAXP的框架設計,只是規定了框架API結構,至于實現者動態載入,這個和ASF等現在可擴展的框架一樣,提供了很方便的擴展點,后續的設計中會提到。

          接口設計類圖:

          1 Cache接口包類圖

                 ICacheIMemcachedCache實現的是最基本的Cache的功能,只是IMemcachedCache有所增強,提供了對于虛擬的Cluster的操作,批量操作,統計的功能。ICacheManagerIMemcachedCacheManager分別是對于上面兩個Cache的管理類,根據配置文件解析,初始化客戶端池,建立虛擬集群,銷毀客戶端池等工作。

          2 Memcached 實現包

                 省略了一些輔助類定義。這部分是具體的實現,同時可以在圖上看到spi包內的CacheManagerFactory就是用來提供擴展使用的接口。只需要定義在jarMETA-INF下面建立services目錄,建立兩個名為:com.alisoft.xplatform.asf.cache.IMemcachedCacheManagercom.alisoft.xplatform.asf.cache.spi.CacheManagerFactory的文件就可以替換MemcachedCacheManagerCacheManagerFactory的實現類,從而改變Memcached Client實現機制。如果沒有這兩個文件在Classpath目錄下面,那么默認將會使用當前框架中的兩個實現。

          3 Memcached的結構圖

                 Memcached Server就是部署在不同服務器或者在同一臺服務器上的Memcached實例,一般采用后臺守護進程方式運行。SocketPool是客戶端連接到服務端的Socket通信層,Memcached Client可以歸屬為虛擬的ClusterMemcachedCacheManager作用是管理ClusterCache。從這個結構圖可以看出客戶端的每一層都是很獨立,這樣有利于層次的交互,以及組合擴展。

          測試與使用

          1. 配置:

          需要有一個名為memcached.xml的文件在classpath中,可以在jar里面也可以在任意classpath可以找的到的地方,需要注意的是,CacheManager實現了對于多個memcached.xml merge的功能。

          具體的配置內容如下:

          <?xml version="1.0" encoding="UTF-8"?>

          <memcached>//總標簽

            //memcached Client的配置,也就是一個IMemcachedCache的配置。Name必須填,表示Cache的名稱,socketpool必須填,表示使用的遠程通信連接池是哪一個,參看后面對于socketpool的定義。后面都是可選的,第三個參數表示傳輸的時候是否壓縮,第四個參數表示默認的編碼方式

          <client name="mclient1" socketpool="pool1" compressEnable="true" defaultEncoding="UTF-8" >

                  <!--errorHandler></errorHandler-->//可定義錯誤處理類,一般不需要定義

              </client>

              <client name="mclient2" socketpool="pool2" compressEnable="true" defaultEncoding="UTF-8" >

              </client>  

               //socketpool是通信連接池定義,每一個memcached Client要和服務端交互都必須有通信連接池作為底層數據通信的支持,name必填,表示名字,同時也是memcached client指定socketpool的依據,failover表示對于服務器出現問題時的自動修復。initConn初始的時候連接數,minConn表示最小閑置連接數,maxConn最大連接數,maintSleep表示是否需要延時結束(最好設置為0,如果設置延時的話那么就不能夠立刻回收所有的資源,如果此時從新啟動同樣的資源分配,就會出現問題),nagleTCP對于socket創建的算法,socketTOsocket連接超時時間,aliveCheck表示心跳檢查,確定服務器的狀態。Serversmemcached服務端開的地址和ip列表字符串,weights是上面服務器的權重,必須數量一致,否則權重無效

              <socketpool name="pool1" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

                  nagle="false" socketTO="3000" aliveCheck="true">

                  <servers>10.0.68.210:12000,10.0.68.210:12222</servers>

                  <weights>5,5</weights>

              </socketpool>  

              <socketpool name="pool2" failover="true" initConn="10" minConn="5" maxConn="250" maintSleep="0"

                  nagle="false" socketTO="3000" aliveCheck="true">

                  <servers>10.0.68.210:22000,10.0.68.210:22222</servers>

                  <weights>5,5</weights>

              </socketpool>

              //虛擬集群設置,這里將幾個clientcache設置為一個虛擬集群,當對這些IMemcachedCache作集群操作的時候,就會自動地對集群中所有的Cache作插入,尋找以及刪除的操作,做一個虛擬交互備份

              <cluster name="cluster1">

                  <memCachedClients>mclient1,mclient2</memCachedClients>

              </cluster>            

          </memcached>

          2. 測試代碼,這里就附帶一個單元測試類的代碼就可以很清楚的知道使用方法。


          后話

          沒有不好的,只有不適合的,適合的場景使用,根據場景適合的使用,才是提高性能的最有效手段。后需要根據所需的應用場景繼續對這部分集成內容作完善,實踐完善設計。

           
          posted on 2008-01-02 22:58 岑文初 閱讀(2074) 評論(1)  編輯  收藏

          評論

          # re: 高效緩存Memcached 集成使用說明 2009-12-28 14:19 nonamexz
          測試代碼怎么沒有看到呢?  回復  更多評論
            


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 玛沁县| 开鲁县| 如东县| 沂南县| 哈尔滨市| 禄劝| 武夷山市| 宿松县| 延安市| 黄龙县| 芷江| 绥棱县| 柘城县| 东乌| 达拉特旗| 安顺市| 马尔康县| 贞丰县| 灌阳县| 思南县| 沅陵县| 宣城市| 阜新市| 贵南县| 偃师市| 洛川县| 安吉县| 长顺县| 高邮市| 吴堡县| 定远县| 仙桃市| 阿克陶县| 洞口县| 旬邑县| 满城县| 铜山县| 柘城县| 烟台市| 洪湖市| 肥城市|