redis多数据源配置有多种方式,比如可以同时使用redisson客户端和Jedis两个数据源即可实现。
这里我讲的是怎么通过配置使用Jedis生成两个RedisTemplate实例来进行多数据源的配置
一、依赖引入
<!-- 集群redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
二、application配置文件
spring.cluster.pool1.nodes=10.200.85.185:6380,10.200.85.186:6380,10.200.85.187:6380,10.200.85.189:6380,10.200.85.190:6380,10.200.85.191:6380 spring.redis.cluster.max-redirects=2 spring.cluster.pool1.maxIdel=0 spring.cluster.pool1.maxWaitMillis=1000 spring.cluster.pool1.maxTotal=30 spring.cluster.pool1.minEvictableIdleTimeMillis=1800000 spring.cluster.pool1.minIdel=0 spring.cluster.pool1.lifo=false spring.cluster.pool1.softMinEvictableIdleTimeMillis=1800000 #redis spring.cluster.pool2.nodes=10.200.85.211:6379,10.200.85.212:6379,10.200.85.213:6379,10.200.85.214:6379,10.200.85.215:6379,10.200.85.216:6379 #spring.redis.cluster.max-redirects=2 spring.cluster.pool2.maxIdel=0 spring.cluster.pool2.maxWaitMillis=1000 spring.cluster.pool2.maxTotal=30 spring.cluster.pool2.minEvictableIdleTimeMillis=1800000 spring.cluster.pool2.minIdel=0 spring.cluster.pool2.lifo=false spring.cluster.pool2.softMinEvictableIdleTimeMillis=1800000
三、Java配置
- 读取配置属性
package com.migu.live.config.redisConfig; import com.alibaba.fastjson.JSONObject; import java.util.List; public class ClusterRedisPoolProperties { private int maxIdel; private long maxWaitMillis; private int maxTotal; private long minEvictableIdleTimeMillis; private int minIdel; private boolean lifo; private long softMinEvictableIdleTimeMillis; private List<String> nodes; public int getMaxIdel() { return maxIdel; } public void setMaxIdel(int maxIdel) { this.maxIdel = maxIdel; } public long getMaxWaitMillis() { return maxWaitMillis; } public void setMaxWaitMillis(long maxWaitMillis) { this.maxWaitMillis = maxWaitMillis; } public int getMaxTotal() { return maxTotal; } public void setMaxTotal(int maxTotal) { this.maxTotal = maxTotal; } public long getMinEvictableIdleTimeMillis() { return minEvictableIdleTimeMillis; } public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) { this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis; } public int getMinIdel() { return minIdel; } public void setMinIdel(int minIdel) { this.minIdel = minIdel; } public boolean isLifo() { return lifo; } public void setLifo(boolean lifo) { this.lifo = lifo; } public long getSoftMinEvictableIdleTimeMillis() { return softMinEvictableIdleTimeMillis; } public void setSoftMinEvictableIdleTimeMillis(long softMinEvictableIdleTimeMillis) { this.softMinEvictableIdleTimeMillis = softMinEvictableIdleTimeMillis; } public List<String> getNodes() { return nodes; } public void setNodes(List<String> nodes) { this.nodes = nodes; } @Override public String toString() { return JSONObject.toJSONString(this); } }
- 第一个redis库配置
package com.migu.live.config.redisConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import redis.clients.jedis.JedisPoolConfig; /** * @author wangcongming * @Package com.example.multidatasource.config.redis * @Description: * @date 2018/4/5 19:49 */ @Configuration @ConfigurationProperties(prefix = "spring.cluster.pool1") public class FirstRedisConfig extends ClusterRedisPoolProperties { private final static Logger log = LoggerFactory.getLogger(FirstRedisConfig.class); @Bean(name = "firstRedisConnectionFactory") @Primary public RedisConnectionFactory connectionFactory() { log.info("************初始化redis1集群************"); JedisConnectionFactory factory = new JedisConnectionFactory( new RedisClusterConfiguration(this.getNodes())); JedisPoolConfig config = factory.getPoolConfig(); config.setMaxIdle(this.getMaxIdel()); config.setMaxWaitMillis(this.getMaxWaitMillis()); config.setMaxTotal(this.getMaxTotal()); config.setMinEvictableIdleTimeMillis(this.getMinEvictableIdleTimeMillis()); config.setMinIdle(this.getMinIdel()); config.setLifo(this.isLifo()); config.setSoftMinEvictableIdleTimeMillis(this.getSoftMinEvictableIdleTimeMillis()); log.info("************初始化redis1集群结束************"); return factory; } }
- 第二个redis配置
package com.migu.live.config.redisConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisClusterConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import redis.clients.jedis.JedisPoolConfig; /** * @author wangcongming * @Package com.example.multidatasource.config.redis * @Description: * @date 2018/4/5 19:49 */ @Configuration @ConfigurationProperties(prefix = "spring.cluster.pool2") public class SecondRedisConfig extends ClusterRedisPoolProperties { private final static Logger log = LoggerFactory.getLogger(FirstRedisConfig.class); @Bean(name = "secondRedisConnectionFactory") public RedisConnectionFactory connectionFactory() { log.info("************初始化redis2集群************"); JedisConnectionFactory factory = new JedisConnectionFactory( new RedisClusterConfiguration(this.getNodes())); JedisPoolConfig config = factory.getPoolConfig(); config.setMaxIdle(this.getMaxIdel()); config.setMaxWaitMillis(this.getMaxWaitMillis()); config.setMaxTotal(this.getMaxTotal()); config.setMinEvictableIdleTimeMillis(this.getMinEvictableIdleTimeMillis()); config.setMinIdle(this.getMinIdel()); config.setLifo(this.isLifo()); config.setSoftMinEvictableIdleTimeMillis(this.getSoftMinEvictableIdleTimeMillis()); log.info("************初始化redis2集群结束************"); return factory; } }
- RedisTemplate和StringRedisTemplate具体配置
package com.migu.live.config.redisConfig; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration public class AppConfig { // private final static Logger logger = LoggerFactory.getLogger(AppConfig.class); @Autowired @Qualifier(value = "firstRedisConnectionFactory") private RedisConnectionFactory redisConnectionFactory; @Autowired @Qualifier(value = "secondRedisConnectionFactory") private RedisConnectionFactory secondRedisConnectionFactory; @Bean(name = "firstRedisTemplate") @Primary public RedisTemplate<Object,Object> redisTemplate(){ return getRedisTemplate(redisConnectionFactory); } @Bean(name = "firstStringRedisTemplate") @Primary public StringRedisTemplate stringRedisTemplate(){ return getStringRedisTemplate(redisConnectionFactory); } @Bean(name = "secondRedisTemplate") public RedisTemplate<Object,Object> secondRedisTemplate(){ return getRedisTemplate(secondRedisConnectionFactory); } @Bean(name = "secondStringRedisTemplate") public StringRedisTemplate secondStringRedisTemplate(){ return getStringRedisTemplate(secondRedisConnectionFactory); } private RedisTemplate<Object,Object> getRedisTemplate(RedisConnectionFactory connectionFactory){ RedisTemplate<Object,Object> template = new RedisTemplate<Object,Object>(); template.setConnectionFactory(connectionFactory); setSerializer(template); template.afterPropertiesSet(); return template; } private StringRedisTemplate getStringRedisTemplate(RedisConnectionFactory connectionFactory){ StringRedisTemplate template = new StringRedisTemplate(); template.setConnectionFactory(connectionFactory); setStringSerializer(template); template.afterPropertiesSet(); return template; } private void setStringSerializer(StringRedisTemplate template){ RedisSerializer<String> stringSerializer = new StringRedisSerializer(); template.setKeySerializer(stringSerializer); template.setValueSerializer(stringSerializer ); template.setHashKeySerializer(stringSerializer ); template.setHashValueSerializer(stringSerializer ); template.afterPropertiesSet(); } private void setSerializer(RedisTemplate<Object, Object> template) { Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>( Object.class); ObjectMapper om = new ObjectMapper(); om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); jackson2JsonRedisSerializer.setObjectMapper(om); template.setKeySerializer(jackson2JsonRedisSerializer); template.setValueSerializer(jackson2JsonRedisSerializer); template.setHashValueSerializer(jackson2JsonRedisSerializer); } }
四、使用示例
package com.migu.live.util; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.PostConstruct; import javax.annotation.Resource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.ListOperations; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.ZSetOperations; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; @SuppressWarnings("rawtypes") @Component public class RedisSrcUtil { @Resource(name = "firstStringRedisTemplate") private StringRedisTemplate stringRedisTemplate; @Resource(name = "firstStringRedisTemplate") private ValueOperations<String, String> stringRedisOperations; @Resource(name = "firstRedisTemplate") private RedisTemplate redisTemplate; @Resource(name = "firstRedisTemplate") private ValueOperations<String, String> redisOperations; @Resource(name = "firstStringRedisTemplate") private HashOperations<String, String, String> hMapOps; @Resource(name = "firstStringRedisTemplate") ZSetOperations<String, String> zSetOps; @Resource(name = "firstRedisTemplate") ListOperations<String, Object> listOps; /** * StringRedisTemplate<br> * 放入redis,使用默认的过期时间<br> * @param key * @param value */ public void setStringValue(final String key,String value){ stringRedisOperations.set(key, value); } /** * StringRedisTemplate<br> * 从redis取出value * @param key * @return */ public String getStringValue(final String key){ return stringRedisOperations.get(key); } /** * StringRedisTemplate<br> * 放入redis,并设置过期时间(分钟) * @param key * @param value * @param expireTime */ public void setStringValue(final String key,String value,Long expireTime){ stringRedisOperations.set(key, value); stringRedisTemplate.expire(key, expireTime, TimeUnit.MINUTES); } /** * StringRedisTemplate<br> * 判断是否存在key * @param key * @return */ public boolean hasKey(final String key){ return stringRedisTemplate.hasKey(key); } /** * StringRedisTemplate<br> * 删除相应的value * @param key */ public void remove(final String key){ stringRedisTemplate.delete(key); } public StringRedisTemplate geStringRedisTemplate(){ return this.stringRedisTemplate; } public RedisTemplate geRedisTemplate(){ return this.redisTemplate; } /** * StringRedisTemplate<br> * 批量删除对应的value * * @param keys */ public void remove(final String... keys) { for (String key : keys) { remove(key); } } /** * StringRedisTemplate<br> * 返回 StringRedisOperation * @return */ public ValueOperations<String, String> getOperations(){ return this.stringRedisOperations; } /** * RedisTemplate<br> * 获取对象类型的值 * @param key * @return */ public Object getObjectValue(String key){ return redisOperations.get(key); } /** * RedisTemplate<br> * 添加对象类型数据 * @param key * @param object */ public void setObjectValue(String key,Object object){ redisOperations.set(key, (String) object); } /** * RedisTemplate<br> * @param key * @param object * @param expireTime */ /* @SuppressWarnings("unchecked") public void setObjectValue(String key,Object object ,Long expireTime){ redisOperations.set(key, object); redisTemplate.expire(key, expireTime, TimeUnit.MINUTES); }*/ public void increment(String key,Long delta){ redisOperations.increment(key, delta); } @SuppressWarnings("unchecked") public void expire(String key,Long expireTime){ redisTemplate.expire(key, expireTime, TimeUnit.MINUTES); } public void expire(String key,Long expireTime,TimeUnit unit){ stringRedisTemplate.expire(key, expireTime, unit); } @SuppressWarnings("unchecked") public Set getKeysByPattern(String pattern){ return redisTemplate.keys(pattern); } public void setHash(String key,String hashKey ,String value) { hMapOps.put(key, hashKey, value); } public String getHashValue(String key, String mapKey) { return hMapOps.get(key, mapKey); } public Map<String, String> getHashAll(String key){ return hMapOps.entries(key); } public long setHashIncrement(String key, String hashKey, long counts) { return hMapOps.increment(key, hashKey, counts); } public long size(String key){ return hMapOps.size(key); } public long lookTimeOut(String key, TimeUnit timeUnit) { return stringRedisTemplate.getExpire(key, timeUnit); } public boolean zAddZsetElement(String key, String value, long score) { return zSetOps.add(key, value, score); } public Double getZsetScore(String key, String value) { return zSetOps.score(key, value); } public long getListSize(String key) { return listOps.size(key); } public List<Object> getList(String key) { return listOps.range(key,0L ,-1L); } public void addList(String key, List<Object> values) { if (values == null || values.size() == 0) { return; } listOps.rightPushAll(key, values); } /** * 获取自增值 * @param key * @return */ public int getIncrValue(final String key) { return stringRedisTemplate.execute(new RedisCallback<Integer>() { @Override public Integer doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = stringRedisTemplate.getStringSerializer(); byte[] rowkey=serializer.serialize(key); byte[] rowval=connection.get(rowkey); try { String val=serializer.deserialize(rowval); return Integer.parseInt(val); } catch (Exception e) { return 0; } } }); } @SuppressWarnings("unchecked") @PostConstruct public void init(){ redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); } public long delOfflineContent(String contentId,String listId){ return listOps.remove(listId,1,contentId); } }
package com.migu.live.util; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.*; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import javax.annotation.Resource; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; @SuppressWarnings("rawtypes") @Component public class SecondRedisSrcUtil { @Resource(name = "secondStringRedisTemplate") private StringRedisTemplate stringRedisTemplate; @Resource(name = "secondStringRedisTemplate") private ValueOperations<String, String> stringRedisOperations; @Resource(name = "secondRedisTemplate") private RedisTemplate redisTemplate; @Resource(name = "secondRedisTemplate") private ValueOperations<String, String> redisOperations; @Resource(name = "secondStringRedisTemplate") private HashOperations<String, String, String> hMapOps; @Resource(name = "secondStringRedisTemplate") ZSetOperations<String, String> zSetOps; @Resource(name = "secondRedisTemplate") ListOperations<String, Object> listOps; /** * StringRedisTemplate<br> * 放入redis,使用默认的过期时间<br> * @param key * @param value */ public void setStringValue(final String key,String value){ stringRedisOperations.set(key, value); } /** * StringRedisTemplate<br> * 从redis取出value * @param key * @return */ public String getStringValue(final String key){ return stringRedisOperations.get(key); } /** * StringRedisTemplate<br> * 放入redis,并设置过期时间(分钟) * @param key * @param value * @param expireTime */ public void setStringValue(final String key,String value,Long expireTime){ stringRedisOperations.set(key, value); stringRedisTemplate.expire(key, expireTime, TimeUnit.MINUTES); } /** * StringRedisTemplate<br> * 判断是否存在key * @param key * @return */ public boolean hasKey(final String key){ return stringRedisTemplate.hasKey(key); } /** * StringRedisTemplate<br> * 删除相应的value * @param key */ public void remove(final String key){ stringRedisTemplate.delete(key); } public StringRedisTemplate geStringRedisTemplate(){ return this.stringRedisTemplate; } public RedisTemplate geRedisTemplate(){ return this.redisTemplate; } /** * StringRedisTemplate<br> * 批量删除对应的value * * @param keys */ public void remove(final String... keys) { for (String key : keys) { remove(key); } } /** * StringRedisTemplate<br> * 返回 StringRedisOperation * @return */ public ValueOperations<String, String> getOperations(){ return this.stringRedisOperations; } /** * RedisTemplate<br> * 获取对象类型的值 * @param key * @return */ public Object getObjectValue(String key){ return redisOperations.get(key); } /** * RedisTemplate<br> * 添加对象类型数据 * @param key * @param object */ public void setObjectValue(String key,Object object){ redisOperations.set(key, (String) object); } /** * RedisTemplate<br> * @param key * @param object * @param expireTime */ /* @SuppressWarnings("unchecked") public void setObjectValue(String key,Object object ,Long expireTime){ redisOperations.set(key, object); redisTemplate.expire(key, expireTime, TimeUnit.MINUTES); }*/ public void increment(String key,Long delta){ redisOperations.increment(key, delta); } @SuppressWarnings("unchecked") public void expire(String key,Long expireTime){ redisTemplate.expire(key, expireTime, TimeUnit.MINUTES); } public void expire(String key,Long expireTime,TimeUnit unit){ stringRedisTemplate.expire(key, expireTime, unit); } @SuppressWarnings("unchecked") public Set getKeysByPattern(String pattern){ return redisTemplate.keys(pattern); } public void setHash(String key,String hashKey ,String value) { hMapOps.put(key, hashKey, value); } public String getHashValue(String key, String mapKey) { return hMapOps.get(key, mapKey); } public Map<String, String> getHashAll(String key){ return hMapOps.entries(key); } public long setHashIncrement(String key, String hashKey, long counts) { return hMapOps.increment(key, hashKey, counts); } public long size(String key){ return hMapOps.size(key); } public long lookTimeOut(String key, TimeUnit timeUnit) { return stringRedisTemplate.getExpire(key, timeUnit); } public boolean zAddZsetElement(String key, String value, long score) { return zSetOps.add(key, value, score); } public Double getZsetScore(String key, String value) { return zSetOps.score(key, value); } public long getListSize(String key) { return listOps.size(key); } public List<Object> getList(String key) { return listOps.range(key,0L ,-1L); } public void addList(String key, List<Object> values) { if (values == null || values.size() == 0) { return; } listOps.rightPushAll(key, values); } /** * 获取自增值 * @param key * @return */ public int getIncrValue(final String key) { return stringRedisTemplate.execute(new RedisCallback<Integer>() { @Override public Integer doInRedis(RedisConnection connection) throws DataAccessException { RedisSerializer<String> serializer = stringRedisTemplate.getStringSerializer(); byte[] rowkey=serializer.serialize(key); byte[] rowval=connection.get(rowkey); try { String val=serializer.deserialize(rowval); return Integer.parseInt(val); } catch (Exception e) { return 0; } } }); } @SuppressWarnings("unchecked") @PostConstruct public void init(){ redisTemplate.setKeySerializer(new StringRedisSerializer()); redisTemplate.setValueSerializer(new StringRedisSerializer()); } public long delOfflineContent(String contentId,String listId){ return listOps.remove(listId,1,contentId); } public Set<String> keys(String partten){ return redisTemplate.keys(partten); } public void del(String key){ redisTemplate.delete(key); } }
到此,redis多数据源就介绍完了