Pipeline:“管道”,和很多設計模式中的“管道”具有同樣的概念,pipleline的操作,將明確client與server端的交互,都是“單向的”:你可以將多個command,依次發給server,但在此期間,你將無法獲得單個command的響應數據,此後你可以關閉“請求”,然後依次獲取每個command的響應結果。
從簡單來說,在IO操作層面,對於client而言,就是一次批量的連續的“write”請求,然後是批量的連續的“read”操作。其實對於底層Socket-IO而言,對於client而言,只不過是多次write,然後一次read的操作;對於server端,input通道上read到數據之後,就會立即被實施,也會和非pipeline一樣在output通道上輸出執行的結果,只不過此時數據會被阻塞在網絡緩衝區上,直到client端開始read或者關閉鏈接。
redisService:
public interface RedisService {
/**
* 根據 redis 的key的集合批量查詢對應存在數據
* @param keys
* @param useParallel 是否使用parallel 在沒有順序要求的時候,提高效率,true爲表示使用,false 表示不用,默認爲true
* @return
*/
Map<String,Object> batchQueryByKeys(List<String> keys,Boolean useParallel);
/**
* 使用管道的方式,批量添加數據
* @param keyValueMap
* @param expire 過期時間
* @return
*/
List<Object> batchPutInPipelined(Map<String,Object> keyValueMap,long expire);
/**
* batch increment an integer value in pipelined
*
* @param entityList
*
* @return
*
*/
List<MapEntity> batIncByPipelined(List<MapEntity> entityList);
}
AbstractRedisService 抽象類
public abstract class AbstractRedisService implements RedisService{
private static final Logger logger = LoggerFactory.getLogger(AbstractRedisService.class);
protected abstract RedisTemplate getRedisTemplate();
@Override
public Boolean expire(String key, long timeout, TimeUnit timeUnit) {
return getRedisTemplate().expire(key,timeout,timeUnit);
}
@Override
public Map<String,Object> batchQueryByKeys(List<String> keys,Boolean useParallel){
if(null == keys || keys.size() == 0 ){
return null;
}
if(null == useParallel){
useParallel = true;
}
List<Object> results = getRedisTemplate().executePipelined(
new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
for(String key:keys) {
stringRedisConn.get(key);
}
return null;
}
});
if(null == results || results.size() == 0 ){return null;}
Map<String,Object> resultMap = null;
if(useParallel){
Map<String,Object> resultMapOne = Collections.synchronizedMap(new HashMap<String,Object>());
keys.parallelStream().forEach(t -> {
resultMapOne.put(t,results.get(keys.indexOf(t)));
});
resultMap = resultMapOne;
}else{
Map<String,Object> resultMapTwo = new HashMap<>();
for(String t:keys){
resultMapTwo.put(t,results.get(keys.indexOf(t)));
}
resultMap = resultMapTwo;
}
return resultMap;
}
@Override
public List<Object> batchPutInPipelined(Map<String,Object> keyValueMap,long expire){
List<Object> results = getRedisTemplate().executePipelined(
new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
for(String key:keyValueMap.keySet()) {
if(null != keyValueMap.get(key)){
stringRedisConn.set(key, keyValueMap.get(key).toString());
stringRedisConn.expire(key,expire);
}
}
return null;
}
});
return results;
}
@Override
public List<MapEntity> batIncByPipelined(List<MapEntity> params){
List<Object> results = getRedisTemplate().executePipelined(
new RedisCallback<Object>() {
public Object doInRedis(RedisConnection connection) throws DataAccessException {
StringRedisConnection stringRedisConn = (StringRedisConnection)connection;
for(MapEntity entity:params) {
if(null != entity){
stringRedisConn.incrBy(entity.getKey(), entity.getValue());
}
}
return null;
}
});
List<MapEntity> resultList = Lists.newArrayList();
for(MapEntity entity:params){
resultList.add(new MapEntity(entity.getKey(),(Long)results.get(params.indexOf(entity))));
}
return resultList;
}
}
RedisServiceImpl 實現類
public class RedisServiceImpl extends AbstractRedisService {
private RedisTemplate redisTemplate;
public RedisServiceImpl(RedisTemplate redisTemplate) {
this.redisTemplate = redisTemplate;
}
@Override
protected RedisTemplate getRedisTemplate() {
return redisTemplate;
}
}
補充: 具體RedisTemplate 替代 jedis 方法 點這裏 https://www.cnblogs.com/yinfengjiujian/p/9084711.html