Redis集群使用Jedis的pipeline操作

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;
		});
	}

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Redis集群中,由于集群将数据划分为不同的slot,并且每个节点负责一批slot,所以无法直接执行一些批量操作命令,如mget和pipeline等。这是因为jedis客户端没有封装这些批量操作的命令。\[1\] 然而,如果你需要在Redis集群中进行批量操作,可以使用pipeline来实现。通过使用pipeline,你可以将多个命令一次性发送给Redis服务器,减少了网络通信的开销,提高了性能。\[2\] 要在Redis集群使用pipeline进行批量操作,你需要将redis-trib.rb文件复制到集群的根目录中。你可以进入到Redis的解压目录,找到src文件夹中的redis-trib.rb文件,然后将其复制到集群目录中。例如,可以使用以下命令将redis-trib.rb文件复制到/root/redis-cluster/目录中:cp redis-trib.rb /root/redis-cluster/。\[3\] 通过使用pipeline和正确配置Redis集群,你可以实现在集群模式下进行批量操作的需求。 #### 引用[.reference_title] - *1* *2* [在Redis集群模式下使用pipeline进行批量操作](https://blog.csdn.net/zc19921215/article/details/128824445)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] - *3* [搭建redis集群使用,以及批处理启动关闭。](https://blog.csdn.net/weixin_44893467/article/details/111151110)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值