1.哨兵:
applicationContext.xml:
<!-- redis sentinel 配置 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="${im.hs.server.redis.maxTotal}" />
<property name="minIdle" value="${im.hs.server.redis.minIdle}" />
<property name="maxWaitMillis" value="${im.hs.server.redis.maxWaitTime}" />
<property name="maxIdle" value="${im.hs.server.redis.maxIdle}" />
<property name="testOnBorrow" value="${im.hs.server.redis.testOnBorrow}" />
<property name="testOnReturn" value="true" />
<property name="testWhileIdle" value="true" />
</bean>
<bean id="sentinelConfiguration"
class="org.springframework.data.redis.connection.RedisSentinelConfiguration">
<property name="master">
<bean class="org.springframework.data.redis.connection.RedisNode">
<property name="name" value="${im.hs.server.redis.sentinel.masterName}"></property>
</bean>
</property>
<property name="sentinels">
<set>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host"
value="${im.hs.server.redis.sentinel1.host}"></constructor-arg>
<constructor-arg name="port"
value="${im.hs.server.redis.sentinel1.port}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host"
value="${im.hs.server.redis.sentinel2.host}"></constructor-arg>
<constructor-arg name="port"
value="${im.hs.server.redis.sentinel2.port}"></constructor-arg>
</bean>
<bean class="org.springframework.data.redis.connection.RedisNode">
<constructor-arg name="host"
value="${im.hs.server.redis.sentinel3.host}"></constructor-arg>
<constructor-arg name="port"
value="${im.hs.server.redis.sentinel3.port}"></constructor-arg>
</bean>
</set>
</property>
</bean>
<bean id="sentinelConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="password" value="${im.hs.server.redis.sentinel.password}"></property>
<constructor-arg name="sentinelConfig" ref="sentinelConfiguration"></constructor-arg>
<constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg>
</bean>
<!-- redis sentinel 配置结束 -->
redis-sentinel.properties:
# Redis settings
#sentinel1的IP和端口
im.hs.server.redis.sentinel1.host=192.168.126.131
im.hs.server.redis.sentinel1.port=26379
#sentinel2的IP和端口
im.hs.server.redis.sentinel2.host=192.168.126.132
im.hs.server.redis.sentinel2.port=26380
#sentinel3的IP和端口
im.hs.server.redis.sentinel3.host=192.168.126.133
im.hs.server.redis.sentinel3.port=26381
#sentinel的鉴权密码
im.hs.server.redis.sentinel.masterName=mymaster
im.hs.server.redis.sentinel.password=12345678
#最大闲置连接数
im.hs.server.redis.maxIdle=500
#最大连接数,超过此连接时操作redis会报错
im.hs.server.redis.maxTotal=5000
im.hs.server.redis.maxWaitTime=1000
im.hs.server.redis.testOnBorrow=true
#最小闲置连接数,spring启动的时候自动建立该数目的连接供应用程序使用,不够的时候会申请。
im.hs.server.redis.minIdle=300
测试:
package com.shidebin.mongodb.spring_redis;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.CollectionUtils;
import com.alibaba.fastjson.JSON;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisSentinelTest {
@Autowired
public ValueOperations<String,String> stringRedisTemplate;
@Autowired
public HashOperations<String,String,String> hashRedisTemplate;
@Autowired
public ListOperations<String,String> listRedisTemplate;
@Autowired
public SetOperations<String,String> setRedisTemplate;
@Autowired
public ZSetOperations<String,String> zSetRedisTemplate;
@Test
public void set() {
//set name shidebin
stringRedisTemplate.set("name", "shidebin");
//保存对象
User user = User.getUserBuilder().name("shidebin").age(29).sex("男").build();
String jsonString = JSON.toJSONString(user);
stringRedisTemplate.set("user:1", jsonString);
//保存list
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
String listJson = JSON.toJSONString(list);
stringRedisTemplate.set("list", listJson);
//保存map
Map<String,String> map = new HashMap<String,String>();
map.put("name", "shidebin");
map.put("age", "29");
map.put("phone", "18615412359");
String mapJson = JSON.toJSONString(map);
stringRedisTemplate.set("map", mapJson);
//mset country china city beijing
stringRedisTemplate.multiSet(map);
}
@SuppressWarnings("unchecked")
@Test
public void get() {
//取string
String name = stringRedisTemplate.get("name");
System.out.println(name);
//取对象
String userStr = stringRedisTemplate.get("user:1");
User parseObject = JSON.parseObject(userStr, User.class);
System.out.println(userStr);
System.out.println(parseObject);
//取list
String listStr = stringRedisTemplate.get("list");
List<String> parseObject2 = JSON.parseArray(listStr, String.class);
System.out.println(listStr);
System.out.println(parseObject2);
//取map
String mapStr = stringRedisTemplate.get("map");
Map<String,String> parseObject3 = JSON.parseObject(mapStr, Map.class);
System.out.println(mapStr);
System.out.println(parseObject3);
//mget country city address
List<String> multiGet = stringRedisTemplate.multiGet(Arrays.asList("name","age","phone"));
System.out.println(multiGet);
}
//hash
@Test
public void hSet() {
Map<String,String> map = new HashMap<String,String>();
map.put("name", "shidebin");
map.put("age", "29");
map.put("phone", "18615412359");
hashRedisTemplate.putAll("user:2", map);
}
@Test
public void hGet() {
Map<String, String> entries = hashRedisTemplate.entries("user:2");
System.out.println(entries);
}
//list
@Test
public void lpush() {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
listRedisTemplate.leftPushAll("list:1", list);
}
@Test
public void lget() {
List<String> range = listRedisTemplate.range("list:1", 0, -1);
System.out.println(range);
}
//list
@Test
public void sset() {
List<String> list = new ArrayList<String>();
list.add("aaa");
list.add("bbb");
list.add("ccc");
setRedisTemplate.add("set:1", list.toArray(new String[] {}));
}
@Test
public void sget() {
Set<String> members = setRedisTemplate.members("set:1");
System.out.println(members);
}
//list
@Test
public void zpush() {
Set<TypedTuple<String>> set = new HashSet<TypedTuple<String>>();
TypedTuple<String> tt = new DefaultTypedTuple<String>("shidebin",Double.valueOf(23));
set.add(tt);
zSetRedisTemplate.add("zset",set);
}
@Test
public void zget() {
Set<TypedTuple<String>> rangeWithScores = zSetRedisTemplate.rangeWithScores("zset", 0, -1);
rangeWithScores.stream().forEach(action -> {
System.out.println(action.getScore());
System.out.println(action.getValue());
});
}
}
cluster配置:
applicationContext.xml:
<!-- cluster 集群配置 -->
<bean id="genericObjectPoolConfig" class="org.apache.commons.pool2.impl.GenericObjectPoolConfig">
<property name="maxTotal" value="${maxTotal}" />
<property name="minIdle" value="${minIdle}" />
<property name="maxIdle" value="${maxIdle}" />
<property name="maxWaitMillis" value="${maxWaitMillis}" />
<property name="testOnBorrow" value="${testOnBorrow}" />
</bean>
<bean id="jedisCluster" class="com.shidebin.mongodb.spring_redis.JedisClusterFactory">
<property name="addressConfig" value="classpath:redis-cluster.properties"/>
<property name="addressKeyPrefix" value="address" />
<property name="timeout" value="${timeout}" />
<!--代表集群有几台redis-->
<property name="maxRedirections" value="${maxRedirections}" />
<property name="genericObjectPoolConfig" ref="genericObjectPoolConfig" />
</bean>
<!-- redis cluster 集群配置结束 -->
redis_cluster.properties:
address1=192.168.126.128:6379
address2=192.168.126.129:6380
address3=192.168.126.130:6381
address4=192.168.126.131:6389
address5=192.168.126.132:6390
address6=192.168.126.133:6391
#最大连接数
maxTotal=1024
#客户端超时时间单位是毫秒
timeout=300000
#最大连接数
maxActive=1024
#最小空闲数
minIdle=8
#最大空闲数
maxIdle=100
#最大建立连接等待时间
maxWaitMillis=1000
#redis集群单位数
maxRedirections=6
testOnBorrow=true
JedisClusterFactory类:
package com.shidebin.mongodb.spring_redis;
import java.io.IOException;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.Resource;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
public class JedisClusterFactory implements InitializingBean{
private Resource addressConfig;
private String addressKeyPrefix;
private JedisCluster jedisCluster;
private Integer timeout;
private Integer maxRedirections;
private GenericObjectPoolConfig genericObjectPoolConfig;
private Pattern p = Pattern.compile("^.+[:]\\d{1,5}\\s*$");
@Override
public void afterPropertiesSet() throws Exception {
Set<HostAndPort> nodes = getNodes();
this.jedisCluster = new JedisCluster(nodes,timeout,maxRedirections,genericObjectPoolConfig);
}
private Set<HostAndPort> getNodes(){
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
Properties source = new Properties();
try {
source.load(this.addressConfig.getInputStream());
for(Iterator<Object> ite = source.keySet().iterator();ite.hasNext();){
String key = ite.next().toString();
if(key.startsWith(addressKeyPrefix)) {
String val = source.getProperty(key);
boolean isAddress = p.matcher(val).matches();
if(!isAddress) {
throw new IllegalArgumentException("cluster 地址格式不对");
}
HostAndPort hap = new HostAndPort(val.split(":")[0],Integer.parseInt(val.split(":")[1]));
nodes.add(hap);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return nodes;
}
public void setAddressConfig(Resource addressConfig) {
this.addressConfig = addressConfig;
}
public void setAddressKeyPrefix(String addressKeyPrefix) {
this.addressKeyPrefix = addressKeyPrefix;
}
public void setTimeout(Integer timeout) {
this.timeout = timeout;
}
public void setMaxRedirections(Integer maxRedirections) {
this.maxRedirections = maxRedirections;
}
public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) {
this.genericObjectPoolConfig = genericObjectPoolConfig;
}
public JedisCluster getJedisCluster() {
return jedisCluster;
}
}
JedisCluster实例也可以通过FactoryBean来实现,此类直接用了get()方法,目前不清楚俩种方法的优劣,目测get()更为简便。
测试:
package com.shidebin.mongodb.spring_redis;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import redis.clients.jedis.JedisCluster;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class RedisClusterTest {
@Autowired
JedisClusterFactory jf;
@Test
public void testCluster() {
JedisCluster jedisCluster = jf.getJedisCluster();
String set = jedisCluster.set("abd".getBytes(), "fasdfjklasd".getBytes());
System.out.println(set);
}
}
git上工程地址:https://github.com/shidebin/redis/tree/master/spring-redis