引用
一、redis-cluster构造
引用
二、与spring-data-redis集成
1.JedisCluster
以集群方式使用连接池,来直接使用redis相关命令。
spring.xml
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxTotal}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> <property name="testOnReturn" value="${redis.testOnReturn}" /> </bean> <bean id="redisConnectionFactory" class="com.sinowel.eacpa.test.JedisClusterFactory"> <property name="addressConfig"> <value>classpath:connect-redis.properties</value> </property> <!-- 属性文件里 key的前缀 --> <property name="addressKeyPrefix" value="address" /> <property name="timeout" value="300000" /> <property name="maxRedirections" value="6" /> <property name="genericObjectPoolConfig" ref="jedisPoolConfig" /> </bean>
connect-redis.properties
address1=192.168.71.188:6380 address2=192.168.71.188:6381 address3=192.168.71.188:6382 address4=192.168.71.188:7380 address5=192.168.71.188:7381 address6=192.168.71.188:7382
import java.util.HashSet; 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 FactoryBean<JedisCluster>, 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 JedisCluster getObject() throws Exception { return jedisCluster; } @Override public Class<? extends JedisCluster> getObjectType() { return (this.jedisCluster != null ? this.jedisCluster.getClass() : JedisCluster.class); } @Override public boolean isSingleton() { return true; } private Set<HostAndPort> parseHostAndPort() throws Exception { try { Properties prop = new Properties(); prop.load(this.addressConfig.getInputStream()); Set<HostAndPort> haps = new HashSet<HostAndPort>(); for (Object key : prop.keySet()) { if (!((String) key).startsWith(addressKeyPrefix)) { continue; } String val = (String) prop.get(key); boolean isIpPort = p.matcher(val).matches(); if (!isIpPort) { throw new IllegalArgumentException("ip 或 port 不合法"); } String[] ipAndPort = val.split(":"); HostAndPort hap = new HostAndPort(ipAndPort[0], Integer.parseInt(ipAndPort[1])); haps.add(hap); } return haps; } catch (IllegalArgumentException ex) { throw ex; } catch (Exception ex) { throw new Exception("解析 jedis 配置文件失败", ex); } } @Override public void afterPropertiesSet() throws Exception { Set<HostAndPort> haps = this.parseHostAndPort(); jedisCluster = new JedisCluster(haps, timeout, maxRedirections,genericObjectPoolConfig); // jedisCluster = new JedisCluster(haps, timeout, genericObjectPoolConfig); } public void setAddressConfig(Resource addressConfig) { this.addressConfig = addressConfig; } public void setTimeout(int timeout) { this.timeout = timeout; } public void setMaxRedirections(int maxRedirections) { this.maxRedirections = maxRedirections; } public void setAddressKeyPrefix(String addressKeyPrefix) { this.addressKeyPrefix = addressKeyPrefix; } public void setGenericObjectPoolConfig(GenericObjectPoolConfig genericObjectPoolConfig) { this.genericObjectPoolConfig = genericObjectPoolConfig; } }
引用
2.RedisTemplate
以集群方式使用连接池,来使用模板进行数据操作,key与value自动序列化存储。
spring.xml
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxTotal" value="${redis.maxTotal}" /> <property name="maxIdle" value="${redis.maxIdle}" /> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> <property name="testOnReturn" value="${redis.testOnReturn}" /> </bean> <!-- <bean id="redisNode" class="org.springframework.data.redis.connection.RedisNode"> <property name=""></property> </bean> --> <bean id="redisClusterConfig" class="org.springframework.data.redis.connection.RedisClusterConfiguration"> <property name="maxRedirects" value="3" /> <property name="clusterNodes"> <set> <!-- <ref bean="redisNode" /> --> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.71.188"></constructor-arg> <constructor-arg name="port" value="7380"></constructor-arg> </bean> <!-- <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.71.188"></constructor-arg> <constructor-arg name="port" value="6381"></constructor-arg> </bean> <bean class="org.springframework.data.redis.connection.RedisNode"> <constructor-arg name="host" value="192.168.71.188"></constructor-arg> <constructor-arg name="port" value="6382"></constructor-arg> </bean> --> </set> </property> </bean> <bean id="redis4CacheConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"> <constructor-arg name="clusterConfig" ref="redisClusterConfig" /> <property name="hostName" value="${redis.host}"/> <property name="port" value="${redis.port}"/> <property name="timeout" value="${redis.timeout}" /> <property name="poolConfig" ref="jedisPoolConfig"/> </bean> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id="redis4CacheTemplate" class="org.springframework.data.redis.core.RedisTemplate"> <property name="connectionFactory" ref="redis4CacheConnectionFactory" /> <!-- <property name="keySerializer"> <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" /> </property> --> <property name="keySerializer" ref="stringRedisSerializer" /> <property name="hashKeySerializer" ref="stringRedisSerializer" /> <property name="valueSerializer" ref="stringRedisSerializer" /> <property name="hashValueSerializer" ref="stringRedisSerializer" /> </bean>
引用
spring-data-redis提供了多种serializer策略,这对使用jedis的开发者而言,实在是非常便捷。sdr提供了4种内置的serializer:
JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储
StringRedisSerializer:字符串编码,数据以string存储
JacksonJsonRedisSerializer:json格式存储
OxmSerializer:xml格式存储
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,其中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。
RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:
1) keySerializer :对于普通K-V操作时,key采取的序列化策略
2) valueSerializer:value采取的序列化策略
3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
4) hashValueSerializer:hash-value的序列化策略
无论如何,建议key/hashKey采用StringRedisSerializer。
http://www.360doc.com/content/15/0513/21/1073512_470277654.shtml
JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储
StringRedisSerializer:字符串编码,数据以string存储
JacksonJsonRedisSerializer:json格式存储
OxmSerializer:xml格式存储
其中JdkSerializationRedisSerializer和StringRedisSerializer是最基础的序列化策略,其中“JacksonJsonRedisSerializer”与“OxmSerializer”都是基于stirng存储,因此它们是较为“高级”的序列化(最终还是使用string解析以及构建java对象)。
RedisTemplate中需要声明4种serializer,默认为“JdkSerializationRedisSerializer”:
1) keySerializer :对于普通K-V操作时,key采取的序列化策略
2) valueSerializer:value采取的序列化策略
3) hashKeySerializer: 在hash数据结构中,hash-key的序列化策略
4) hashValueSerializer:hash-value的序列化策略
无论如何,建议key/hashKey采用StringRedisSerializer。
http://www.360doc.com/content/15/0513/21/1073512_470277654.shtml
3. 测试代码
@Service public class TestService { @Resource private JedisCluster redisConnectionFactory; // @Resource private RedisTemplate redis4CacheTemplate; public void test() { System.out.println(redisConnectionFactory.get("t1")); System.out.println(redisConnectionFactory.get("aa")); System.out.println(redisConnectionFactory.get("cc")); System.out.println("----------------"); redis4CacheTemplate.opsForValue().set("aa", "300人"); redis4CacheTemplate.opsForValue().set("cc", "AA1"); redis4CacheTemplate.opsForValue().set("t4", "BB"); System.out.println(redis4CacheTemplate.opsForValue().get("aa")); System.out.println(redis4CacheTemplate.opsForValue().get("cc")); System.out.println(redis4CacheTemplate.opsForValue().get("t44")); } }
import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.BlockJUnit4ClassRunner; import com.sinowel.eacpa.BaseTest; import com.sinowel.eacpa.test.service.TestService; @RunWith(BlockJUnit4ClassRunner.class) public class TestDemo extends BaseTest{ public TestDemo() { super("classpath:spring/spring.xml"); } @Test //测试构造注入 public void testCons() { TestService service = super.getBean("testService"); service.test(); System.out.println("success"); } }
控制台输出:
100 300人 AA1 ---------------- 300人 AA1 null