记一次线上问题,布隆过滤器使用中碰到的坑

前几天我开发了的投票小程序终于上线了,上午都运行的好好的,用户投票操作都流畅的很,突然下午3点的时候产品经理找到了我,说投票报错了。投票系统投票报错,这可相当于系统崩溃了啊。吓得我菊花一紧,虎躯一震,赶紧排查起问题来。我飞快的登录了项目部署服务器,打开日志排查,发现某处报了空指针异常,但是没有打印出堆栈信息。光有一个空指针我也没着啊,我仔细查看了代码,是有打印堆栈信息啊。问了旁边的张大师,才知道是tomcat的配置禁用了堆栈信息的打印,百度了一下,加了了一串配置,成功打印出堆栈信息。才发现是布隆过滤器的bitSet报了空指针异常。我登上redis发现,redis中是有值的啊,为啥为报空指针异常呢?百思不得其解,关键是之前压测也没出这个问题啊!

经过我和另外两个同事的认真排查,最终终于发现了这个坑是怎么回事了!

    public RedisBitSet(RedisTemplate jedisCluster, String name, int expire) {
        this.jedisCluster = jedisCluster;
        this.name = name;
        //初始化化  --- add bu whz
        Boolean isExits = jedisCluster.opsForValue().getBit(name, 1);
        if(isExits==null || isExits==false ){
            set(1, false);
            jedisCluster.expire(this.name, expire, TimeUnit.DAYS);
        }
    }
     public void set(long bitIndex, boolean value) {
        this.jedisCluster.opsForValue().setBit(this.name, bitIndex, value);

    }   

看代码可以发现,我在初始化RedisBitSet的时候,做了个操作,把1的比特位置设置为了false。这为后面的大坑埋了个大大的伏笔。

  Boolean isExits = redisTemplate.opsForValue().getBit(CacheConstant.CACHE_METADATA + "redisbit_" + dateStr, 1);

在投票之前我做了个判断,每次都新建了个bloomFilter,然后判断1的比特位如果为null或false就初始化布隆过滤器。实际上这个地方有个很大的问题,new BloomFilter可以放到外面作为静态成员变量,随着项目启动加载一次就行了。但真正的问题不是这个,而是后面投票的时候,刚好有个key的字节哈希值取余正好是1,把初始化的1的false置为了true。导致后面这个判断if (isExits == null || isExits == false) 一直为false,然后每次都没有bindBloomFilter,bitSet的值始终为空。

这个问题排查了很久才发现,给了我很大的教训。以后写代码一定要考虑的更周全一点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值