一般应用中,哨兵模式可以满足应用场景。当redis存储的数据量太大,单个机器已经无法满足的情况下,需要使用cluster集群。
spring-redis.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:redis.properties" />
<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 连接超时时是否阻塞,false时报异常,ture阻塞直到超时, 默认true -->
<property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<bean id="sentinelConfig" class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<!-- master名称 sentinel.conf里面配置的主节点名称 -->
<constructor-arg name="master" value="${redis.adapter.masterName}" />
<!-- sentinel的ip和端口列表 -->
<constructor-arg name="sentinelHostAndPorts">
<set>
<value>${redis.adapter.sentinel1}</value>
<value>${redis.adapter.sentinel2}</value>
<value>${redis.adapter.sentinel3}</value>
</set>
</constructor-arg>
</bean>
<!-- Spring-redis连接池管理工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<constructor-arg name="sentinelConfig" ref="sentinelConfig" />
<constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
<!-- IP地址 -->
<!-- <property name="hostName" value="${redis.host}" />
--> <!-- 端口号 -->
<!-- <property name="port" value="${redis.port}" />
--> <!-- 密码 -->
<!-- <property name="password" value="${redis.password}"></property>
--> <!-- 读取超时时间 默认2000-->
<!-- <property name="timeout" value="${redis.timeout}" />
--> <!-- 连接池配置引用 -->
<!-- <property name="poolConfig" ref="poolConfig" />
--> <!-- usePool:是否使用连接池 -->
<!-- <property name="usePool" value="true"/>
--> </bean>
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory"></property>
<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>
<bean id="redisUtil" class="redis.RedisUtil">
<property name="redisTemplate" ref="redisTemplate"></property>
</bean>
</beans>
redis.properties
redis.maxIdle=10
redis.maxTotal=20
redis.maxWaitMillis=1000
redis.blockWhenExhausted=true
redis.testOnBorrow=true
#redis.timeout=60000
defaultCacheExpireTime=60
redis.adapter.masterName=mymaster
redis.adapter.sentinel1=127.0.0.1:26379
redis.adapter.sentinel2=127.0.0.1:26479
redis.adapter.sentinel3=127.0.0.1:26579
RedisUtil.java
public class RedisUtil {
//@Autowired
@Resource private RedisTemplate redisTemplate;
public <T> void setMap(String key, Map<String, T> dataMap){
redisTemplate.opsForHash().putAll(key, dataMap);
}
public <T> void setMap(String key, Map<String, T> dataMap, long timeout, TimeUnit timeUnit){
redisTemplate.opsForHash().putAll(key, dataMap);
redisTemplate.expire(key, timeout, timeUnit);
}
public <T> Map<String, T> getMap(String key){
return redisTemplate.opsForHash().entries(key);
}
public <T> void setList(String key, List<T> dataList){
redisTemplate.opsForList().rightPushAll(key, dataList);
}
public Long getListSize(String key){
return redisTemplate.opsForList().size(key);
}
public void setObject(String key, Object value){
redisTemplate.opsForValue().set(key, value);
}
public Object getObject(String key){
return redisTemplate.opsForValue().get(key);
}
public void delete(String key){
redisTemplate.delete(key);
}
public Boolean getLock(String key, String value, long timeout, TimeUnit timeUnit){
return redisTemplate.opsForValue().setIfAbsent(key, value, timeout, timeUnit);
}
public void delLock(String key, String value){
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end ";
DefaultRedisScript<Integer> redisScript = new DefaultRedisScript<Integer>();
redisScript.setScriptText(script);
redisScript.setResultType(Integer.class);
Long res = (Long) redisTemplate.execute(redisScript, Collections.singletonList(key), value);
System.out.println(res);
}
public RedisTemplate getRedisTemplate() {
return redisTemplate;
}
public void setRedisTemplate(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
}
TestJedis.java
public class TestJedis {
//@Resource
private RedisUtil redisUtil;
public static void main(String[] args) {
TestJedis test = new TestJedis();
test.test1();
}
//@Test
public void test1(){
ApplicationContext appliction = new ClassPathXmlApplicationContext("spring-redis.xml");
redisUtil = appliction.getBean(RedisUtil.class);
// String key = "test";
// redisUtil.setObject(key, "test");
// String val = (String) redisUtil.getObject(key);
// System.out.println(val);
// redisUtil.delete(key);
// System.out.println(redisUtil.getObject(key));
int max = 100;
Thread[] threads = new Thread[max];
for(int i = 0; i < max; i++){
threads[i] = new Thread(new TestLockThread());
}
for(int i = 0; i < max; i++){
threads[i].start();
}
}
class TestLockThread implements Runnable{
private String key = "transfer_0001";
/* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run() {
Boolean getLock = redisUtil.getLock(key, Thread.currentThread().getName(), 10000, TimeUnit.MILLISECONDS);
if(getLock){
try{
System.out.println(Thread.currentThread().getName() + "开始干活了。。。。");
}finally{
redisUtil.delLock(key, Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + "over。。。。");
}
}
}
}
}