使用Memcached改進Java企業級應用效能(1):架構和設定

ImportNew發表於2015-06-03

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):架構和設定

圖1 傳統的Java快取架構

在為你的應用程式新增快取框架之後,通過建立CacheManager物件獲取和設定其中的快取條目(entry)。這樣,你的應用和快取框架建立的CacheManager會在相同的JVM上執行。每次增加快取條目,此物件會新增到由快取框架維護某類雜湊表中。

一旦你的應用伺服器軟體執行在多個節點上,你可能需要支援分散式快取。在分散式快取系統中,一旦在AppServer1中新增了某個物件,在AppServer2和AppServer3上此物件也變為可用。傳統的Java快取使用複製(replication)實現分散式快取,這意味著當你為AppServer1新增一個快取條目,該條目會自動複製到系統的其它應用伺服器上。最終,條目會在所有的站點中可用。

使用Memcached

要使用Memcached進行快取,必須下載並在你的平臺上安裝Memcached伺服器軟體。一旦Memcached伺服器安裝成功,它會通過TCP或者UDP埠監聽快取呼叫。

使用Memcached改進Java企業級應用效能(1):架構和設定

圖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企業級應用效能(1):架構和設定

圖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企業級應用效能(1):架構和設定

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

第一部分結語

到此,我們簡要地討論了Memcached分散式框架和眾多傳統Java快取系統。在你的開發環境中安裝了Memcached,通過Telnet連線Memcached。教程的下一篇中,我們將呼叫Java客戶端sypmemcached命令,為一個Java示例應用建立分散式快取方案。在此過程中,你會了解更多關於Memcached的資訊,以及如何提升你的JavaEE應用效能。

相關文章