记得上下班打卡 | git大法好,push需谨慎

Commit ea45e5ae authored by anjiabin's avatar anjiabin

实现redis分库工具类

parent bdf00ef1
package com.liquidnet.common.cache.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Created by Administrator on 2017/2/8.
*/
@Configuration
public class RedisCacheConfig{
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
redisTemplate.setConnectionFactory(factory);
Jackson2JsonRedisSerializer j2jrs = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new JavaTimeModule());
om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
j2jrs.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
redisTemplate.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
redisTemplate.setValueSerializer(j2jrs);
// hash的value序列化方式采用jackson
redisTemplate.setHashValueSerializer(j2jrs);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
package com.liquidnet.common.cache.redis.config;//package com.liquidnet.common.cache.redis.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
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.StringRedisSerializer;
import javax.annotation.PostConstruct;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: RedisConfig
* @Package com.liquidnet.common.cache.redis.config
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/8/10 16:28
*/
@Slf4j
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.lettuce.pool.max-active}")
private int maxActive;
@Value("${spring.redis.lettuce.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.lettuce.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.lettuce.pool.max-wait}")
private int maxWait;
public static int defaultDb = 0;
public static int totalDbs = 1;
@Value("${spring.redis.dbs:${spring.redis.database}}")
private List<Integer> dbs;
public static Map<Integer, RedisTemplate<String, Object>> redisTemplateMap = new HashMap<>();
@PostConstruct
public void initRedisTemp() throws Exception {
log.info("###### START 初始化 Redis 连接池 START ######");
defaultDb = dbs.get(0);
if(dbs.size()==2&&dbs.get(1)!=null){
totalDbs = dbs.get(1);
log.info("init totalDbs : {}",totalDbs);
for (int i = 0;i < totalDbs; i++) {
log.info("###### 正在加载Redis-db-" + i+ " ######");
redisTemplateMap.put(i, getRedisTemplate(i));
}
}else{
log.info("init defaultDb : {}",defaultDb);
redisTemplateMap.put(defaultDb, getRedisTemplate(defaultDb));
}
log.info("###### END 初始化 Redis 连接池 END ######");
}
private RedisTemplate<String, Object> getRedisTemplate(int dbNo) {
return getRedisTemplate(getDbFactory(dbNo));
}
private LettuceConnectionFactory getDbFactory(int dbNo){
LettuceConnectionFactory factory = new LettuceConnectionFactory(getRedisConfig(dbNo), getClientConfig());
factory.afterPropertiesSet();//必须初始化实例
return factory;
}
private RedisStandaloneConfiguration getRedisConfig(int dbNo) {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(host);
config.setPort(port);
config.setPassword(password);
config.setDatabase(dbNo);
return config;
}
private LettuceClientConfiguration getClientConfig() {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
poolConfig.setMaxTotal(maxActive);
poolConfig.setMaxIdle(maxIdle);
poolConfig.setMinIdle(minIdle);
poolConfig.setMaxWaitMillis(maxWait);
return LettucePoolingClientConfiguration.builder().poolConfig(poolConfig).build();
}
private RedisTemplate<String, Object> getRedisTemplate(LettuceConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
setSerializer(redisTemplate);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
public RedisTemplate<String, Object> getRedisTemplateByDb(int db){
return redisTemplateMap.get(db);
}
@Bean
public RedisTemplate redisTemplate() {
LettuceConnectionFactory factory = null;
if(totalDbs==1){
factory = getDbFactory(defaultDb);
}else{
factory = getDbFactory(totalDbs-1);
}
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(factory);
setSerializer(redisTemplate);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate() {
LettuceConnectionFactory factory = null;
if(totalDbs==1){
factory = getDbFactory(defaultDb);
}else{
factory = getDbFactory(totalDbs-1);
}
StringRedisTemplate redisTemplate = new StringRedisTemplate();
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
private void setSerializer(RedisTemplate<String, Object> template) {
Jackson2JsonRedisSerializer j2jrs = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
om.registerModule(new JavaTimeModule());
om.activateDefaultTyping(om.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
j2jrs.setObjectMapper(om);
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用String的序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用String的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value序列化方式采用jackson
template.setValueSerializer(j2jrs);
// hash的value序列化方式采用jackson
template.setHashValueSerializer(j2jrs);
template.afterPropertiesSet();
}
}
\ No newline at end of file
package com.liquidnet.common.cache.redis.util;
import com.liquidnet.common.cache.redis.config.RedisConfig;
import lombok.extern.slf4j.Slf4j;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: MathUtil
* @Package com.liquidnet.common.cache.redis.util
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/8/10 18:03
*/
@Slf4j
public class MathUtil {
public static int getIndex(String key){
log.info("MathUtil.getIndex key:{} hashcode:{}",key,key.hashCode());
int defaultDb = RedisConfig.defaultDb;
int totalDbs = RedisConfig.totalDbs;
if(totalDbs==1){
log.info("only one db : {} ",defaultDb);
return defaultDb;
}
int mod = 250;
if(totalDbs > 1 && totalDbs < 256){
if(totalDbs==16){
mod = 15;
}else{
mod = totalDbs - 1;
}
}
long value = Long.valueOf(key.hashCode());
int hash=(int)(value ^ (value >>> 32));
int index=hash % mod;
log.info("MathUtil.getIndex key:{} index:{}",key,index);
return index;
}
public static void main(String[] args) {
RedisConfig redisConfig = new RedisConfig();
redisConfig.getRedisTemplateByDb(MathUtil.getIndex("1"));
}
}
package com.liquidnet.common.cache.redis.util;
/**
* @author AnJiabin <jiabin.an@lightnet.io>
* @version V1.0
* @Description: Redis工具类
* @class: RedisUtil
* @Package com.liquidnet.stellar.utils
* @Copyright: LightNet @ Copyright (c) 2020
* @date 2020/8/26 13:11
*/
import com.liquidnet.common.cache.redis.config.RedisConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
......@@ -20,13 +11,19 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* @author AnJiabin <jiabin.an@lightnet.io>
* @version V1.0
* @Description: Redis工具类
* @class: RedisUtil
* @Package com.liquidnet.stellar.utils
* @Copyright: LightNet @ Copyright (c) 2020
* @date 2020/8/26 13:11
*/
@Component("redisUtil")
public final class RedisUtil {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
private RedisConfig redisConfig;
// =============================common============================
......@@ -47,7 +44,7 @@ public final class RedisUtil {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).expire(key, time, TimeUnit.SECONDS);
}
......@@ -68,7 +65,7 @@ public final class RedisUtil {
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).getExpire(key, TimeUnit.SECONDS);
}
......@@ -85,7 +82,7 @@ public final class RedisUtil {
public boolean hasKey(String key) {
return redisTemplate.hasKey(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).hasKey(key);
}
......@@ -96,10 +93,12 @@ public final class RedisUtil {
*/
public void delKeysByPrefix(String prefix) {
if (null != prefix && prefix.trim().length() > 0) {
Set<String> keys = redisTemplate.keys(prefix.concat("*"));
for(Integer key: RedisConfig.redisTemplateMap.keySet()){
Set<String> keys = redisConfig.getRedisTemplateByDb(key).keys(prefix.concat("*"));
if (!CollectionUtils.isEmpty(keys)) {
redisTemplate.delete(keys);
redisConfig.getRedisTemplateByDb(key).delete(keys);
}
}
}
}
......@@ -107,7 +106,7 @@ public final class RedisUtil {
/**
* 删除缓存
* 删除缓存(多db情况需要单独实现批量删除-该方法慎重使用)
* @param key 可以传一个值 或多个
......@@ -121,12 +120,14 @@ public final class RedisUtil {
if (key.length == 1) {
redisTemplate.delete(key[0]);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key[0])).delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
// redisTemplate.delete(CollectionUtils.arrayToList(key));
for(String keyStr:key){
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(keyStr)).delete(keyStr);
}
}
}
......@@ -148,7 +149,7 @@ public final class RedisUtil {
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
return key == null ? null : redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForValue().get(key);
}
......@@ -168,7 +169,7 @@ public final class RedisUtil {
public boolean set(String key, Object value) {
redisTemplate.opsForValue().set(key, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForValue().set(key, value);
return true;
......@@ -195,7 +196,7 @@ public final class RedisUtil {
if (time > 0) {
RedisTemplate<String, Object> redisTemplate = redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key));
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
......@@ -230,7 +231,7 @@ public final class RedisUtil {
}
return redisTemplate.opsForValue().increment(key, delta);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForValue().increment(key, delta);
}
......@@ -255,7 +256,7 @@ public final class RedisUtil {
}
return redisTemplate.opsForValue().increment(key, -delta);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForValue().increment(key, -delta);
}
......@@ -275,11 +276,11 @@ public final class RedisUtil {
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().get(key, item);
}
public Object hkeys(String key) {
return redisTemplate.opsForHash().keys(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().keys(key);
}
......@@ -295,7 +296,7 @@ public final class RedisUtil {
public Map<Object, Object> hmget(String key) {
return redisTemplate.opsForHash().entries(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().entries(key);
}
......@@ -315,7 +316,7 @@ public final class RedisUtil {
public boolean hmset(String key, Map<String, Object> map) {
redisTemplate.opsForHash().putAll(key, map);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().putAll(key, map);
return true;
......@@ -340,7 +341,7 @@ public final class RedisUtil {
public boolean hmset(String key, Map<String, Object> map, long time) {
redisTemplate.opsForHash().putAll(key, map);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().putAll(key, map);
if (time > 0) {
......@@ -371,7 +372,7 @@ public final class RedisUtil {
public boolean hset(String key, String item, Object value) {
redisTemplate.opsForHash().put(key, item, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().put(key, item, value);
return true;
......@@ -398,7 +399,7 @@ public final class RedisUtil {
public boolean hset(String key, String item, Object value, long time) {
redisTemplate.opsForHash().put(key, item, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().put(key, item, value);
if (time > 0) {
......@@ -424,7 +425,7 @@ public final class RedisUtil {
public void hdel(String key, Object... item) {
redisTemplate.opsForHash().delete(key, item);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().delete(key, item);
}
......@@ -443,7 +444,7 @@ public final class RedisUtil {
public boolean hHasKey(String key, String item) {
return redisTemplate.opsForHash().hasKey(key, item);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().hasKey(key, item);
}
......@@ -464,7 +465,7 @@ public final class RedisUtil {
public double hincr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, by);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().increment(key, item, by);
}
......@@ -485,7 +486,7 @@ public final class RedisUtil {
public double hdecr(String key, String item, double by) {
return redisTemplate.opsForHash().increment(key, item, -by);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForHash().increment(key, item, -by);
}
......@@ -505,7 +506,7 @@ public final class RedisUtil {
public Set<Object> sGet(String key) {
return redisTemplate.opsForSet().members(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().members(key);
}
......@@ -526,7 +527,7 @@ public final class RedisUtil {
public boolean sHasKey(String key, Object value) {
return redisTemplate.opsForSet().isMember(key, value);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().isMember(key, value);
}
......@@ -547,7 +548,7 @@ public final class RedisUtil {
public long sSet(String key, Object... values) {
return redisTemplate.opsForSet().add(key, values);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().add(key, values);
}
......@@ -570,7 +571,7 @@ public final class RedisUtil {
public long sSetAndTime(String key, long time, Object... values) {
Long count = redisTemplate.opsForSet().add(key, values);
Long count = redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().add(key, values);
if (time > 0)
......@@ -595,7 +596,7 @@ public final class RedisUtil {
public long sGetSetSize(String key) {
return redisTemplate.opsForSet().size(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().size(key);
}
......@@ -616,7 +617,7 @@ public final class RedisUtil {
public long setRemove(String key, Object... values) {
Long count = redisTemplate.opsForSet().remove(key, values);
Long count = redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForSet().remove(key, values);
return count;
......@@ -643,7 +644,7 @@ public final class RedisUtil {
public List<Object> lGet(String key, long start, long end) {
return redisTemplate.opsForList().range(key, start, end);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().range(key, start, end);
}
......@@ -662,7 +663,7 @@ public final class RedisUtil {
public long lGetListSize(String key) {
return redisTemplate.opsForList().size(key);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().size(key);
}
......@@ -683,7 +684,7 @@ public final class RedisUtil {
public Object lGetIndex(String key, long index) {
return redisTemplate.opsForList().index(key, index);
return redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().index(key, index);
}
......@@ -698,7 +699,7 @@ public final class RedisUtil {
public boolean lSet(String key, Object value) {
redisTemplate.opsForList().rightPush(key, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().rightPush(key, value);
return true;
......@@ -723,7 +724,7 @@ public final class RedisUtil {
public boolean lSet(String key, Object value, long time) {
redisTemplate.opsForList().rightPush(key, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().rightPush(key, value);
if (time > 0)
......@@ -744,7 +745,7 @@ public final class RedisUtil {
public boolean lSet(String key, List<Object> value) {
redisTemplate.opsForList().rightPushAll(key, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().rightPushAll(key, value);
return true;
......@@ -771,7 +772,7 @@ public final class RedisUtil {
public boolean lSet(String key, List<Object> value, long time) {
redisTemplate.opsForList().rightPushAll(key, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().rightPushAll(key, value);
if (time > 0)
......@@ -800,7 +801,7 @@ public final class RedisUtil {
public boolean lUpdateIndex(String key, long index, Object value) {
redisTemplate.opsForList().set(key, index, value);
redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().set(key, index, value);
return true;
......@@ -825,7 +826,7 @@ public final class RedisUtil {
public long lRemove(String key, long count, Object value) {
Long remove = redisTemplate.opsForList().remove(key, count, value);
Long remove = redisConfig.getRedisTemplateByDb(MathUtil.getIndex(key)).opsForList().remove(key, count, value);
return remove;
......
......@@ -75,6 +75,9 @@ spring:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
redis:
database: 0
#如果配置了dbs,则database配置失效 格式为0,16 0为分库初始索引(目前只支持从0开始),16为redis总的db数,队列会自动创建在db15
#如果配置了dbs为具体dbNo 如:0 则作用同database配置一样
# dbs: 0
port: ${liquidnet.redis.dragon.port}
host: ${liquidnet.redis.dragon.host}
password: ${liquidnet.redis.dragon.password}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment