redisキャッシュ構成およびredisツールクラス/キャッシュページング
34809 ワード
ここでは、ビジネスシーン、redisキャッシュ構成、redisツールクラスの統合について説明します.
まずredis構成を行います.
pom.xmlファイルの新規作成
redis.propertiesファイル
redisキャッシュ構成の初期化とオープン:RedisCacheConfig.java
新しいredisツールクラス:
操作インタフェースクラス:RedisCommand.java
操作実装クラス:RedisHandle実装RedisCommandインタフェース
このredisの基本的なツールは、古い鉄が備えています.
ステップ2:使用方法、ここで簡単にコードを貼ります
例1:天気データのキャッシュ、注釈実装
@Cacheable注記はこのメソッドreturnの値をキャッシュし、valueとkeyは対応するredisキャッシュkeyキーを生成します.
例2:redisツールクラス使用、ここにコードの一部を貼ります
ここには2つのデータ構造の値が保存され、failKeyはlist、resultKeyはzsetを保存し、redisCommandはキーごとに異なる有効時間単位秒(S)を設定することができます.
例3:キャッシュページング
ここではキャッシュページングの例ですが、クエリーのデータが保存されているときはzsetでなければならないことに注意してください(例2を参照).このようにしてzsetでページングを行うことができます.ソートが必要な場合は簡単な方法を採用しています.zsetは秩序があります.私はredisに保存するときはすでにシーケンスを作っています(ソート方法についてはまだ勉強しなければなりません).
OK、メモを取って、間違ったところがあったら指摘してください.
まずredis構成を行います.
pom.xmlファイルの新規作成
1.8.10.RELEASE
2.9.0
org.springframework.data
spring-data-redis
${spring-redis.version}
redis.clients
jedis
${redis-jedis.version}
redis.propertiesファイル
# REDIS
# Redis
spring.redis.database=0
# Redis
spring.redis.host=172.16.6.75
# Redis
spring.redis.port=6379
# Redis
spring.redis.password=redis@112358
# ( )
spring.redis.pool.max-active=8
# ( )
spring.redis.pool.max-wait=-1
#
spring.redis.pool.max-idle=8
#
spring.redis.pool.min-idle=0
# ( )
spring.redis.timeout=0
redisキャッシュ構成の初期化とオープン:RedisCacheConfig.java
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.io.Serializable;
/**
* redis
* @author WangHan
* @date 2018/4/3 14:23
*/
@Configuration
@EnableCaching
@PropertySource("classpath:redis.properties")
public class RedisCacheConfig extends CachingConfigurerSupport {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.pool.max-wait}")
private int maxWait;
@Bean
public JedisConnectionFactory redisConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setPassword(password);
factory.setHostName(host);
factory.setPort(port);
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMinIdle(minIdle);
jedisPoolConfig.setMaxWaitMillis(maxWait);
factory.setPoolConfig(jedisPoolConfig);
return factory;
}
@Bean
public RedisTemplate getRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
RedisSerializer redisSerializer = new JdkSerializationRedisSerializer();
redisTemplate.setDefaultSerializer(redisSerializer);
RedisSerializer keySerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(keySerializer);
return redisTemplate;
}
@Bean
public CacheManager cacheManager(RedisTemplate,?> redisTemplate) {
RedisCacheManager redisCacheManager = new RedisCacheManager(redisTemplate);
redisCacheManager.setDefaultExpiration(3600 * 12);
return redisCacheManager;
}
}
新しいredisツールクラス:
操作インタフェースクラス:RedisCommand.java
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.ZSetOperations;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
/**
* redis
* @author WangHan
* @date 2018/7/3 10:56
*/
public interface RedisCommand {
/**
*
* @param date
* @return
*/
double getCreateTimeScore(long date);
/**
* Redis key
* @return
*/
Set getAllKeys();
/**
* key-value
* @return
*/
Map getAllString();
/**
* Set -key-value
* @return
*/
Map> getAllSet();
/**
* ZSet -key-value
* @return
*/
Map> getAllZSetReverseRange();
/**
* ZSet -key-value
* @return
*/
Map> getAllZSetRange();
/**
* List -key-value
* @return
*/
Map> getAllList();
/**
* Map -key-value
* @return
*/
Map> getAllMap();
/**
* list
* @param key
* @param objectList
*/
void addList(K key, List objectList);
/**
* list
* @param key
* @param obj
* @return list
*/
long addList(K key,V obj);
/**
*
* list
* @param key
* @param obj
* @return list
*/
long addList(K key,V ...obj);
/**
*
* list
* @param key List key
* @param s
* @param e
* @return
*/
List getList(K key, long s, long e);
/**
* list
* @param key
*/
List getList(K key);
/**
* list
* @param key
* @return
*/
long getListSize(K key);
/**
* list
* list count value object , ,
* count 0, list value object ,
* value object ,
* @param key
* @param object
* @return
*/
long removeListValue(K key,V object);
/**
* list
* @param key
* @param object
* @return
*/
long removeListValue(K key,V... object);
/**
* key value
* @param keys
*/
void remove(final K... keys);
/**
*
* key
* @param key
*/
void remove(final K key);
/**
* ZSet
* @param key
* @param s
* @param e
*/
void removeZSetRangeByScore(String key,double s , double e);
/**
* Set
* @param key
* @param time
* @return
*/
Boolean setSetExpireTime(String key,Long time);
/**
* ZSet
* @param key
* @param time
* @return
*/
Boolean setZSetExpireTime(String key,Long time);
/**
* key value
* @param key
* @return
*/
boolean exists(final K key);
/**
* String
* @param key
* @return
*/
V get(final K key);
/**
* String
* @param key
* @return
*/
List get(final K... key);
/**
*
* @param regKey
* @return
*/
List
操作実装クラス:RedisHandle実装RedisCommandインタフェース
import com.klicen.common.web.util.redis.RedisCommand;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
/**
* redis
* @author WangHan
* @date 2018/7/3 10:59
*/
@Component
@Slf4j
public class RedisHandle implements RedisCommand {
@Autowired
protected RedisTemplate redisTemplate;
/**
* ,
*/
private static Integer times = 5;
@Override
public double getCreateTimeScore(long date) {
return date/ 100000.0;
}
@Override
public Set getAllKeys() {
return redisTemplate.keys("*");
}
@Override
public Map getAllString() {
Set stringSet = getAllKeys();
Map map = new HashMap();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.STRING) {
map.put(k, get(k));
}
}
return map;
}
@Override
public Map> getAllSet() {
Set stringSet = getAllKeys();
Map> map = new HashMap>();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.SET) {
map.put(k, getSet(k));
}
}
return map;
}
@Override
public Map> getAllZSetRange() {
Set stringSet = getAllKeys();
Map> map = new HashMap>();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.ZSET) {
log.debug("k:"+k);
map.put(k, getZSetRange(k));
}
}
return map;
}
@Override
public Map> getAllZSetReverseRange() {
Set stringSet = getAllKeys();
Map> map = new HashMap>();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.ZSET) {
map.put(k, getZSetReverseRange(k));
}
}
return map;
}
@Override
public Map> getAllList() {
Set stringSet = getAllKeys();
Map> map = new HashMap>();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.LIST) {
map.put(k, getList(k));
}
}
return map;
}
@Override
public Map> getAllMap() {
Set stringSet = getAllKeys();
Map> map = new HashMap>();
Iterator iterator = stringSet.iterator();
while (iterator.hasNext()) {
String k = iterator.next();
if (getType(k) == DataType.HASH) {
map.put(k, getMap(k));
}
}
return map;
}
@Override
public void addList(String key, List objectList) {
for (Object obj : objectList) {
addList(key, obj);
}
}
@Override
public long addList(String key, Object obj) {
return redisTemplate.boundListOps(key).rightPush(obj);
}
@Override
public long addList(String key, Object... obj) {
return redisTemplate.boundListOps(key).rightPushAll(obj);
}
@Override
public List getList(String key, long s, long e) {
return redisTemplate.boundListOps(key).range(s, e);
}
@Override
public List getList(String key) {
return redisTemplate.boundListOps(key).range(0, getListSize(key));
}
@Override
public long getListSize(String key) {
return redisTemplate.boundListOps(key).size();
}
@Override
public long removeListValue(String key, Object object) {
return redisTemplate.boundListOps(key).remove(0, object);
}
@Override
public long removeListValue(String key, Object... objects) {
long r = 0;
for (Object object : objects) {
r += removeListValue(key, object);
}
return r;
}
@Override
public void remove(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
remove(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
@Override
public void removeBlear(String... blears) {
for (String blear : blears) {
removeBlear(blear);
}
}
@Override
public Boolean renameIfAbsent(String oldKey, String newKey) {
return redisTemplate.renameIfAbsent(oldKey, newKey);
}
@Override
public void removeBlear(String blear) {
redisTemplate.delete(redisTemplate.keys(blear));
}
@Override
public void removeByRegular(String... blears) {
for (String blear : blears) {
removeBlear(blear);
}
}
@Override
public void removeByRegular(String blear) {
Set stringSet = getAllKeys();
for (String s : stringSet) {
if (Pattern.compile(blear).matcher(s).matches()) {
redisTemplate.delete(s);
}
}
}
@Override
public void removeMapFieldByRegular(String key, String... blears) {
for (String blear : blears) {
removeMapFieldByRegular(key, blear);
}
}
@Override
public void removeMapFieldByRegular(String key, String blear) {
Map map = getMap(key);
Set stringSet = map.keySet();
for (String s : stringSet) {
if (Pattern.compile(blear).matcher(s).matches()) {
redisTemplate.boundHashOps(key).delete(s);
}
}
}
@Override
public Long removeZSetValue(String key, Object... value) {
return redisTemplate.boundZSetOps(key).remove(value);
}
@Override
public void removeZSet(String key) {
removeZSetRange(key, 0L, getZSetSize(key));
}
@Override
public void removeZSetRange(String key, Long start, Long end) {
redisTemplate.boundZSetOps(key).removeRange(start, end);
}
@Override
public void setZSetUnionAndStore(String key,String key1, String key2) {
redisTemplate.boundZSetOps(key).unionAndStore(key1,key2);
}
@Override
public Set getZSetRange(String key) {
return getZSetRange(key, 0, getZSetSize(key));
}
@Override
public Set getZSetRange(String key, long s, long e) {
return redisTemplate.boundZSetOps(key).range(s, e);
}
@Override
public Set getZSetReverseRange(String key) {
return getZSetReverseRange(key, 0, getZSetSize(key));
}
@Override
public Set getZSetReverseRange(String key, long start, long end) {
return redisTemplate.boundZSetOps(key).reverseRange(start, end);
}
@Override
public Set getZSetRangeByScore(String key, double start, double end) {
return redisTemplate.boundZSetOps(key).rangeByScore(start, end);
}
@Override
public Set getZSetReverseRangeByScore(String key, double start, double end) {
return redisTemplate.boundZSetOps(key).reverseRangeByScore(start, end);
}
@Override
public Set> getZSetRangeWithScores(String key, long start, long end) {
return redisTemplate.boundZSetOps(key).rangeWithScores(start, end);
}
@Override
public Set> getZSetReverseRangeWithScores(String key, long start, long end) {
return redisTemplate.boundZSetOps(key).reverseRangeWithScores(start, end);
}
@Override
public Set> getZSetRangeWithScores(String key) {
return getZSetRangeWithScores(key, 0, getZSetSize(key));
}
@Override
public Set> getZSetReverseRangeWithScores(String key) {
return getZSetReverseRangeWithScores(key, 0, getZSetSize(key));
}
@Override
public long getZSetCountSize(String key, double sMin, double sMax) {
return redisTemplate.boundZSetOps(key).count(sMin, sMax);
}
@Override
public long getZSetSize(String key) {
return redisTemplate.boundZSetOps(key).size();
}
@Override
public double getZSetScore(String key, Object value) {
return redisTemplate.boundZSetOps(key).score(value);
}
@Override
public double incrementZSetScore(String key, Object value, double delta) {
return redisTemplate.boundZSetOps(key).incrementScore(value, delta);
}
@Override
public Boolean addZSet(String key, double score, Object value) {
return redisTemplate.boundZSetOps(key).add(value, score);
}
@Override
public Long addZSet(String key, TreeSet value) {
return redisTemplate.boundZSetOps(key).add(value);
}
@Override
public Boolean addZSet(String key, double[] score, Object[] value) {
if (score.length != value.length) {
return false;
}
for (int i = 0; i < score.length; i++) {
if (addZSet(key, score[i], value[i]) == false) {
return false;
}
}
return true;
}
@Override
public void remove(String key) {
if (exists(key)) {
redisTemplate.delete(key);
}
}
@Override
public void removeZSetRangeByScore(String key,double s , double e) {
redisTemplate.boundZSetOps(key).removeRangeByScore(s,e);
}
@Override
public Boolean setSetExpireTime(String key, Long time) {
return redisTemplate.boundSetOps(key).expire(time, TimeUnit.SECONDS);
}
@Override
public Boolean setZSetExpireTime(String key, Long time) {
return redisTemplate.boundZSetOps(key).expire(time, TimeUnit.SECONDS);
}
@Override
public boolean exists(String key) {
return redisTemplate.hasKey(key);
}
@Override
public Object get(String key) {
return redisTemplate.boundValueOps(key).get();
}
@Override
public List get(String... keys) {
List list = new ArrayList();
for (String key : keys) {
list.add(get(key));
}
return list;
}
@Override
public List getByRegular(String regKey) {
Set stringSet = getAllKeys();
List objectList = new ArrayList();
for (String s : stringSet) {
if (Pattern.compile(regKey).matcher(s).matches() && getType(s) == DataType.STRING) {
objectList.add(get(s));
}
}
return objectList;
}
@Override
public void set(String key, Object value) {
redisTemplate.boundValueOps(key).set(value);
}
@Override
public void set(String key, Object value, Long expireTime) {
redisTemplate.boundValueOps(key).set(value, expireTime, TimeUnit.SECONDS);
}
@Override
public boolean setExpireTime(String key, Long expireTime) {
return redisTemplate.expire(key, expireTime, TimeUnit.SECONDS);
}
@Override
public DataType getType(String key) {
return redisTemplate.type(key);
}
@Override
public void removeMapField(String key, Object... field) {
redisTemplate.boundHashOps(key).delete(field);
}
@Override
public Long getMapSize(String key) {
return redisTemplate.boundHashOps(key).size();
}
@Override
public Map getMap(String key) {
return redisTemplate.boundHashOps(key).entries();
}
@Override
public T getMapField(String key, String field) {
return (T) redisTemplate.boundHashOps(key).get(field);
}
@Override
public Boolean hasMapKey(String key, String field) {
return redisTemplate.boundHashOps(key).hasKey(field);
}
@Override
public List getMapFieldValue(String key) {
return redisTemplate.boundHashOps(key).values();
}
@Override
public Set getMapFieldKey(String key) {
return redisTemplate.boundHashOps(key).keys();
}
@Override
public void addMap(String key, Map map) {
redisTemplate.boundHashOps(key).putAll(map);
}
@Override
public void addMap(String key, String field, Object value) {
redisTemplate.boundHashOps(key).put(field, value);
}
@Override
public void addMap(String key, String field, Object value, long time) {
redisTemplate.boundHashOps(key).put(field, value);
redisTemplate.boundHashOps(key).expire(time, TimeUnit.SECONDS);
}
@Override
public void watch(String key) {
redisTemplate.watch(key);
}
@Override
public void addSet(String key, Object... obj) {
redisTemplate.boundSetOps(key).add(obj);
}
@Override
public long removeSetValue(String key, Object obj) {
return redisTemplate.boundSetOps(key).remove(obj);
}
@Override
public long removeSetValue(String key, Object... obj) {
if (obj != null && obj.length > 0) {
return redisTemplate.boundSetOps(key).remove(obj);
}
return 0L;
}
@Override
public long getSetSize(String key) {
return redisTemplate.boundSetOps(key).size();
}
@Override
public Boolean hasSetValue(String key, Object obj) {
Boolean boo = null;
int t =0;
while (true){
try {
boo = redisTemplate.boundSetOps(key).isMember(obj);
break;
} catch (Exception e) {
log.error("key[" + key + "],obj[" + obj + "] Set , :" + e.getMessage());
t++;
}
if(t>times){
break;
}
}
log.info("key[" + key + "],obj[" + obj + "] ,boo:" + boo);
return boo;
}
@Override
public Set getSet(String key) {
return redisTemplate.boundSetOps(key).members();
}
@Override
public Set getSetUnion(String key, String otherKey) {
return redisTemplate.boundSetOps(key).union(otherKey);
}
@Override
public Set getSetUnion(String key, Set set) {
return redisTemplate.boundSetOps(key).union(set);
}
@Override
public Set getSetIntersect(String key, String otherKey) {
return redisTemplate.boundSetOps(key).intersect(otherKey);
}
@Override
public Set getSetIntersect(String key, Set set) {
return redisTemplate.boundSetOps(key).intersect(set);
}
}
このredisの基本的なツールは、古い鉄が備えています.
ステップ2:使用方法、ここで簡単にコードを貼ります
例1:天気データのキャッシュ、注釈実装
@Cacheable(value = "application_weather", key = "#keyPrefix + '_' + #date + '_' + #city")
public String queryCacheWeatherApi(String city, String date, String keyPrefix, String weatherUrl) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
// uri
URIBuilder uriBuilder = new URIBuilder(weatherUrl);
uriBuilder.addParameter("city", city);
uriBuilder.addParameter("key", WeatherConfig.myKey);
String apiInfo = getApiInfo(uriBuilder, httpClient);
log.info(keyPrefix +"_"+ date +"_"+ city + " - " +apiInfo);
return apiInfo;
}
@Cacheable注記はこのメソッドreturnの値をキャッシュし、valueとkeyは対応するredisキャッシュkeyキーを生成します.
例2:redisツールクラス使用、ここにコードの一部を貼ります
String uid = IdUtil.gen();
// list redis( list) , ( )
String failKey = "fail_list_key_".concat(uid);
Long failExpireTime = 86400L;
redisCommand.addList(failKey, failList);
redisCommand.setExpireTime(failKey, failExpireTime);
// list redis( zset) , (3 )
String resultKey = "result_zset_key_".concat(uid);
Long resultExpireTime = 10800L;
double[] scoreArray = new double[resultList.size()];
for (int i = 0; i < resultList.size(); i++) {
scoreArray[i] = (double)resultList.get(i).getRowNum();
}
redisCommand.addZSet(resultKey, scoreArray, resultList.toArray());
redisCommand.setExpireTime(resultKey, resultExpireTime);
ここには2つのデータ構造の値が保存され、failKeyはlist、resultKeyはzsetを保存し、redisCommandはキーごとに異なる有効時間単位秒(S)を設定することができます.
例3:キャッシュページング
public ResponseData excelImportPage(String key, Integer pageNum, Integer pageSize) {
//
super.getCurrentBackendUser();
int startIndex = PageUtil.getStartIndex(pageNum, pageSize);
// pageSize
pageSize = PageUtil.handlePageSize(pageSize);
//
long total = 0L;
LinkedHashSet set = new LinkedHashSet<>();
// redis
if (!StringUtil.isEmpty(key)) {
total = redisCommand.getZSetSize(key);
Object obj = redisCommand.getZSetRange(key, startIndex, startIndex + pageSize - 1);
set = (LinkedHashSet)obj;
}
JSONObject jsonData = new JSONObject();
jsonData.put("total", total);
jsonData.put("import_list", set);
return ResponseUtil.SUCC().setData(jsonData);
}
ここではキャッシュページングの例ですが、クエリーのデータが保存されているときはzsetでなければならないことに注意してください(例2を参照).このようにしてzsetでページングを行うことができます.ソートが必要な場合は簡単な方法を採用しています.zsetは秩序があります.私はredisに保存するときはすでにシーケンスを作っています(ソート方法についてはまだ勉強しなければなりません).
OK、メモを取って、間違ったところがあったら指摘してください.