java缓存技术memcached实例
1 下載memcached-1.2.1-win32.zip? 并且解壓.
2 新建web project項(xiàng)目 名字自己取,然后導(dǎo)入必要的包,alisoft-xplatform-asf-cache-2.5.1.jar,commons-logging-1.0.3.jar,log4j-1.2.13.jar
3 新建類 user.java
package bean;
import java.io.Serializable;
public class User implements Serializable{
?
??? /**
???? * 序列號
???? */
??? private static final long serialVersionUID = -3896605600471191953L;
??? private int uid;
??? private String uname;
??? private String upass;
????
??? public int getUid() {
?????? return uid;
??? }
??? public void setUid(int uid) {
?????? this.uid = uid;
??? }
??? public String getUname() {
?????? return uname;
??? }
??? public void setUname(String uname) {
?????? this.uname = uname;
??? }
??? public String getUpass() {
?????? return upass;
??? }
??? public void setUpass(String upass) {
?????? this.upass = upass;
??? }
}
4 新建 JdbcConnector.java
package util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class JdbcConnector {
? // 定義數(shù)據(jù)庫連接常量
??? private final static String DRIVER = "com.mysql.jdbc.Driver";
??? private final static String URL = "jdbc:mysql://192.168.1.13:3306/test";
??? private final static String DBNAME = "root";
??? private final static String DBPASS = "123456";
????
??? /**
???? * 得到數(shù)據(jù)庫連接
???? * @return
???? * @throws ClassNotFoundException
???? * @throws SQLException
???? */
??? public Connection getConn()throws ClassNotFoundException,SQLException {
?????? // 加載驅(qū)動
?????? Class.forName(DRIVER);
?????? // 通過DriverManager對象得到連接
?????? Connection conn = DriverManager.getConnection(URL,DBNAME,DBPASS);
?????? // 返回?cái)?shù)據(jù)庫連接
?????? return conn;
??? }
}
5 新建 UserDao.java
package util;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import bean.User;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import com.mysql.jdbc.ResultSet;
public class UserDao extends JdbcConnector {
??? // 定義全局變量
??? Connection conn = null;
??? PreparedStatement pstmt = null;
??? ResultSet rs = null;
????
??? /**
???? * 根據(jù)Id查詢用戶
???? * @param uid
???? * @return
???? */
??? public User getUserById(int uid) {
?????? // 創(chuàng)建User對象
?????? User user = null;
?????? // 創(chuàng)建SQL語句
?????? String sql = "select * from user where uid=?";
???????
?????? try {
?????????? // 獲得數(shù)據(jù)庫連接
?????????? conn = (Connection) this.getConn();
?????????? // 通過Connection對象創(chuàng)建PrepareStatement對象
?????????? pstmt = (PreparedStatement) conn.prepareStatement(sql);
?????????? // 設(shè)置SQL語句的參數(shù)
?????????? pstmt.setInt(2, uid);
?????????? // 執(zhí)行查詢,將查詢結(jié)果賦給ResultSet對象
?????????? rs = (ResultSet) pstmt.executeQuery();
?????????? // 遍歷指針
?????????? while (rs.next())
?????????? {
????????????? user = new User();
????????????? user.setUid(rs.getInt("uid"));
????????????? user.setUname(rs.getString("uname"));
????????????? user.setUpass(rs.getString("upass"));
?????????? }
?????? } catch (ClassNotFoundException e) {
?????????? e.printStackTrace();
?????? } catch (SQLException e) {
?????????? e.printStackTrace();
?????? }
?????? return user;
??? }
????
??? /**
???? * 查詢所有用戶
???? * @return
???? */
??? @SuppressWarnings("unchecked")
??? public List getUserList() {
?????? // 創(chuàng)建ArrayList對象
?????? List userList = new ArrayList();
???????
?????? // 創(chuàng)建SQL對象
?????? String sql = "select * from user";
???????
?????? try {
?????????? conn = (Connection) this.getConn();
?????????? pstmt = (PreparedStatement) conn.prepareStatement(sql);
?????????? rs = (ResultSet) pstmt.executeQuery();
?????????? while (rs.next())
?????????? {
????????????? User user = new User();
????????????? user.setUid(rs.getInt("uid"));
????????????? user.setUname(rs.getString("uname"));
????????????? user.setUpass(rs.getString("upass"));
??????????????
????????????? userList.add(user);
?????????? }
?????? } catch (ClassNotFoundException e) {
?????????? e.printStackTrace();
?????? } catch (SQLException e) {
?????????? e.printStackTrace();
?????? }
?????? return userList;
??? }
}
6 新建 MemcachedManager.java
package memcachedTest;
import java.util.Date;
import java.util.List;
import util.UserDao;
import bean.User;
import com.alisoft.xplatform.asf.cache.memcached.client.MemCachedClient;
import com.alisoft.xplatform.asf.cache.memcached.client.SockIOPool;
public class MemcachedManager {
?
?? // 創(chuàng)建MemCachedClient全局對象
??? private static MemCachedClient mcc = new MemCachedClient();
????
??? static {
?????? // 創(chuàng)建服務(wù)器列表及其權(quán)重
?????? String[] servers = {"127.0.0.1:11211"};
?????? Integer[] weights = {3};
???????
?????? // 創(chuàng)建Socket連接池對象
?????? SockIOPool pool = SockIOPool.getInstance();
???????
?????? // 設(shè)置服務(wù)器信息
?????? pool.setServers(servers);
?????? pool.setWeights(weights);
?????? pool.setFailover(true);
???????
?????? // 設(shè)置初始連接數(shù)、最小和最大連接數(shù)以及最大處理時(shí)間
?????? pool.setInitConn(5);
?????? pool.setMinConn(5);
?????? pool.setMaxConn(250);
?????? pool.setMaxIdle(1000*60*60*6);
???????
?????? // 設(shè)置主線程睡眠時(shí)間
?????? pool.setMaintSleep(30);
???????
?????? // 設(shè)置TCP參數(shù)、連接超時(shí)等
?????? pool.setNagle(false);
?????? pool.setSocketTO(3000);
?????? pool.setSocketConnectTO(0);
?????? pool.setAliveCheck(true);
???????
?????? // 初始化連接池
?????? pool.initialize();
???????
?????? // 壓縮設(shè)置,超過指定大小(單位為K)的數(shù)據(jù)都會被壓縮
?????? mcc.setCompressEnable(true);
?????? mcc.setCompressThreshold(64 * 1024);
??? }
????
??? /**
???? * 無參構(gòu)造
???? */
??? protected MemcachedManager (){
???????
??? }
????
??? // 受保護(hù)的對象
??? protected static MemcachedManager instance = new MemcachedManager();
????
??? /**
???? * 為受保護(hù)的對象提供一個(gè)公共的訪問方法
???? */
??? public static MemcachedManager getInstance () {
?????? return instance;
??? }
????
??? /**
???? * 添加對象到緩存中,構(gòu)成方法重載
???? * @param key
???? * @param value
???? * @return
???? */
??? public boolean add(String key,Object value) {
?????? return mcc.add(key, value);
??? }
??? public boolean add (String key,Object value,Date expiry) {
?????? return mcc.add(key, value,expiry);
??? }
????
??? public boolean replace (String key,Object value) {
?????? return mcc.replace(key, value);
??? }
????
??? public boolean replace (String key,Object value,Date expiry)
??? {
?????? return mcc.replace(key, value, expiry);
??? }
????
??? /**
???? * 根據(jù)指定的關(guān)鍵字獲取對象
???? */
??? public Object get(String key) {
?????? return mcc.get(key);
??? }
????
????
????
??? /**
???? * 利用MemCached測試將單個(gè)對象存入緩存,并從緩存中取出
???? */
//? public static void main(String[] args) {
//????? // 得到MemcachedManager實(shí)例
//???? MemcachedManager cache = MemcachedManager.getInstance();
//?????
//???? // 創(chuàng)建UserDao對象
//???? UserDao userDao = new UserDao();
//???? // 查詢單個(gè)User對象
//???? User user = userDao.getUserById(4);
//?????
//???? // 將User對象添加到緩存中
//???? cache.add("user", user.getUname());
//?????
//???? // 將User對象從緩存中取出來
//???? String uname = (String)cache.get("user");
//?????
//???? System.out.println("從緩存中取出的對象為:" + uname);
//? }
????
????
????
??? /**
???? * 利用MemCached對象將集合存入緩存,并從緩存中取出
???? */
??? @SuppressWarnings({ "unchecked", "rawtypes" })
??? public static void main(String[] args) {
?????? // 得到MemcachedManager實(shí)例
?????? MemcachedManager cache = MemcachedManager.getInstance();
???????
?????? // 創(chuàng)建UserDao對象
?????? UserDao userDao = new UserDao();
?????? // 得到集合對象
?????? List userList = userDao.getUserList();
???????
?????? // 創(chuàng)建User對象
?????? User user = null;
?????? for (int i=0; i<userList.size(); i++)
?????? {
?????????? // 循環(huán)遍歷集合對象
?????????? user = (User)userList.get(i);
?????????? user.getUid();
?????????? user.getUname();
?????????? user.getUpass();
???????????
?????????? // 將集合對象存入緩存中
?????????? cache.add("userList" + i,user.getUname());
???????????
?????????? // 將集合從緩存中取出
?????????? String uname = (String)cache.get("userList"+i);
???????????
?????????? System.out.println("從緩存中取得的集合為:" + uname);
?????? }
??? }
}
結(jié)果從控制臺輸出:
從緩存中取得的集合為:uname
從緩存中取得的集合為:uname1
從緩存中取得的集合為:uname2
從緩存中取得的集合為:uname3
1緩存為什么要存在?
2緩存可以存在于什么地方?
3緩存有哪些屬性?
4緩存介質(zhì)?
搞清楚這4個(gè)問題,那么我們就可以隨意的通過應(yīng)用的場景來判斷使用何種緩存了.
1. 緩存為什么要存在?
一 般情況下,一個(gè)網(wǎng)站,或者一個(gè)應(yīng)用,它的一般形式是,瀏覽器請求應(yīng)用服務(wù)器,應(yīng)用服務(wù)器做一堆計(jì)算后再請求數(shù)據(jù)庫,數(shù)據(jù)庫收到請求后再作一堆計(jì)算后把數(shù)據(jù) 返回給應(yīng)用服務(wù)器,應(yīng)用服務(wù)器再作一堆計(jì)算后把數(shù)據(jù)返回給瀏覽器.這個(gè)是一個(gè)標(biāo)準(zhǔn)流程.但是隨著互連網(wǎng)的普及,上網(wǎng)的人越來越多,網(wǎng)上的信息量也越來越 多,在這兩個(gè)越來越多的情況下,我們的應(yīng)用需要支撐的并發(fā)量就越來越多.然后我們的應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器所做的計(jì)算也越來越多,但是往往我們的應(yīng)用服 務(wù)器資源是有限的,數(shù)據(jù)庫每秒中接受請求的次數(shù)也是有限的(誰叫俺們的硬盤轉(zhuǎn)速有限呢).如果利用有限的資源來提供盡可能大的吞吐量呢,一個(gè)辦法:減少計(jì) 算量,縮短請求流程(減少網(wǎng)絡(luò)io或者硬盤io),這時(shí)候緩存就可以大展手腳了.緩存的基本原理就是打破上圖中所描繪的標(biāo)準(zhǔn)流程,在這個(gè)標(biāo)準(zhǔn)流程中,任何 一個(gè)環(huán)節(jié)都可以被切斷.請求可以從緩存里取到數(shù)據(jù)直接返回.這樣不但節(jié)省了時(shí)間,提高了響應(yīng)速度,而且也節(jié)省了硬件資源.可以讓我們有限的硬件資源來服務(wù) 更多的用戶.
2 緩存可以存在于什么地方?
Java代碼
瀏覽器---?瀏覽器和app之間---?分過層的app-?數(shù)據(jù)庫
在上圖中,我們可以看到一次請求的一般流程,下面我們重新繪制這張圖,讓我們的結(jié)構(gòu)稍微復(fù)雜一點(diǎn)點(diǎn).
(將app分層)
瀏覽器---?瀏覽器和app之間---?分過層的app-?數(shù)據(jù)庫
理 論上來將,請求的任何一個(gè)環(huán)節(jié)都是緩存可以作用的地方.第一個(gè)環(huán)節(jié),瀏覽器,如果數(shù)據(jù)存在瀏覽器上,那么對用戶來說速度是最快的,因?yàn)檫@個(gè)時(shí)候根本無需網(wǎng) 絡(luò)請求.第二個(gè)環(huán)節(jié),瀏覽器和app之間,如果緩存加在這個(gè)地方,那么緩存對app來說是透明的.而且這個(gè)緩存中存放的是完整的頁面.第三個(gè)節(jié)點(diǎn),app 中本身就有幾個(gè)層次,那么緩存也可以放在不同的層次上,這一部分是情況或者場景比較復(fù)雜的部分.選擇緩存時(shí)需要謹(jǐn)慎.第四個(gè)環(huán)節(jié),數(shù)據(jù)庫中也可以有緩存, 比如說mysql的querycache.
那么也就是說在整個(gè)請求流程的任何一點(diǎn),我們都可以加緩存.但是是所有的數(shù)據(jù)都可以放進(jìn)緩存的嗎.當(dāng)然不是,需要放進(jìn)緩存的數(shù)據(jù)總是有一些特征的,要清楚的判斷數(shù)據(jù)是否可以被緩存,可以被怎樣緩存就必須要從數(shù)據(jù)的變化特征下手.
數(shù) 據(jù)有哪些變化特征?最簡單的就是兩種,變和不變.我們都知道,不會變化的數(shù)據(jù)不需要每次都進(jìn)行計(jì)算.問題是難道所有的數(shù)據(jù)理論上來講都會變化,變化是世界 永恒的主題.也就是說我們把數(shù)據(jù)分為變和不變兩種是不對的,那么就讓我們再加一個(gè)條件:時(shí)間.那么我們就可以把數(shù)據(jù)特征總結(jié)為一段時(shí)間內(nèi)變或者不變.那么 根據(jù)這個(gè)數(shù)據(jù)特征,我們就可以在合適的位置和合適的緩存類型中緩存該數(shù)據(jù).
3緩存有哪些屬性
從面向?qū)ο蟮慕嵌葋砜?緩存就是一個(gè)對象,那么是對象,必然有屬性.那么下面我們來探討一下緩存有哪些屬性.以下列舉我們常用到的3個(gè)屬性.
(1) 命中率
命中率是指請求緩存次數(shù)和緩存返回正確結(jié)果次數(shù)的比例.比例越高,就證明緩存的使用率越高.
命中率問題是緩存中的一個(gè)非常重要的問題,我們都希望自己緩存的命中率能達(dá)到100%,但是往往事與愿違,而且緩存命中率是衡量緩存有效性的重要指標(biāo).
(2) 最大元素
緩存中可以存放得最大元素得數(shù)量,一旦緩存中元素?cái)?shù)量超過這個(gè)值,那么將會起用緩存清空策略,根據(jù)不同的場景合理的設(shè)置最大元素值往往可以一定程度上提高緩存的命中率.從而更有效的時(shí)候緩存.
(3) 清空策略
1 FIFO ,first in first out ,最先進(jìn)入緩存得數(shù)據(jù)在緩存空間不夠情況下(超出最大元素限制時(shí))會被首先清理出去
2 LFU , Less Frequently Used ,一直以來最少被使用的元素會被被清理掉。這就要求緩存的元素有一個(gè)hit 屬性,在緩存空間不夠得情況下,hit 值最小的將會被清出緩存。
2 LRU ,Least Recently Used ,最近最少使用的,緩存的元素有一個(gè)時(shí)間戳,當(dāng)緩存容量滿了,而又需要騰出地方來緩存新的元素的時(shí)候,那么現(xiàn)有緩存元素中時(shí)間戳離當(dāng)前時(shí)間最遠(yuǎn)的元素將被清出緩存。
4緩存介質(zhì)
從硬件介質(zhì)上來將無非就是兩種,內(nèi)存和硬盤(對應(yīng)應(yīng)用層的程序來講不用考慮寄存器等問題).但是往往我們不會從硬件上來劃分,一般的劃分方法是從技術(shù)上劃分,可以分成幾種,內(nèi)存,硬盤文件.數(shù)據(jù)庫.
(1) 內(nèi)存.將緩存放在內(nèi)存中是最快的選擇,任何程序直接操作內(nèi)存都比操作硬盤要快的多,但是如果你的數(shù)據(jù)要考慮到break down的問題,因?yàn)榉旁趦?nèi)存中的數(shù)據(jù)我們稱之為沒有持久話的數(shù)據(jù),如果硬盤上沒有備份,機(jī)器down機(jī)之后,很難或者無法恢復(fù).
(2) 硬盤.一般來說,很多緩存框架會結(jié)合使用內(nèi)存和硬盤,比如給內(nèi)存分配的空間有滿了之后,會讓用戶選擇把需要退出內(nèi)存空間的數(shù)據(jù)持久化到硬盤.當(dāng)然也選擇直 接把數(shù)據(jù)放一份到硬盤(內(nèi)存中一份,硬盤中一份,down機(jī)也不怕).也有其他的緩存是直接把數(shù)據(jù)放到硬盤上.
(3) 數(shù)據(jù)庫.說到數(shù)據(jù)庫,可能有的人會想,之前不是講到要減少數(shù)據(jù)庫查詢的次數(shù),減少數(shù)據(jù)庫計(jì)算的壓力嗎,現(xiàn)在怎么又用數(shù)據(jù)庫作為緩存的介質(zhì)了呢.這是因?yàn)閿?shù) 據(jù)庫又很多種類型,比如berkleydb,這種db不支持sql語句,沒有sql引擎,只是key和value的存儲結(jié)構(gòu),所以速度非常的快,在當(dāng)代一 般的pc上,每秒中十幾w次查詢都是沒有問題的(當(dāng)然這個(gè)是根據(jù)業(yè)務(wù)特征來決定的,如果您訪問的數(shù)據(jù)在分布上是均勻的,那ahuaxuan可不能保證這個(gè) 速度了).
除了緩存介質(zhì)之外,ahuaxuan根據(jù)緩存和應(yīng)用的耦合程度將其劃分為local cache和remote cache.
Local cache是指包含在應(yīng)用之中的緩存組件.而remote cache指和應(yīng)用解耦在應(yīng)用之外的緩存組件.典型的local cache有ehcache,oscache,而remote cache有大名鼎鼎的memcached.
Localcache 最大的優(yōu)點(diǎn)是應(yīng)用和cache的時(shí)候是在同一個(gè)進(jìn)程內(nèi)部,請求緩存非常快速,完全不需要網(wǎng)絡(luò)開銷等.所以單應(yīng)用,不需要集群或者集群情況下cache node不需要相互通知的情況下使用local cache比較合適.這也是java中ehcache和oscache這么流行的原因.
但是 Local cache是有一定的缺點(diǎn)的,一般這種緩存框架(比如java中的ehcache或者oscache)都是local cache.也就是跟著應(yīng)用程序走的,多個(gè)應(yīng)用程序無法直接共享緩存,應(yīng)用集群的情況下這個(gè)問題更加明顯,當(dāng)然也有的緩存組件提供了集群節(jié)點(diǎn)相互通知緩存 更新的功能,但是由于這個(gè)是廣播,或者是環(huán)路更新,在緩存更新頻繁的情況下會導(dǎo)致網(wǎng)絡(luò)io開銷非常大,嚴(yán)重的時(shí)候會影響應(yīng)用的正常運(yùn)行.而且如果緩存中數(shù) 據(jù)量較大得情況下使用localcache意味著每個(gè)應(yīng)用都有一份這么大得緩存,著絕對是對內(nèi)存的浪費(fèi).
所以這個(gè)情況下,往往我們會 選擇remote cache,比如memcached.這樣集群或者分布式的情況下各個(gè)應(yīng)用都可以共享memcached中的數(shù)據(jù),這些應(yīng)用都通過socket和基于 tcp/ip協(xié)議上層的memcached協(xié)議直接連接到memcached,有一個(gè)app更新了memcached中的值,所有的應(yīng)用都能拿到最新的 值.雖然這個(gè)時(shí)候多了很多了網(wǎng)絡(luò)上的開銷,但是往往這種方案要比localcache廣播或環(huán)路更新cache節(jié)點(diǎn)要普遍的多,而且性能也比后者高.由于 數(shù)據(jù)只需要保存一份,所以也提高了內(nèi)存的使用率.
通過以上分析可以看出,不管是local cache,還是remote cache在緩存領(lǐng)域都有自己的一席之地,所以ahuaxuan建議在選擇或者使用緩存時(shí)一定要根據(jù)緩存的特征和我們的業(yè)務(wù)場景準(zhǔn)確判斷使用何種緩存.這樣才能充分發(fā)揮緩存的功能.
Ahuaxuan 認(rèn)為,緩存的使用是架構(gòu)師的必備技能,好的架構(gòu)師能夠根據(jù)數(shù)據(jù)的類型,業(yè)務(wù)的場景來準(zhǔn)確的判斷出使用何種類型的緩存,并且如何使用這種類型的緩存.在緩存 的世界里也沒有銀彈,目前還沒有一種緩存可以解決任何的業(yè)務(wù)場景或者數(shù)據(jù)類型,如果這種技術(shù)出現(xiàn)了,那架構(gòu)師就又更不值錢了.呵呵.
OSCache是個(gè)一個(gè)廣泛采用的高性能的J2EE緩存框架,OSCache能用于任何Java應(yīng)用程序的普通的緩存解決方案。
OSCache有以下特點(diǎn):
緩存任何對象,你可以不受限制的緩存部分jsp頁面或HTTP請求,任何java對象都可以緩存。
擁有全面的API--OSCache API給你全面的程序來控制所有的OSCache特性。
永久緩存--緩存能隨意的寫入硬盤,因此允許昂貴的創(chuàng)建(expensive-to-create)數(shù)據(jù)來保持緩存,甚至能讓應(yīng)用重啟。
支持集群--集群緩存數(shù)據(jù)能被單個(gè)的進(jìn)行參數(shù)配置,不需要修改代碼。
緩存記錄的過期--你可以有最大限度的控制緩存對象的過期,包括可插入式的刷新策略(如果默認(rèn)性能不需要時(shí))。
官方網(wǎng)站?http://www.opensymphony.com/oscache/
Java Caching System
JSC(Java Caching System)是一個(gè)用分布式的緩存系統(tǒng),是基于服務(wù)器的java應(yīng)用程序。它是通過提供管理各種動態(tài)緩存數(shù)據(jù)來加速動態(tài)web應(yīng)用。
JCS和其他緩存系統(tǒng)一樣,也是一個(gè)用于高速讀取,低速寫入的應(yīng)用程序。
動態(tài)內(nèi)容和報(bào)表系統(tǒng)能夠獲得更好的性能。
如果一個(gè)網(wǎng)站,有重復(fù)的網(wǎng)站結(jié)構(gòu),使用間歇性更新方式的數(shù)據(jù)庫(而不是連續(xù)不斷的更新數(shù)據(jù)庫),被重復(fù)搜索出相同結(jié)果的,就能夠通過執(zhí)行緩存方式改進(jìn)其性能和伸縮性。
官方網(wǎng)站?http://jakarta.apache.org/turbine/jcs/
EHCache
EHCache 是一個(gè)純java的在進(jìn)程中的緩存,它具有以下特性:快速,簡單,為Hibernate2.1充當(dāng)可插入的緩存,最小的依賴性,全面的文檔和測試。
官方網(wǎng)站?http://ehcache.sourceforge.net/
JCache
JCache是個(gè)開源程序,正在努力成為JSR-107開源規(guī)范,JSR-107規(guī)范已經(jīng)很多年沒改變了。這個(gè)版本仍然是構(gòu)建在最初的功能定義上。
官方網(wǎng)站?http://jcache.sourceforge.net/
ShiftOne
ShiftOne Java Object Cache是一個(gè)執(zhí)行一系列嚴(yán)格的對象緩存策略的Java lib,就像一個(gè)輕量級的配置緩存工作狀態(tài)的框架。
官方網(wǎng)站?http://jocache.sourceforge.net/
SwarmCache
SwarmCache是一個(gè)簡單且有效的分布式緩存,它使用IP multicast與同一個(gè)局域網(wǎng)的其他主機(jī)進(jìn)行通訊,是特別為集群和數(shù)據(jù)驅(qū)動web應(yīng)用程序而設(shè)計(jì)的。SwarmCache能夠讓典型的讀操作大大超過寫操作的這類應(yīng)用提供更好的性能支持。
SwarmCache使用JavaGroups來管理從屬關(guān)系和分布式緩存的通訊。
官方網(wǎng)站?http://swarmcache.sourceforge.net
TreeCache / JBossCache
JBossCache是一個(gè)復(fù)制的事務(wù)處理緩存,它允許你緩存企業(yè)級應(yīng)用數(shù)據(jù)來更好的改善性能。緩存數(shù)據(jù)被自動復(fù)制,讓你輕松進(jìn)行JBoss服務(wù)器之間 的集群工作。JBossCache能夠通過JBoss應(yīng)用服務(wù)或其他J2EE容器來運(yùn)行一個(gè)MBean服務(wù),當(dāng)然,它也能獨(dú)立運(yùn)行。
JBossCache包括兩個(gè)模塊:TreeCache和TreeCacheAOP。
TreeCache --是一個(gè)樹形結(jié)構(gòu)復(fù)制的事務(wù)處理緩存。
TreeCacheAOP --是一個(gè)“面向?qū)ο蟆本彺?#xff0c;它使用AOP來動態(tài)管理POJO(Plain Old Java Objects)
注:AOP是OOP的延續(xù),是Aspect Oriented Programming的縮寫,意思是面向方面編程。
官方網(wǎng)站?http://www.jboss.org/products/jbosscache
WhirlyCache
Whirlycache是一個(gè)快速的、可配置的、存在于內(nèi)存中的對象的緩存。它能夠通過緩存對象來加快網(wǎng)站或應(yīng)用程序的速度,否則就必須通過查詢數(shù)據(jù)庫或其他代價(jià)較高的處理程序來建立。
總結(jié)
以上是生活随笔為你收集整理的java缓存技术memcached实例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: knockoutJS学习笔记01:从拼接
- 下一篇: NSMutableArray 排序