布隆过滤器与大数据处理

本文介绍了布隆过滤器在大数据处理中的作用,包括其工作原理、误识别率及其在URL去重、垃圾邮件过滤和缓存击穿预防中的应用。同时,讨论了Redis的原子性操作和分布式锁在确保数据一致性中的角色,以及反向代理在提升网站安全性、加速请求响应和实现负载均衡方面的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录
哈希函数(散列函数)
布隆过滤器
Redis原子性操作
反向代理


哈希函数(散列函数)

哈希函数的输入域可以是非常大的范围,但是输出域是固定的范围设为R,并具有如下性质:

1、典型的哈希函数都有无穷的输入值域

2、当给哈希函数传入相同的输入值时,返回值一样

3、当给hash函数传入不同的输入值时,返回值可能一样,也可能不一样

4、很多不同的输入值所得到的返回值会均匀地分布在R上

布隆过滤器

1)布隆过滤器是用来判断一个元素是否出现在给定集合中的重要工具,具有快速,比哈希表更节省空间等优点,而缺点在于有一定的误识别率(false-positive,假阳性),亦即,它可能会把不是集合内的元素判定为存在于集合内,不过这样的概率相当小,在大部分的生产环境中是可以接受的;

2)其原理比较简单,S集合中有n个元素,利用k个哈希函数,将S中的每个元素映射到一个长度为m的位(bit)数组B中不同的位置上,这些位置上的二进制数均置为1,如果待检测的元素经过这k个哈希函数的映射后,发现其k个位置上的二进制数不全是1,那么这个元素一定不在集合S中,反之,该元素可能是S中的某一个元素(参考1);

3)到底需要多少个哈希函数,以及创建长度为多少的bit数组比较合适,为了估算出k和m的值,在构造一个布隆过滤器时,需要传入两个参数,即可以接受的误判率fpp和元素总个数n(不一定完全精确)。

使用场景:

1、网页爬虫对URL的去重,避免爬取相同的URL地址

2、反垃 圾邮件,从数十亿个垃圾邮件列表中判断某邮箱是否垃圾邮箱(同理,垃圾短信)

3、缓存击穿,将已存在的缓存放到布隆过滤器中,当黑客访问不存在的缓存时迅速返回避免缓存及DB挂掉。

Redis原子性操作

1、Redis所有单个命令的执行都是原子性的

2、多个操作也支持事务,及原子性:通过MULTI和EXEC指令包起来

Redis分布式锁:相关命令:

setnx

SETNX是『SET if Not eXists』(如果不存在,则SET)将key的值设为value,当且仅当key不存在。若给定的key已经存在,则SETNX不做任何动作。

getset

获取旧的值并设置新的值,原子性操作

expire

设置键的有效期,原子性操作

del

删除,原子性操作

应用:(1)使用互斥锁,解决缓存击穿(一份热点数据,它的访问量非常大。在其缓存失效(如过期淘汰等)的瞬间,大量请求直达存储层,导致服务崩溃。):该方法是比较普遍的做法,即,在根据key获得的value值为空时,先锁上,再从数据库加载,加载完毕,释放锁。若其他线程发现获取锁失败,则睡眠50ms后重试。至于锁的类型,单机环境用并发包的Lock类型就行,集群环境则使用分布式锁( redis的setnx)。集群环境的redis的代码如下所示:

String get(String key) { 
   String value = redis.get(key); 
   if (value  == null) { 
    if (redis.setnx(key_mutex, "1")) { 
        // 3 min timeout to avoid mutex holder crash 
        redis.expire(key_mutex, 3 * 60) 
        value = db.get(key); 
        redis.set(key, value); 
        redis.delete(key_mutex); 
    } else { 
        //其他线程休息50毫秒后重试 
        Thread.sleep(50); 
        get(key); 
    } 
  } 
} 

(2)设置永不过期(异步构建缓存:构建缓存采取异步策略,会从线程池中取线程来异步构建缓存,从而不会让所有的请求直接怼到数据库上。该方案redis自己维护一个timeout,当timeout小于System.currentTimeMillis()时,则进行缓存更新,否则直接返回value值。)

集群环境的redis代码如下所示:

String get(final String key) { 
        V v = redis.get(key); 
        String value = v.getValue(); 
        long timeout = v.getTimeout(); 
        if (v.timeout <= System.currentTimeMillis()) { 
            // 异步更新后台异常执行 
            threadPool.execute(new Runnable() { 
                public void run() { 
                    String keyMutex = "mutex:" + key; 
                    if (redis.setnx(keyMutex, "1")) { 
                        // 3 min timeout to avoid mutex holder crash 
                        redis.expire(keyMutex, 3 * 60); 
                        String dbValue = db.get(key); 
                        redis.set(key, dbValue); 
                        redis.delete(keyMutex); 
                    } 
                } 
            }); 
        } 
        return value; 
    } 

反向代理

传统代理服务器位于浏览器一侧,代理浏览器将HTTP请求发送到互联网上,而反向代理服务器位于网站机房一侧,代理网站Web服务器接收HTTP请求。和传统代理服务器可以保护浏览器安全一样,反向代理服务器也具有保护网站安全的作用,来自互联网的访问请求必须经过代理服务器,相当于在web服务器和可能的网站之间建立了一个屏障。

除了安全,代理服务器也可以通过配置缓存功能加速web请求。当用户第一次访问静态内容的时候,静态内容就被缓存在反向代理服务器上,这样当其他用户访问该静态内容的时候,就可以直接从反向代理服务器返回,加速web请求响应速度,减轻web服务器负载压力。有些网站会把动态内容也缓存在代理服务器上,当这些动态内容有变化时,通过内部通知机制通知反向代理缓存失效,反向代理会重新加载最新的动态内容再次缓存起来。

反向代理也可以实现负载均衡的功能,通过负载均衡构建的应用集群可以提高系统总体处理能力,进而改善网站高并发情况下的性能。由于web服务器不直接对外提供访问,因此web服务器不需要使用外部ip地址,而反向代理服务器则需要配置双网卡和内部外部两套IP地址。由于反向代理服务器转发请求在HTTP协议层面,因此也叫应用层负载均衡。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值