Memcached是danga.com(運(yùn)營(yíng)LiveJournal的技術(shù)團(tuán)隊(duì))開(kāi)發(fā)的一套分布式內(nèi)存對(duì)象緩存系統(tǒng),用于在動(dòng)態(tài)系統(tǒng)中減少數(shù)據(jù)庫(kù)負(fù)載,提升性能。
適用場(chǎng)合
1.分布式應(yīng)用。由于memcached本身基于分布式的系統(tǒng),所以尤其適合大型的分布式系統(tǒng)。
2.數(shù)據(jù)庫(kù)前段緩存。數(shù)據(jù)庫(kù)常常是網(wǎng)站系統(tǒng)的瓶頸。數(shù)據(jù)庫(kù)的大并發(fā)量訪問(wèn),常常造成網(wǎng)站內(nèi)存溢出。當(dāng)然我們也可以使用Hibernate的緩存機(jī)制。但memcached是基于分布式的,并可獨(dú)立于網(wǎng)站應(yīng)用本身,所以更適合大型網(wǎng)站進(jìn)行應(yīng)用的拆分。
3.服務(wù)器間數(shù)據(jù)共享。舉例來(lái)講,我們將網(wǎng)站的登錄系統(tǒng)、查詢系統(tǒng)拆分為兩個(gè)應(yīng)用,放在不同的服務(wù)器上,并進(jìn)行集群,那這個(gè)時(shí)候用戶登錄后,登錄信息如何從登錄系統(tǒng)服務(wù)器同步到查詢系統(tǒng)服務(wù)器呢?這時(shí)候,我們便可以使用memcached,登錄系統(tǒng)將登錄信息緩存起來(lái),查詢系統(tǒng)便可以獲得登錄信息,就像獲取本地信息一樣。
不適用場(chǎng)合
那些不需要“分布”的,不需要共享的,或者干脆規(guī)模小到只有一臺(tái)服務(wù)器的應(yīng)用,memcached不會(huì)帶來(lái)任何好處,相反還會(huì)拖慢系統(tǒng)效率,因?yàn)榫W(wǎng)絡(luò)連接同樣需要資源
安裝
這里介紹windows環(huán)境的安裝。
1.下載memcache的windows穩(wěn)定版,解壓放某個(gè)盤下面,比如在c:\memcached
2.在cmd下輸入 c:\memcached\memcached.exe -d install 安裝
3.再輸入: c:\memcached\memcached.exe -d start 啟動(dòng)。
以后memcached將作為windows的一個(gè)服務(wù)每次開(kāi)機(jī)時(shí)自動(dòng)啟動(dòng)。這樣服務(wù)器端已經(jīng)安裝完畢了。
客戶端
Memcached本身是使用C開(kāi)發(fā)的,客戶端可以是php、C#、或者java。
在網(wǎng)上看到基于java的客戶端有兩個(gè):
1.javamemcached-release2.6.3
這是比較通用的Memcached客戶端框架。具體原創(chuàng)不詳。
②依賴的jar
- commons-pool-1.5.6.jar
- javamemcached-release2.6.3.jar
- slf4j-api-1.6.1.jar
- slf4j-simple-1.6.1.jar
2.alisoft-xplatform-asf-cache-2.5.1
①簡(jiǎn)介
這個(gè)東東是阿里軟件的架構(gòu)師岑文初進(jìn)行封裝的。里面的注釋都是中文的,比較好。
②依賴的jar
- alisoft-xplatform-asf-cache-2.5.1.jar
- commons-logging-1.0.4.jar
- hessian-3.0.1.jar
- log4j-1.2.9.jar
- stax-api-1.0.1.jar
- wstx-asl-2.0.2.jar
范例
基于javamemcached-release2.6.3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package com.bjpowernode.memcached.cache; import java.util.Date; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; public class MyCache { public static void main(String[] args) { MemCachedClient client= new MemCachedClient(); String [] addr ={ "127.0.0.1:11211" }; Integer [] weights = { 3 }; SockIOPool pool = SockIOPool.getInstance(); pool.setServers(addr); pool.setWeights(weights); pool.setInitConn( 5 ); pool.setMinConn( 5 ); pool.setMaxConn( 200 ); pool.setMaxIdle( 1000 * 30 * 30 ); pool.setMaintSleep( 30 ); pool.setNagle( false ); pool.setSocketTO( 30 ); pool.setSocketConnectTO( 0 ); pool.initialize(); // String [] s =pool.getServers(); client.setCompressEnable( true ); client.setCompressThreshold( 1000 * 1024 ); // 將數(shù)據(jù)放入緩存 client.set( "test2" , "test2" ); // 將數(shù)據(jù)放入緩存,并設(shè)置失效時(shí)間 Date date= new Date( 2000000 ); client.set( "test1" , "test1" , date); // 刪除緩存數(shù)據(jù) // client.delete("test1"); // 獲取緩存數(shù)據(jù) String str =(String)client.get( "test1" ); System.out.println(str); } } |
基于alisoft-xplatform-asf-cache-2.5.1
配置memcached.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<? xml version = "1.0" encoding = "UTF-8" ?> < memcached > <!-- name 屬性是程序中使用Cache的唯一標(biāo)識(shí);socketpool 屬性將會(huì)關(guān)聯(lián)到后面的socketpool配置; --> < client name = "mclient_0" compressEnable = "true" defaultEncoding = "UTF-8" socketpool = "pool_0" > <!-- 可選,用來(lái)處理出錯(cuò)情況 --> < errorHandler >com.alisoft.xplatform.asf.cache.memcached.MemcachedErrorHandler </ errorHandler > </ client > <!-- name 屬性和client 配置中的socketpool 屬性相關(guān)聯(lián)。 maintSleep屬性是后臺(tái)線程管理SocketIO池的檢查間隔時(shí)間,如果設(shè)置為0,則表明不需要后臺(tái)線程維護(hù)SocketIO線程池,默認(rèn)需要管理。 socketTO 屬性是Socket操作超時(shí)配置,單位ms。 aliveCheck 屬性表示在使用Socket以前是否先檢查Socket狀態(tài)。 --> < socketpool name = "pool_0" maintSleep = "5000" socketTO = "3000" failover = "true" aliveCheck = "true" initConn = "5" minConn = "5" maxConn = "250" nagle = "false" > <!-- 設(shè)置memcache服務(wù)端實(shí)例地址.多個(gè)地址用","隔開(kāi) --> < servers >127.0.0.1:11211</ servers > <!-- 可選配置。表明了上面設(shè)置的服務(wù)器實(shí)例的Load權(quán)重. 例如 <weights>3,7</weights> 表示30% load 在 10.2.224.36:33001, 70% load 在 10.2.224.46:33001 <weights>3,7</weights> --> </ socketpool > </ memcached > |
測(cè)試類
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package com.bjpowernode.memcached.client.test; import java.util.ArrayList; import java.util.List; import com.alisoft.xplatform.asf.cache.ICacheManager; import com.alisoft.xplatform.asf.cache.IMemcachedCache; import com.alisoft.xplatform.asf.cache.memcached.CacheUtil; import com.alisoft.xplatform.asf.cache.memcached.MemcachedCacheManager; import com.bjpowernode.memcached.cache.client.TestBean; public class ClientTest { @SuppressWarnings ( "unchecked" ) public static void main(String[] args) { ICacheManager<IMemcachedCache> manager; manager = CacheUtil.getCacheManager(IMemcachedCache. class , MemcachedCacheManager. class .getName()); manager.setConfigFile( "memcached.xml" ); manager.start(); try { IMemcachedCache cache = manager.getCache( "mclient_0" ); cache.put( "key" , "value" ); System.out.println(cache.get( "key" )); } finally { manager.stop(); } } } |
使用memcached緩存java bean自定義對(duì)象
Memcached可以緩存String,也可以緩存自定義java bean。但必須是可序列化的java bean(implements Serializable即可)
基于javamemcached-release2.6.3
測(cè)試用java bean
1
2
3
4
5
6
7
8
9
10
11
|
package com.bjpowernode.memcached.cache.client; import java.io.Serializable; public class TestBean implements Serializable{ private static final long serialVersionUID = 5344571864700659321L; private String name; private Integer age; //get、set方法略 } |
MyCache.java 代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
package com.bjpowernode.memcached.cache; import java.util.Date; import com.danga.MemCached.MemCachedClient; import com.danga.MemCached.SockIOPool; public class MyCache { public static void main(String[] args) { MemCachedClient client= new MemCachedClient(); String [] addr ={ "127.0.0.1:11211" }; Integer [] weights = { 3 }; SockIOPool pool = SockIOPool.getInstance(); pool.setServers(addr); pool.setWeights(weights); pool.setInitConn( 5 ); pool.setMinConn( 5 ); pool.setMaxConn( 200 ); pool.setMaxIdle( 1000 * 30 * 30 ); pool.setMaintSleep( 30 ); pool.setNagle( false ); pool.setSocketTO( 30 ); pool.setSocketConnectTO( 0 ); pool.initialize(); // String [] s =pool.getServers(); client.setCompressEnable( true ); client.setCompressThreshold( 1000 * 1024 ); // 將數(shù)據(jù)放入緩存 TestBean bean= new TestBean(); bean.setName( "name1" ); bean.setAge( 25 ); client.add( "bean1" , bean); // 獲取緩存數(shù)據(jù) TestBean beanClient=(TestBean)client.get( "bean1" ); System.out.println(beanClient.getName()); } } |
基于alisoft-xplatform-asf-cache-2.5.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
package com.bjpowernode.memcached.client.test; import java.util.ArrayList; import java.util.List; import com.alisoft.xplatform.asf.cache.ICacheManager; import com.alisoft.xplatform.asf.cache.IMemcachedCache; import com.alisoft.xplatform.asf.cache.memcached.CacheUtil; import com.alisoft.xplatform.asf.cache.memcached.MemcachedCacheManager; import com.bjpowernode.memcached.cache.client.TestBean; public class ClientTest { @SuppressWarnings ( "unchecked" ) public static void main(String[] args) { ICacheManager<IMemcachedCache> manager; manager = CacheUtil.getCacheManager(IMemcachedCache. class , MemcachedCacheManager. class .getName()); manager.setConfigFile( "memcached.xml" ); manager.start(); try { IMemcachedCache cache = manager.getCache( "mclient_0" ); TestBean bean= new TestBean(); bean.setName( "name1" ); bean.setAge( 25 ); cache.put( "bean" , bean); TestBean beanClient=(TestBean)cache.get( "bean" ); System.out.println(beanClient.getName()); List<TestBean> list= new ArrayList<TestBean>(); list.add(bean); cache.put( "beanList" , list); List<TestBean> listClient=(List<TestBean>)cache.get( "beanList" ); if (listClient.size()> 0 ){ TestBean bean4List=listClient.get( 0 ); System.out.println(bean4List.getName()); } } finally { manager.stop(); } } } |