SpringBoot+Redis集群项目使用Jedis的pipeline执行批量写入操作
写入数据示例:
public void pipeSet() {
// 获取集群节点的slot range
Map<String, RedisClusterNode.SlotRange> slotRangeMap = new HashMap<String, RedisClusterNode.SlotRange>();
Map<String, List<Map<String, Object>>> setListMap = new HashMap<String, List<Map<String,Object>>>();
RedisConnectionFactory factory = redisTemplate.getConnectionFactory();
RedisClusterConnection redisClusterConnection = factory.getClusterConnection();
Iterable<RedisClusterNode> redisClusterNodes = redisClusterConnection.clusterGetNodes();
for (RedisClusterNode redisClusterNode : redisClusterNodes) {
if (redisClusterNode.isMaster()) {
slotRangeMap.put(redisClusterNode.getHost() + ":" + redisClusterNode.getPort(), redisClusterNode.getSlotRange());
setListMap.put(redisClusterNode.getHost() + ":" + redisClusterNode.getPort(), new ArrayList<Map<String,Object>>());
}
}
// 根据slot range将数据分组
List<String> discardKeys = new ArrayList<String>();
int slot = 0;
String setKey = null;
Map<String, Object> tempMap = null;
for (int i = 0; i < pipeSize; i ++) {
// 从队列中取出要写入的数据,tempMap值:{"t":过期时间,"v":数据对象,"k":存储的键值}
tempMap = pipeSetQueue.poll();
setKey = (String) tempMap.get("k");
discardKeys.add(setKey);
slot = JedisClusterCRC16.getSlot(setKey);
for (Map.Entry<String, RedisClusterNode.SlotRange> entry : slotRangeMap.entrySet()) {
if (entry.getValue().contains(slot)) {
setListMap.get(entry.getKey()).add(tempMap);
}
}
}
// 执行Redis集群下的pipeline写入
redisTemplate.execute((RedisCallback<Object>) connection -> {
JedisCluster cluster = (JedisCluster) connection.getNativeConnection();
Map<String, JedisPool> jedisMap = cluster.getClusterNodes();
List<Map<String, Object>> setList = null;
String key = null;
Map<String, Object> setLM = null;
for (Map.Entry<String, JedisPool> jedisEntry : jedisMap.entrySet()) {
try {
Jedis resource = jedisEntry.getValue().getResource();
if (resource.isConnected() && setListMap.containsKey(jedisEntry.getKey())) {
Pipeline pipe = resource.pipelined();
setList = setListMap.get(jedisEntry.getKey());
for (int i = 0; i < setList.size(); i ++) {
setLM = setList.get(i);
key = (String) setLM.get("k");
if (setLM.containsKey("t")) {
// 有过期时间设置
pipe.setex(keySer.serialize(key), Integer.valueOf((String) setLM.get("t")), getValueSer().serialize(setLM.get("v")));
} else {
pipe.set(keySer.serialize(key), getValueSer().serialize(setLM.get("v")));
}
}
pipe.sync();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return null;
});
}