
08141032.png
redis簡介:
Redis 是一個開源(BSD許可)的,非關(guān)系型,內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)存儲系統(tǒng)。它可以用來作為數(shù)據(jù)庫(可以持久化),消息中間件,緩存。它支持多種類型的數(shù)據(jù)結(jié)構(gòu)如:sets,lists,sorted sets,strings,hashs。并通過 Redis哨兵(Sentinel)和自動 分區(qū)(Cluster)提供高可用性(high availability)。
redis5種數(shù)據(jù)結(jié)構(gòu)
| 類型 | 結(jié)構(gòu)存儲 | 讀寫性能 |
|---|---|---|
| Hash | key-value鍵值集合 | 添加或者單個鍵值數(shù)據(jù),比如用戶token |
| List | 字符串鏈表 | 可以在鏈表兩端彈出或者推入數(shù)據(jù),也可以修剪列表 |
| Set | 字符串的無序不重復集合 | 添加,刪除,查詢元素,檢查元素存在性 |
| String | 字符串,整數(shù),浮點數(shù) | 數(shù)字的自增自減操作 |
| Zset | 字符串的有續(xù)集合,zset的每一個成員都有一個分數(shù)與之對應,并且分數(shù)是可以重復的。有序集合的增刪改由于有啦排序,執(zhí)行效率就是非??焖俚模幢闶窃L問集合中間的數(shù)據(jù)也是非常高效 | 添加,刪除,查詢元素,根據(jù)分值獲取元素 |
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<String, String> boundOptions(String key) {
return this.redisTemplate.boundValueOps(key);
}
private BoundHashOperations hashOps(String tableName) {
return redisTemplate.boundHashOps(tableName);
}
public <T> List<T> getMultiVal(String keyPattern, Class<T> clazz) {
return this.getMultiVal(this.keySet(keyPattern), clazz);
}
public <T> List<T> getMultiVal(Collection<String> keys, Class<T> 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 <V> 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 <V> void putVal(String key, V value) {
this.boundOptions(key).set(JSON.toJSONString(value));
}
public <V> 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> T getVal(String key, Class<T> 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<String> allKeys(String key){
Set<String> set = keySet(key + ":*");
set.add(key);
return set;
}
public Set<String> 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<String> keys) {
try {
this.redisTemplate.delete(keys);
}
catch (Exception var3) {
throw new RuntimeException("redis service error: {}", var3);
}
}
public void clearKeyPattern(String key) {
Set<String> set = keySet(key + ":*");
set.add(key);
this.clearKey(set);
}
public T get(String tableName, String key, Class<T> 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<String> 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> T fromRedis(RedisOperations redisOperations, String redisKey, Class<T> clazz, Supplier<T> 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 <T> List<T> fromRedisList(RedisOperations redisOperations, String redisKey, Class<T> clazz, Supplier<List> dbFunc,Object... object) {
List<T> 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);
}
}
}