做的项目为一个OLAP平台项目
首先环境中使用的是redis集群,主要作用是用来存储query的结果,用来遇到相同查询时使用缓存来回答
1、第一个坑:在删除时,jedismoveddataexception: moved
扫描所有的key时有keys()和scan()两种方法,由于项目中存进redis的key和value值都是byte[],且做过一些变换,所以如果scan()出来使用List 时,会看到keys都是乱码。在删除时候使用JedisClusterCRC16.getSlot()获取该key所处的slot值,再区分各个slot来分别删除。但是使用keys获取的byte[]和scan获取的string.getByte[]计算得到的slot值不一致,导致在删除的时候抛了这个异常,在删除时对应master在管理的所有slot中找不到当前要删除的slot,解决办法是使用List<byte[]>来获取scan的值
2、第二个坑:当某个操作导致read timeout后,导致jedis pool中的没有可用的jedis对象后,pool.getResource()会被卡死
导致在cache中查询query结果时卡死,解决方案是使用一个线程来监控query 的时间,如果query超时,则interrupt该线程,在自测过程中发现,在卡死过程中并没有被真正的interrupt,通过debug发现,redis.clients.util.Pool#getResource中将所有异常都捕获了,也就是说我们的InterruptedException被吞掉了,代码如下:
public T getResource() {
try {
return internalPool.borrowObject();
} catch (NoSuchElementException nse) {
throw new JedisException(“Could not get a resource from the pool”, nse);
} catch (Exception e) {
throw new JedisConnectionException(“Could not get a resource from the pool”, e);
}
}
所以需要在外层单独捕获JedisConnectionException,如果是这个异常需要重置interrupted标志位