前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >电商中如何高效的判断某用户已参加了某活动?

电商中如何高效的判断某用户已参加了某活动?

作者头像
业余草
发布2019-06-24 09:56:47
7410
发布2019-06-24 09:56:47
举报
文章被收录于专栏:业余草业余草

点击上方“业余草”,选择“置顶公众号”

第一时间获取技术干货和业界资讯!

640?wx_fmt=jpeg
640?wx_fmt=jpeg

看了这个话题,我相信很多人都会说,这还不简单。某用户参加了某优惠活动,购买了某商品等,数据库中肯定有对应记录吧。查询一下不久好了!

好吧,如果这是在面试中,你这样回答。game over,你肯定挂掉了。

我前面所有的文章,包括网上其他的一些文章,都在描述一件事,高并发场景下,一定要减少 DB 的访问。因为,压力一般都在 DB 端。所以,查询 DB,是一个非常笨的方法,而且很可能引起灾难性问题。

640
640

从 Nginx 到 DB 数据库,流量是成漏斗型的,能访问到 DB 的,最终都是很少很少的请求,大部分请求都被过滤掉了,这一点你一定要清楚。

既然你说了不能用 DB,那我可以使用内存吧。内存很好高,HashSet 存储的元素不能重复,刚好可以利用。

但我要告诉你的是,HashSet 在数据规模小时是王者,随着数据规模增大,变青铜,到黑铁,最后是塑料,崩溃了!

假设现在有 1 亿的数据,下面的测试代码,大家自己去执行一下,我就不贴结果了。

640?wx_fmt=png
640?wx_fmt=png

所以,在数据量很大的时候,HashSet 并不是一个很好的选择。比如,某知名面试题,直接问你,如何判断一个数是否在40亿个整数中?

如果你要使用 HashSet,则可能直接 Game over!

所以,有没有好办法呢?不知道布隆过滤器,大家有没有听说过。

布隆过滤器,英文叫 BloomFilter,可以说是一个二进制向量和一系列随机映射函数实现。可以用于检索一个元素是否在一个集合中。

Bloom Filter 是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合。Bloom Filter 的这种高效是有一定代价的:在判断一个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter 不适合那些“零错误”的应用场合。而在能容忍低错误率的应用场合下,Bloom Filter 通过极少的错误换取了存储空间的极大节省。

640
640

布隆过滤器的原理很简单。有一组函数和一个位数组,每个元素经过这一组 hash 函数,得到第对应位为 1。比如,存储“xttblog”,经过 2 个哈希函数得出位数组的下标为 3 和 6。那么 3 和 6 下标的元素改为 1。再比如,存储“业余草”,经过这一组 hash 函数计算出位数组的下标为 6 和 10,那么 6 和 10 下标的元素改为 1。其他元素以此类推。

上面我这组 Hash 函数是有两个计算方法。实际使用中可以存在多个哈希函数,哈希函数越多,散列度越高,计算出来的误识别率相对也会低一些。这个大家可以自己去尝试,位数组的大小,哈希函数的多少,散列度都有些关系。 知道这个原理后,判断元素是否存在就很简单了。判断之前,先计算通过一组 Hash 函数,计算出哈希值,判断对应位数组中的元素全为 1,则这个元素一定存在。否则不存在。

布隆过滤器效率非常的高,被广泛的采用。网页黑名单系统、垃圾邮件过滤系统、爬虫的网址判重系统以及解决缓存穿透问题等,处处有它的影子。我们这里用来判断用户是否参加某个活动,是有一定的错误率的,但是影响不大。具体其他公司是否采用,和具体的业务也有一定的关系。

今天先不讲布隆过滤器的实现源码。我直接先来一个使用。Guava 工具包中有现成的实现,不再重复造轮子。

640?wx_fmt=png
640?wx_fmt=png

使用 Guava 有一个缺陷就是分布式系统下,不太好用。所以,Redis 中有一个高级模块 RedisBloom。使用它需要先安装它。

640?wx_fmt=png
640?wx_fmt=png

这个模块不仅仅实现了布隆过滤器,还实现了 CuckooFilter(布谷鸟过滤器),以及 TopK 功能。今天主要说布隆过滤器。安装好后,使用很简单,测试代码如下:

640?wx_fmt=png
640?wx_fmt=png

上面用到的几个命令,解释一下:

  • bf.add 添加元素到布隆过滤器
  • bf.exists 判断元素是否在布隆过滤器
  • bf.madd 添加多个元素到布隆过滤器,bf.add只能添加一个
  • bf.mexists 判断多个元素是否在布隆过滤器

更多相关功能,建议大家到 Redis 官网学习。喜欢本文的,动动手指,谢谢!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年06月23日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis
腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档