最近在使用jedis 操作redis,在处理一个sortedset key的返回值时遇到一个棘手的问题。
有如下报错:
java.lang.ClassCastException: java.lang.String cannot be cast to redis.clien
具体操作是这样子:
zrangebyscore 返回的是一个数据集合,如果要接这个返回值,你又不想new 一个bean, tuple 是一个不错的选择。
需求中需要将该方法的返回值的第三个字段截取出来放入List<String> 中。
此时报错
java.lang.ClassCastException: java.lang.String cannot be cast to redis.clien
public List<Tuple> getReferenceOpeMove(String referenceOpe, String eqpt, LocalDateTime nowTime, Jedis jedis){ List<Tuple> tupleList = new ArrayList<>(); Pipeline pipe = jedis.pipelined(); nowTime = nowTime.plusMinutes(15); String refKey = ""; // 根据rule中设定机台取参照配置中的机台 List <MBisDataDN> referenceEqpt= matchUtil.getSPRCMatch(eqpt); // String key = referenceOpe + ":" + referenceEqpt.get(0).getCode(); if(referenceEqpt.size() > 0){ refKey = referenceEqpt.get(0).getItem() + ":" + referenceEqpt.get(0).getCode().substring(0,6); // 前台有必要设定参照站点吗? 既然要取一次配置则不需要再设定 } long fiStartTime = nowTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond() - (60 * 60); long fiEndTime = nowTime.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond(); // pipe.zrangeByScore(refKey,fiStartTime,fiEndTime); pipe.zrangeByScore(refKey,String.valueOf(fiStartTime),String.valueOf(fiEndTime)); final List<Object> objects = pipe.syncAndReturnAll(); objects.stream().map(p -> ((LinkedHashSet<Tuple>) p)).filter(p -> p.size() > 0).forEach(p -> { tupleList.addAll(p); }); return tupleList.parallelStream().collect(Collectors.toList()); }
仔细分析下这段代码,发现zrangebyscore的返回值是set, 为了使用pipeLined 转为List<Tuple>.
看jedis下面这段代码, 我们应该将返回值改为
Set<String>, 这样再返回给List<String> 不再报错
不过没有用到pipeLine 是否会有redis性能问题。待验证
update 2021年8月12日17:25:25
不使用Pipeline时,客户端是发送一个命令、读取一次结果。而使用Pipeline时,客户端先把一批命令暂存到buffer中,然后一次性把buffer中的命令发送到服务端,服务端处理多个命令后批量返回结果,这样做的好处是可以减少来回网络IO的次数,降低延迟,提高访问性能。当然,Redis服务端的buffer内存也会相应增长,可以控制好Pipeline命令的数量防止buffer超限。