欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

七夕不孤!单身程序员源码讲解:redis布隆算法实现数据锁!

程序员文章站 2024-03-18 23:59:04
...

今天七夕节了,不知道大家过的是甜甜蜜蜜还是水深火热呀,已婚老男人不配过七夕,只能默默的蹲在电脑前敲敲代码,写写文档,这不,趁着公司下午放假的功夫,我也整理了一下关于Redis的布隆过滤器和锁的相关知识,这里分享给大家,希望能让大家更好的学习。

七夕不孤!单身程序员源码讲解:redis布隆算法实现数据锁!

简单一点,对于互联网开发,我们从单机到多机一直到微服务,随着数据量的增多,对于数据库的压力也随之增大,这个时候,勤劳的程序员们,将数据分为冷数据和热点数据,然后把热点数据存储在缓存中,提升查询效率并且减轻数据库的压力,但是,这是理想环境,毕竟互联网没有想象中的那么平静。

比方说下面这种情况

七夕不孤!单身程序员源码讲解:redis布隆算法实现数据锁!

黑客,一个让程序员向往但是又让安全部门感到头疼的人群,当上面的场景:有大量不同的key获取后台数据的时候该怎么处理,

在这个时候,我就不得不吹捧一波老祖宗的智慧,宁可错杀三千,绝不放过一个的纯真理念,从而产生了神奇的布隆过滤器,那布隆过滤器是怎么一个执行流程呢?继续往下看

布隆过滤器是─个使用错误率来换取空间和时间的算法错误率主要体现在:他说数据存在,那么不一定存在不存在,一定不存在

七夕不孤!单身程序员源码讲解:redis布隆算法实现数据锁!

代码只展示部分吧,因为完整展现太多了,没得办法

\* 判断keys是否存在于集合where中
 \*/
public boolean isExist(String where, String key) {
    long\[\] indexs = getIndexs(key);
    boolean result;
    //这里使用了Redis管道来降低过滤器运行当中访问Redis次数 降低Redis并发量
    Pipeline pipeline = jedis.pipelined();
    try {
        for (long index : indexs) {
            pipeline.getbit(where, index);
        }
        result = !pipeline.syncAndReturnAll().contains(false);
    } finally {
        pipeline.close();

    }
// if (!result) {
// put(where, key);
// }

return result;
}


/\*\*
 \* 将key存入redis bitmap
 \*/
private void put(String where, String key) {
    long\[\] indexs = getIndexs(key);
    //这里使用了Redis管道来降低过滤器运行当中访问Redis次数 降低Redis并发量
    Pipeline pipeline = jedis.pipelined();
    try {
        for (long index : indexs) {
            pipeline.setbit(where, index, true);
        }
        pipeline.sync();
        /\*\*
         \* 把数据存储到mysql中
         \*/
    } finally {
        pipeline.close();
    }
}




/\*\*
 \*  根据key获取bitmap下标方法来自guava
 \*/
public long\[\] getIndexs(String key) {
    long hash1 = hash(key);
    long hash2 = hash1 >>> 16;
    long\[\] result = new long\[numHashFunctions\];
    for (int i = 0; i < numHashFunctions; i++) {
        long combinedHash = hash1 + i \* hash2;
        if (combinedHash < 0) {
            combinedHash = ~combinedHash;
        }
        result\[i\] = combinedHash % numBits;
    }
    return result;
}

/\*\*
 \* 获取一个hash值 方法来自guava
 \*/
private long hash(String key) {
    Charset charset = Charset.forName("UTF-8");
    return Hashing.murmur3\_128().hashObject(key, Funnels.stringFunnel(charset)).asLong();
}


private static int optimalNumOfHashFunctions(long n, long m) {
    return Math.max(1, (int) Math.round((double) m / n \* Math.log(2)));
}

当然了,出现这种情况也不是只有黑客攻击,还有一种,我想很多人都参与过,它叫做限时秒杀,比如淘宝双十一,这个时候会造成的一种情况是大量的客户端拿着相同的Key去后台获取数据,但是,这种情况,你不能通过布隆过滤器然后去不放过一个吧,那该怎么办呢?锁住他呗!

七夕不孤!单身程序员源码讲解:redis布隆算法实现数据锁!

可能这几张图这么看有那么一点点的模糊,个人还有日常工作,也就没有完整的整理形成文档,就以图片和简单的文字进行了简述。

希望对大家有帮助!文章来源:SegmentFault博客

如果你想更好的提升你的编程能力,成为一个强大的C/C++程序员!不妨和一些志同道合的小伙伴一起学习成长!

C语言C++编程学习交流圈子,【点击进入微信公众号:C语言编程学习基地

有一些源码和资料分享,欢迎转行也学习编程的伙伴,和大家一起交流成长会比自己琢磨更快哦!