一、Redis了解
1.1、Redis介紹:
redis是一個key-value存儲系統(tǒng)。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set –有序集合)和hash(哈希類型)。這些數(shù)據(jù)類型都支持push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎(chǔ)上,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數(shù)據(jù)都是緩存在內(nèi)存中。區(qū)別的是redis會周期性的把更新的數(shù)據(jù)寫入磁盤或者把修改操作寫入追加的記錄文件,并且在此基礎(chǔ)上實現(xiàn)了master-slave(主從)同步。
Redis數(shù)據(jù)庫完全在內(nèi)存中,使用磁盤僅用于持久性。相比許多鍵值數(shù)據(jù)存儲,Redis擁有一套較為豐富的數(shù)據(jù)類型。Redis可以將數(shù)據(jù)復(fù)制到任意數(shù)量的從服務(wù)器。
1.2、Redis優(yōu)點:
(1)異??焖伲篟edis的速度非???,每秒能執(zhí)行約11萬集合,每秒約81000+條記錄。
(2)支持豐富的數(shù)據(jù)類型:Redis支持最大多數(shù)開發(fā)人員已經(jīng)知道像列表,集合,有序集合,散列數(shù)據(jù)類型。這使得它非常容易解決各種各樣的問題,因為我們知道哪些問題是可以處理通過它的數(shù)據(jù)類型更好。
(3)操作都是原子性:所有Redis操作是原子的,這保證了如果兩個客戶端同時訪問的Redis服務(wù)器將獲得更新后的值。
(4)多功能實用工具:Redis是一個多實用的工具,可以在多個用例如緩存,消息,隊列使用(Redis原生支持發(fā)布/訂閱),任何短暫的數(shù)據(jù),應(yīng)用程序,如Web應(yīng)用程序會話,網(wǎng)頁命中計數(shù)等。
1.3、Redis缺點:
(1)單線程
(2)耗內(nèi)存
二、64位windows下Redis安裝
Redis官方是不支持windows的,但是Microsoft Open Tech group 在 GitHub上開發(fā)了一個Win64的版本,下載地址:https://github.com/MSOpenTech/redis/releases。注意只支持64位哈。
小寶鴿是下載了Redis-x64-3.0.500.msi進行安裝。安裝過程中全部采取默認(rèn)即可。
安裝完成之后可能已經(jīng)幫你開啟了Redis對應(yīng)的服務(wù),博主的就是如此。查看資源管理如下,說明已經(jīng)開啟:
已經(jīng)開啟了對應(yīng)服務(wù)的,我們讓它保持,下面例子需要用到。如果沒有開啟的,我們命令開啟,進入Redis的安裝目錄(博主的是C:\Program Files\Redis),然后如下命令開啟:
redis-server redis.windows.conf
OK,下面我們進行實例。
三、詳細(xì)實例
本工程采用的環(huán)境:Eclipse + maven + spring + junit
3.1、添加相關(guān)依賴(spring+junit+redis依賴),pom.xml:
project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
modelVersion>4.0.0/modelVersion>
groupId>com.luo/groupId>
artifactId>redis_project/artifactId>
version>0.0.1-SNAPSHOT/version>
properties>
!-- spring版本號 -->
spring.version>3.2.8.RELEASE/spring.version>
!-- junit版本號 -->
junit.version>4.10/junit.version>
/properties>
dependencies>
!-- 添加Spring依賴 -->
dependency>
groupId>org.springframework/groupId>
artifactId>spring-core/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-webmvc/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-context/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-context-support/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-aop/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-aspects/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-tx/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-jdbc/artifactId>
version>${spring.version}/version>
/dependency>
dependency>
groupId>org.springframework/groupId>
artifactId>spring-web/artifactId>
version>${spring.version}/version>
/dependency>
!--單元測試依賴 -->
dependency>
groupId>junit/groupId>
artifactId>junit/artifactId>
version>${junit.version}/version>
scope>test/scope>
/dependency>
!--spring單元測試依賴 -->
dependency>
groupId>org.springframework/groupId>
artifactId>spring-test/artifactId>
version>${spring.version}/version>
scope>test/scope>
/dependency>
!-- Redis 相關(guān)依賴 -->
dependency>
groupId>org.springframework.data/groupId>
artifactId>spring-data-redis/artifactId>
version>1.6.1.RELEASE/version>
/dependency>
dependency>
groupId>redis.clients/groupId>
artifactId>jedis/artifactId>
version>2.7.3/version>
/dependency>
/dependencies>
/project>
3.2、spring配置文件application.xml:
?xml version="1.0" encoding="UTF-8"?>
beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
!-- 自動掃描注解的bean -->
context:component-scan base-package="com.luo.service" />
!-- 引入properties配置文件 -->
bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
property name="locations">
list>
value>classpath:properties/*.properties/value>
!--要是有多個配置文件,只需在這里繼續(xù)添加即可 -->
/list>
/property>
/bean>
!-- jedis 配置 -->
bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig" >
property name="maxIdle" value="${redis.maxIdle}" />
property name="maxWaitMillis" value="${redis.maxWait}" />
property name="testOnBorrow" value="${redis.testOnBorrow}" />
/bean >
!-- redis服務(wù)器中心 -->
bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
property name="poolConfig" ref="poolConfig" />
property name="port" value="${redis.port}" />
property name="hostName" value="${redis.host}" />
!-- property name="password" value="${redis.password}" /> -->
property name="timeout" value="${redis.timeout}" >/property>
/bean >
bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
property name="connectionFactory" ref="connectionFactory" />
property name="keySerializer" >
bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
/property>
property name="valueSerializer" >
bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
/property>
/bean >
!-- cache配置 -->
bean id="methodCacheInterceptor" class="com.luo.redis.cache.MethodCacheInterceptor" >
property name="redisTemplate" ref="redisTemplate" />
/bean >
!-- aop配置切點跟通知 -->
bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
property name="advice" ref="methodCacheInterceptor"/>
property name="pattern" value=".*ServiceImpl.*getTimestamp"/>
/bean>
bean id="redisTestService" class="com.luo.service.impl.RedisTestServiceImpl">
/bean>
bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
/beans>
3.3、Redis配置參數(shù),redis.properties:
#redis中心
#綁定的主機地址
redis.host=127.0.0.1
#指定Redis監(jiān)聽端口,默認(rèn)端口為6379
redis.port=6379
#授權(quán)密碼(本例子沒有使用)
redis.password=123456
#最大空閑數(shù):空閑鏈接數(shù)大于maxIdle時,將進行回收
redis.maxIdle=100
#最大連接數(shù):能夠同時建立的“最大鏈接個數(shù)”
redis.maxActive=300
#最大等待時間:單位ms
redis.maxWait=1000
#使用連接時,檢測連接是否成功
redis.testOnBorrow=true
#當(dāng)客戶端閑置多長時間后關(guān)閉連接,如果指定為0,表示關(guān)閉該功能
redis.timeout=10000
3.4、添加接口及對應(yīng)實現(xiàn)RedisTestService.Java和RedisTestServiceImpl.java:
package com.luo.service;
public interface RedisTestService {
public String getTimestamp(String param);
}
package com.luo.service.impl;
import org.springframework.stereotype.Service;
import com.luo.service.RedisTestService;
@Service
public class RedisTestServiceImpl implements RedisTestService {
public String getTimestamp(String param) {
Long timestamp = System.currentTimeMillis();
return timestamp.toString();
}
}
3.5、本例采用spring aop切面方式進行緩存,配置已在上面spring配置文件中,對應(yīng)實現(xiàn)為MethodCacheInterceptor.java:
package com.luo.redis.cache;
import java.io.Serializable;
import java.util.concurrent.TimeUnit;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
public class MethodCacheInterceptor implements MethodInterceptor {
private RedisTemplateSerializable, Object> redisTemplate;
private Long defaultCacheExpireTime = 10l; // 緩存默認(rèn)的過期時間,這里設(shè)置了10秒
public Object invoke(MethodInvocation invocation) throws Throwable {
Object value = null;
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
String key = getCacheKey(targetName, methodName, arguments);
try {
// 判斷是否有緩存
if (exists(key)) {
return getCache(key);
}
// 寫入緩存
value = invocation.proceed();
if (value != null) {
final String tkey = key;
final Object tvalue = value;
new Thread(new Runnable() {
public void run() {
setCache(tkey, tvalue, defaultCacheExpireTime);
}
}).start();
}
} catch (Exception e) {
e.printStackTrace();
if (value == null) {
return invocation.proceed();
}
}
return value;
}
/**
* 創(chuàng)建緩存key
*
* @param targetName
* @param methodName
* @param arguments
*/
private String getCacheKey(String targetName, String methodName,
Object[] arguments) {
StringBuffer sbu = new StringBuffer();
sbu.append(targetName).append("_").append(methodName);
if ((arguments != null) (arguments.length != 0)) {
for (int i = 0; i arguments.length; i++) {
sbu.append("_").append(arguments[i]);
}
}
return sbu.toString();
}
/**
* 判斷緩存中是否有對應(yīng)的value
*
* @param key
* @return
*/
public boolean exists(final String key) {
return redisTemplate.hasKey(key);
}
/**
* 讀取緩存
*
* @param key
* @return
*/
public Object getCache(final String key) {
Object result = null;
ValueOperationsSerializable, Object> operations = redisTemplate
.opsForValue();
result = operations.get(key);
return result;
}
/**
* 寫入緩存
*
* @param key
* @param value
* @return
*/
public boolean setCache(final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperationsSerializable, Object> operations = redisTemplate
.opsForValue();
operations.set(key, value);
redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public void setRedisTemplate(
RedisTemplateSerializable, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
3.6、單元測試相關(guān)類:
package com.luo.baseTest;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//指定bean注入的配置文件
@ContextConfiguration(locations = { "classpath:application.xml" })
//使用標(biāo)準(zhǔn)的JUnit @RunWith注釋來告訴JUnit使用Spring TestRunner
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTestCase extends AbstractJUnit4SpringContextTests {
}
package com.luo.service;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.luo.baseTest.SpringTestCase;
public class RedisTestServiceTest extends SpringTestCase {
@Autowired
private RedisTestService redisTestService;
@Test
public void getTimestampTest() throws InterruptedException{
System.out.println("第一次調(diào)用:" + redisTestService.getTimestamp("param"));
Thread.sleep(2000);
System.out.println("2秒之后調(diào)用:" + redisTestService.getTimestamp("param"));
Thread.sleep(11000);
System.out.println("再過11秒之后調(diào)用:" + redisTestService.getTimestamp("param"));
}
}
3.7、運行結(jié)果:
四、源碼下載:redis-project(jb51.net).rar
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助。
您可能感興趣的文章:- 圖文詳解Windows下使用Redis緩存工具的方法
- window手動操作清理redis緩存的技巧總結(jié)