redis简介:
Redis 是一个开源(BSD许可)的,非关系型,内存中的数据结构存储系统。它可以用来作为数据库(可以持久化),消息中间件,缓存。它支持多种类型的数据结构如:sets,lists,sorted sets,strings,hashs。并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
redis5种数据结构
类型 | 结构存储 | 读写性能 |
---|---|---|
Hash | key-value键值集合 | 添加或者单个键值数据,比如用户token |
List | 字符串链表 | 可以在链表两端弹出或者推入数据,也可以修剪列表 |
Set | 字符串的无序不重复集合 | 添加,删除,查询元素,检查元素存在性 |
String | 字符串,整数,浮点数 | 数字的自增自减操作 |
Zset | 字符串的有续集合,zset的每一个成员都有一个分数与之对应,并且分数是可以重复的。有序集合的增删改由于有啦排序,执行效率就是非常快速的,即便是访问集合中间的数据也是非常高效 | 添加,删除,查询元素,根据分值获取元素 |
Redis配置
@Configuration
public class RedisConfig {
@Value("${redis.host}")
private String host;
@Value("${redis.password}")
private String password;
@Value("${redis.port}")
private int port;
@Value("${redis.timeout}")
private int timeout;
@Value("${redis.maxTotal}")
private int maxTotal;
@Value("${redis.maxIdle}")
private int maxIdle;
@Value("${redis.maxWaitMillis}")
private int maxWaitMillis;
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig config= new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMaxWaitMillis(maxWaitMillis);
config.setTestOnBorrow(true);
return config;
}
@Bean
public JedisConnectionFactory jedisConnectionFactory(JedisPoolConfig jedisPoolConfig){
JedisConnectionFactory factory= new JedisConnectionFactory(jedisPoolConfig);
factory.setHostName(host);
factory.setPassword(password);
factory.setPort(port);
factory.setTimeout(timeout);
factory.setUsePool(true);
return factory;
}
@Bean
public StringRedisTemplate redisTemplate(JedisConnectionFactory factory){
StringRedisTemplate template = new StringRedisTemplate(factory);
template.setValueSerializer(new StringRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
配置:
redis.maxTotal=500
redis.maxIdle=100
redis.maxWaitMillis=1000
redis.testOnBorrow=true
redis.host=localhost
redis.password=
redis.port=6379
redis.timeout=5000
RedisOperations 工具类
public class RedisOperations {
private Logger logger = LoggerFactory.getLogger(RedisOperations.class);
private final StringRedisTemplate redisTemplate;
public RedisOperations(StringRedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
private BoundValueOperations boundOptions(String key) {
return this.redisTemplate.boundValueOps(key);
}
private BoundHashOperations hashOps(String tableName) {
return redisTemplate.boundHashOps(tableName);
}
public List getMultiVal(String keyPattern, Class clazz) {
return this.getMultiVal(this.keySet(keyPattern), clazz);
}
public List getMultiVal(Collection keys, Class clazz) {
ArrayList result = new ArrayList();
if (null != keys && !keys.isEmpty()) {
byte[][] rawKeys = new byte[keys.size()][];
int counter = 0;
String key;
for (Iterator rawValues = keys.iterator(); rawValues.hasNext(); rawKeys[counter++] = key.getBytes()) {
key = (String) rawValues.next();
}
List var9 = this.redisTemplate.execute((connection) ->
{
return connection.mGet(rawKeys);
}, true);
Iterator var10 = var9.iterator();
while (var10.hasNext()) {
byte[] bytes = (byte[]) var10.next();
if(bytes!=null && bytes.length>0){
if(clazz==String.class){
try {
result.add(new String(bytes,CharsetNames.UTF_8));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}else {
result.add(JSON.parseObject(bytes, clazz));
}
}
}
return result;
}
else {
return result;
}
}
public void putVal(String key, V value, long expireSeconds) {
BoundValueOperations operation = this.boundOptions(key);
if (operation != null) {
operation.set(JSON.toJSONString(value, new SerializerFeature[0]));
operation.expire(expireSeconds, TimeUnit.SECONDS);
}
}
public void putVal(String key, V value) {
this.boundOptions(key).set(JSON.toJSONString(value));
}
public void putValExpireAt(String key, V value, Date date) {
BoundValueOperations operation = this.boundOptions(key);
if (operation != null) {
operation.set(JSON.toJSONString(value, new SerializerFeature[0]));
operation.expireAt(date);
}
}
public T getVal(String key, Class clazz) {
return this.redisTemplate.execute((connection) ->
{
byte[] bytes = connection.get(key.getBytes());
return null != bytes ? JSON.parseObject(bytes, clazz, new Feature[0]) : null;
}, true);
}
public String getVal(String key) {
return this.redisTemplate.execute((connection) ->
{
byte[] bytes = connection.get(key.getBytes());
try {
return null != bytes ? new String(bytes, CharsetNames.UTF_8) : null;
}
catch (UnsupportedEncodingException e) {
logger.error("UnsupportedEncodingException:{}" + e);
}
return null;
}, true);
}
public Set allKeys(String key){
Set set = keySet(key + ":*");
set.add(key);
return set;
}
public Set keySet(String pattern) {
try {
return this.redisTemplate.keys(pattern);
}
catch (Exception var3) {
throw new RuntimeException("redis service error: {}", var3);
}
}
public boolean addKeyExpire(String key, long delta) {
Long newExpire = this.redisTemplate.getExpire(key, TimeUnit.SECONDS);
return this.redisTemplate.expire(key, newExpire.longValue() + delta, TimeUnit.SECONDS).booleanValue();
}
public void clearKey(String... keys) {
this.clearKey(Arrays.asList(keys));
}
public void clearKey(Collection keys) {
try {
this.redisTemplate.delete(keys);
}
catch (Exception var3) {
throw new RuntimeException("redis service error: {}", var3);
}
}
public void clearKeyPattern(String key) {
Set set = keySet(key + ":*");
set.add(key);
this.clearKey(set);
}
public T get(String tableName, String key, Class clazz) {
try {
return JSON.parseObject(hashOps(tableName).get(key).toString(), clazz);
}
catch (Exception e) {
logger.error("get{}:{} error.", tableName, key, e);
}
return null;
}
public void put(String tableName, String key, Object value) {
try {
hashOps(tableName).put(key, value);
}
catch (Exception e) {
logger.error("put{}:{}:{} error.", tableName, key, value, e);
}
}
public StringRedisTemplate getRedisTemplate() {
return redisTemplate;
}
public Object memory() {
return redisTemplate.execute(new RedisCallback()
{
@Override
public Object doInRedis(RedisConnection connection) throws DataAccessException {
return connection.info("memory");
}
});
}
public Long leftPush(String channel, Message message) {
return redisTemplate.opsForList().leftPush(channel, JSON.toJSONString(message));
}
public Message rightPop(String channel) {
String message = redisTemplate.opsForList().rightPop(channel);
if (StringUtils.isEmpty(message)) {
return null;
}
Message parseObject = JSON.parseObject(message, Message.class);
return parseObject;
}
public List rangeList(String channel) {
return redisTemplate.opsForList().range(channel, 0, -1);
}
public Long listSize(String channel) {
return redisTemplate.opsForList().size(channel);
}
}
Redis工具增强类
public class CacheFetchUtils {
private static final Logger logger= LoggerFactory.getLogger(CacheFetchUtils.class);
public CacheFetchUtils() {
}
public static T fromRedis(RedisOperations redisOperations, String redisKey, Class clazz, Supplier dbFunc, Object... object) {
T result = redisOperations.getVal(redisKey, clazz);
if(result == null) {
result = dbFunc.get();
if(result == null) {
logger.error("fetch " + clazz + " error, redisKey: " + redisKey);
return null;
}
valSerialize(redisOperations,redisKey,result,object);
}
return result;
}
public static List fromRedisList(RedisOperations redisOperations, String redisKey, Class clazz, Supplier dbFunc,Object... object) {
List result = JSON.parseArray(redisOperations.getVal(redisKey),clazz);
if(CollectionUtils.isEmpty(result)) {
result = dbFunc.get();
if(result == null) {
logger.error("fetch " + clazz + " error, redisKey: " + redisKey);
return null;
}
valSerialize(redisOperations,redisKey,result,object);
}
return result;
}
private static void valSerialize(RedisOperations redisOperations,String redisKey, Object result,Object... object){
Object[] objects= object;
if(objects!=null && objects.length>0){
Object obj= objects[0];
if(obj instanceof Date){
redisOperations.putValExpireAt(redisKey, result, (Date) obj);
}else {
Long expireTime= Long.valueOf(obj.toString());
if(expireTime==0){
return;
}
redisOperations.putVal(redisKey, result,expireTime);
}
}else{
redisOperations.putVal(redisKey, result);
}
}
}