瀑布流推荐用到Redis布隆过滤器报错:ERR exbloom is already exists
瀑布流推荐用到Redis布隆过滤器报错:ERR exbloom is already existsorg.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR Error
报错场景:
我的代码中用到了redis的布隆过滤器来做瀑布流的推荐与过滤,在压测的时候,因为是多个进程并发访问,这样就导致了以下错误:
org.springframework.data.redis.RedisSystemException: Error in execution; nested exception is io.lettuce.core.RedisCommandExecutionException: ERR Error running script (call to f_7eccf151e55936985c918ea89cf06b0b5205f711): @user_script:1: ERR exbloom is already exists
解决方法:
很明显是由于并发多个线程同时操作同一个redis布隆过滤器,发生了删除与建立不一致的问题。若加锁可以解决redis报错问题,但是每次都要进行加锁,反而降低了访问效率。
压测的请求量是50000次,出现的报错小于50次,综合考虑后,这个错误不进行修改了。若报错,直接获取保底数据进行填充瀑布流推荐。
2022年10月24日补充:
上次说到这个错误不进行处理通过保底数据来处理这个问题;
今天又看代码,如下:
// 若已推荐个数为0,说明是第一次推荐,则进行初始化布隆过滤器
if(currentConsumedFeedCnt == 0){
// 删除该布隆过滤器
redisUtil.del(RedisConstant.REC_FEEDS_4_BLOOM_UUID_4_CONTENT_IDS+uuid);
// 新建布隆过滤器
redisUtil.bfreserve(RedisConstant.REC_FEEDS_4_BLOOM_UUID_4_CONTENT_IDS+uuid,
BloomConstant.EXPECT_ERROR_RATE, BloomConstant.EXPECT_STORED_NUM);
}
发现,只有符合推荐数为0的时候才进行删除并重新创建;
若是这样,感觉可以通过加轻量级的锁进行解决,所以优化后代码如下:
// 若已推荐个数为0,说明是第一次推荐,则进行初始化布隆过滤器
if(currentConsumedFeedCnt == 0){
Lock l = new ReentrantLock();
l.lock();
try{
// 删除该布隆过滤器
redisUtil.del(RedisConstant.REC_FEEDS_4_BLOOM_UUID_4_CONTENT_IDS+uuid);
// 新建布隆过滤器
redisUtil.bfreserve(RedisConstant.REC_FEEDS_4_BLOOM_UUID_4_CONTENT_IDS+uuid, BloomConstant.EXPECT_ERROR_RATE, BloomConstant.EXPECT_STORED_NUM);
}catch(Exception e){
log.error("删除或创建布隆过滤器报错:",e.getMessage());
}finally {
l.unlock();
}
}
果然,再给到我们测试的哥哥,进行压测,速度并没有影响多少,反而不进行报错了,perfect!!
更多推荐
所有评论(0)