天天看點

使用Memcached改進Java企業級應用性能:架構和設定

Memcached由Danga Interactive開發,用來提升LiveJournal.com網站性能。Memcached分布式架構支援衆多的社交網絡應用,Twitter、Facebook還有Wikipedia。在接下來的兩部分教程中,Sunil Patil介紹了Memcached分布式哈希表架構,以及利用它幫助你為資料驅動Java企業應用做資料緩存。

本文介紹了如何利用Memcached提升Java企業應用性能。首先,總覽了傳統的Java緩存架構,并和Memcached做一個比較。當然,也會在你的本機上安裝Memcached,如何通過telnet與Memcached互動工作。接着,建立一個”Hello Memcached”Java用戶端程式。你會了解如何利用Memcached減少資料庫伺服器負載,緩存動态生成的頁面标記。最後,考慮對spymemcached用戶端做一些進階優化配置。

Memcached以及Java緩存架構總覽

像EHCache和OSCache這樣的Java緩存架構,本質上是存在于應用代碼中的HashMap對象。無論何時添加一個新的對象到緩存中,它都儲存在你的應用記憶體中。儲存少量資料時,這個政策是沒有問題的,但緩存超過GB的資料就有問題了。Memcached伺服器的設計者采用一種分布式架構,這種方式便于擴充,是以,可以利用Memcached做海量資料緩存。

Memcached架構包含兩部分。首先是一個擁有自身程序的Memcached伺服器軟體。倘若你想擴充你的應用,可以在其它機器上運作Memcached伺服器軟體。Memcached伺服器軟體執行個體互相獨立。Memcached系統的第二部分是Memcached用戶端,它确切地知道每台伺服器的存在。用戶端負責擷取緩存錄入對應的伺服器,以及存儲或者獲得緩存錄入——這一過程,稍後我會做詳細地讨論。

如果曾經開發過Java EE 網絡應用,你一定用過EHCache或者OSCache之類的Java開源緩存架構。你或許用過DynaCache或者JBoss Cache這樣的商業緩存架構作為應用伺服器的一部分。在我們親手實踐本教程之前,明白Memcached與那些傳統Java緩存架構的不同之處是很重要的。

使用傳統的Java緩存

無論選擇開源或者是商業方案,使用傳統Java緩存架構是很容易。使用類似EHCache或者OSCache這種開源的架構,你需要下載下傳二進制檔案,添加必須的JAR檔案到你的應用classpath下。同樣,你需要建立配置檔案,配置緩存、交換分區的大小。由于緩存架構需要與軟體綁定,而緩存架構通常會與應用伺服器綁定,是以無需下載下傳任何額外的JAR檔案。

使用Memcached改進Java企業級應用性能:架構和設定

圖1 傳統的Java緩存架構

在為你的應用程式添加緩存架構之後,通過建立CacheManager對象擷取和設定其中的緩存條目(entry)。這樣,你的應用和緩存架構建立的CacheManager會在相同的JVM上運作。每次增加緩存條目,此對象會添加到由緩存架構維護某類哈希表中。

一旦你的應用伺服器軟體運作在多個節點上,你可能需要支援分布式緩存。在分布式緩存系統中,一旦在AppServer1中添加了某個對象,在AppServer2和AppServer3上此對象也變為可用。傳統的Java緩存使用複制(replication)實作分布式緩存,這意味着當你為AppServer1添加一個緩存條目,該條目會自動複制到系統的其它應用伺服器上。最終,條目會在所有的站點中可用。

使用Memcached

要使用Memcached進行緩存,必須下載下傳并在你的平台上安裝Memcached伺服器軟體。一旦Memcached伺服器安裝成功,它會通過TCP或者UDP端口監聽緩存調用。

使用Memcached改進Java企業級應用性能:架構和設定

圖2 Memcached架構

接着,下載下傳一個JavaMemcached用戶端,把用戶端JAR檔案添加到你的應用中。然後建立一個Memcached用戶端對象,就可以調用它的方法擷取和設定緩存條目。一旦添加某個對象到緩存中,Memcached用戶端會擷取該對象、對其序列化并發送位元組數組到Memcached服務端儲存。這時,緩存對象可能被應用運作的JVM作為垃圾回收。

當你需要緩存對象時,可以調用Memcached用戶端的 get() 方法。用戶端會得到這個get請求、序列化并将get請求傳給Memcached伺服器。Memcached伺服器通過該請求從緩存中查找這個對象。如果存有此對象,伺服器會把這個位元組數組傳回給用戶端。用戶端收到位元組數組,反序列化并建立對象傳回給你的應用。

即使你的應用跑在不止一個應用伺服器上,所有的應用都能指向相同的Memcached伺服器,通過它擷取并設定緩存條目。倘若你擁有不止一台Memcached伺服器,伺服器互相之間不會知道。是以,你需要配置Memcached用戶端,這樣它就能知道所有Memcached伺服器。比如,應用在AppServer1建立一個Java對象,接着調用Memcached的 set() 方法,Memcached用戶端就找到某個Memcached伺服器來存放條目。接着它隻和此台Memcached伺服器通信。同樣,一旦存在于AppServer2或者Appserver3的代碼嘗試去擷取某個錄入時,Memcached用戶端首先會找出哪個伺服器存儲了此條目,接着隻與此伺服器通信。

Memcached用戶端邏輯

在預設狀态下,Memcached用戶端使用非常簡單的邏輯選擇伺服器進行get或set操作。一旦調用get()或者set(),用戶端就會得到緩存鍵(key)調用hashcode()方法得到整數值,比如11。接着用這個數除以Memcached伺服器可用數量(比如2),本例中得到的餘數為1。緩存條目就會指向Memcached伺服器1。這個簡單的算可以確定應用伺服器所在的Memcached用戶端為給定的緩存鍵選擇相同的伺服器。

Memcached安裝

Memcached可以運作在Unix、Linux、windows以及MacOSX上。你可以下載下傳Memcached源碼編譯,或者直接下載下傳編譯好的二進制檔案安裝Memcached。這裡我會展示為特定平台下載下傳二進制檔案的安裝過程。如果你更傾向于編譯,請參見這裡。

接下來的安裝指令針對Windows XP 32位機器,若平台是linux等其它平台,檢視這裡。注意本文案例代碼是在Windows XP 32位機器上開發的,不過是可以在其它平台上運作。

  1. Jellycan code是一個Memcached修訂版本,更易用更有效,我們先從下載下傳win32二進制壓縮檔案開始。
  2. 解壓Memcached-<versionnumber>-win32-bin.zip,注意裡面包含memcached.exe,執行此檔案完成伺服器搭建。
  3. 使用 memcached.exe -d install 注冊memcached.exe作為系統服務,你可以在服務控制台開啟或者停止Memcached伺服器。

當你在預設狀态下執行memcached.exe,Memcached伺服器預設占用64兆記憶體,監聽11211端口。在某些情形下,或許你想做一些更加細粒度的控制。比如,端口11211被本機其他程序占用,你希望Memcached可以監聽端口12000;或者你想在品質保證或者生産環境中搭建Memcached伺服器,需要的預設記憶體不止64兆。你可以通過指令行參數定制伺服器行為。運作memcache.exe -help指令會擷取所有的指令行選項,如下圖3所示。

使用Memcached改進Java企業級應用性能:架構和設定

圖3 Memcached伺服器指令行選項

通過Telnet與Memcached互動

一旦Memcached伺服器開始監聽你指定的端口,Memcached用戶端就可以通過TCP或者UDP端口與之連接配接,發送指令或者接受響應,最後關閉連接配接。

連接配接Memcached伺服器方式有多種,我會在本教程的第二部分采用Java用戶端連接配接,你将能夠利用簡單的API從緩存中存儲或者擷取對象。或者你可以采用Telnet用戶端直接與伺服器連接配接。懂得利用Telnet用戶端與Memcached伺服器互動對調試Java用戶端很重要,是以我們就從這裡開始。

Telnet指令

首先你需要用Telnet用戶端連接配接Memcached伺服器。在WindowsXP平台上,如果Memcached伺服器也運作在這台機器上并預設監聽端口11211,隻要執行telnet localhost 11211。接下來的指令對Telnet管理Memcached很重要:

  • set添加一個新的項目到緩存中,使用格式是 Set <keyName> <flags> <expiryTime> <bytes>,你可以将敲入的值存入下一行。倘若不想緩存錄入過期,可以輸入0。
  • get傳回緩存鍵的值,調用get <keyName>獲得keyName的值。
  • add添加一個新的鍵,前提是此鍵之前并不存在,比如add <keyName> <flags> <expiryTime> <bytes>。
  • replace會替代某個鍵的值,前提是此鍵已存在,比如replace <keyName> <flags> <expiryTime> <bytes>。
  • delete删除某個鍵的緩存錄入,調用delete <keyName>删除keyName的值。

圖4的截圖展示了通過Telnet與Memcached伺服器互動案例。正如你所看到的,Memcached伺服器會對每個指令做出回應,比如STORED、NOT_STORED等。

使用Memcached改進Java企業級應用性能:架構和設定

圖4 Telnet用戶端與Memcached伺服器互動案例

第一部分結語

到此,我們簡要地讨論了Memcached分布式架構和衆多傳統Java緩存系統。在你的開發環境中安裝了Memcached,通過Telnet連接配接Memcached。教程的下一篇中,我們将調用Java用戶端sypmemcached指令,為一個Java示例應用建立分布式緩存方案。在此過程中,你會了解更多關于Memcached的資訊,以及如何提升你的JavaEE應用性能。