不知你大规模的用过Redis
吗?还是仅仅作为缓存的工具了?在Redis中使用最多的就是集合了,举个例子,如下场景:
Redis中集合的特点无非是一个Key
对应一系列的数据, 但是数据的作用往往是为了统计的,比如:
大型互联网应用中,数据量是巨大的,少说百万,千万,甚至是一个亿,比如电商巨头淘宝,交友巨头微信、微博;办公巨头钉钉等,哪一个的用户不是上亿?
只有针对不同场景,选择合适的集合,统计才能更方便。
聚合统计
指的是多个元素聚合的结果,比如统计多个集合的交集、并集、差集
在你需要对多个集合做聚合统计的时候,Set集合是个不错的选择,除了其中无重复的数据外,Redis还提供了对应的API
在上述的例子中交友系统中统计双方的共同好友正是聚合统计中的交集
。
在Redis
中可以userid
作为key
,好友的userid
作为value
,如下图:
统计两个用户的共同好友只需要两个Set
集合的交集,命令如下;
SINTERSTORE userid:new userid:20002 userid:20003
上述命令运行完成后,userid:new
这个key中存储的将是userid:20002
、userid:20003
两个集合的交集。
举个例子:假设交友系统中需要统计每日新增的好友,此时就需要对临近两天的好友集合取差集了,比如2020/11/1
日的好友是set1
,2020/11/2
日的好友是set2
,此时只需要对set1
和set2
做差集。
此时的结构应该如何设计呢?如下图:
userid:20201101
这个key
记录了userid
用户的2020/11/1
日的好友集合。
差集很简单,只需要执行SDIFFSTORE
命令,如下:
SDIFFSTORE user:new userid:20201102 userid:20201101
执行完毕,此时的user:new
这集合将是2020/11/2
日新增的好友。
这里还有一个更贴切的例子,微博上有个可能认识的人功能,可以使用差集,即是你朋友的好友减去你们共同的好友即是可能认识的人。
还是差集的那个例子,假设需要统计2020/11/01
和2020/11/2
总共新增的好友,此时只需要对这两日新增好友的集合做一个并集。命令如下:
SUNIONSTORE userid:new userid:20201102 userid:20201101
此时新的集合userid:new
则是两日新增的好友。
Set
集合的交差并的计算复杂度很高,如果数据量很大的情况下,可能会造成Redis的阻塞。
那么如何规避阻塞呢?建议如下:
Redis
集群中选一个从库专门负责聚合统计,这样就不会阻塞主库和其他的从库了在一些电商网站中可以看到商品的评论总是最新的在上面,这个是怎么做的呢?
最新评论列表包含了所有的评论,这就要集合对元素进行保序存储了。也就是说集合中的元素必须按序存储,称之为有序集合。
Redis
中的四种集合中List
和Sorted Set
属于有序集合。
但是List
和Sorted Set
有何区别呢?到底使用哪一种呢?
List是按照元素进入顺序进行排序,而Sorted Set可以根据元素权重来排序。 比如可以根据元素插入集合的时间确定权值,先插入的元素权重小,后插入的元素权重大。
针对这一例子中,显然这两种都是能够满足要求的,List中分页查询命令LRANGE
和Sorted Set
分页查询命令ZRANGEBYSCORE
。
但是就灵活性来说,List肯定不适合,List只能根据先后插入的顺序排序,但是大多数的场景中可能并不只是按照时间先后排序,可能还会按照一些特定的条件,此时Sorted Set
就很合适了,只需要根据独有的算法生成相应的权重即可。
二值状态指的是取值0或者1两种;在签到打卡的场景中,只需要记录签到(1)和未签到(0)两种状态,这就是典型的二值状态统计。
二值状态的统计可以使用Redis
的扩展数据类型Bitmap
,底层使用String
类型实现,可以把它看成是一个bit
数组。关于详细内容后续介绍.........
在签到统计中,0
和1
只占了一个bit
,即使一年的签到数据才365个bit
位。大大减少了存储空间。
Bitmap 提供了GETBIT/SETBIT
操作,使用一个偏移值 offset
对 bit 数组的某一个 bit 位进行读和写。不过,需要注意的是,Bitmap 的偏移量是从 0 开始算的,也就是说 offset
的最小值是 0。当使用 SETBIT
对一个 bit 位进行写操作时,这个 bit 位会被设置为 1。Bitmap 还提供了 BITCOUNT
操作,用来统计这个 bit 数组中所有1
的个数。
键值如何设计呢?key可以是userid:yyyyMM
,即是唯一id加上月份。假设员工id为10001
,需要统计2020/11
月份的签到打卡记录。
第一步,执行命令设置值,假设11月2号打卡了,命令如下:
SETBIT userid:10001:202011 1 1
BitMap是从下标0开始,因此2号则是下标为1,值设置为1则表示成功打卡了。
第二步,检查该用户11月2号是否打卡了,命令如下:
GETBIT userid:10001:202011 1
第三步,统计11月的打卡次数,命令如下:
BITCOUNT userid:10001:202011
那么问题来了,需要统计你这个签到系统中连续20天的签到打卡的用户的总数,如何处理呢?假设用户一个亿。
比如需要统计2020/11/01
到2020/11/20
天中连续打卡的人数,如何统计呢?
Bitmap
中还支持同时对多个BitMap按位做与
、或
、异或
操作,命令如下图:
思路来了,我们可以将每天的日期作为一个key
,对应的BitMap
存储一亿个用户当天的打卡情况。如下图:
此时我们只需要对2020/11/1
到2020/11/20
号的Bitmap
做按位与
操作,最终得到的一个Bitmap
中每个bit位置对应的值则代表连续20天打卡的情况,只有连续20天全部打卡,所在的bit位的值才为1。如下图:
最终可以使用BITCOUNT
命令进行统计。
可以尝试计算下内存开销,每天使用 1 个 1 亿位的 Bitmap,大约占 12MB
的内存(10^8/8/1024/1024
),20 天的 Bitmap 的内存开销约为 240MB
,内存压力不算太大。不过,在实际应用时,最好对 Bitmap
设置过期时间,让 Redis 自动删除不再需要的签到记录,以节省内存开销。
如果涉及到二值状态,比如用户是否存在,签到打卡,商品是否存在等情况可以使用Bitmap,可以有效的节省内存空间。
基数统计指统计一个集合中不重复元素的个数。
举个栗子:电商网站中通常需要统计每个网页的UV
来确定权重,网页的UV肯定是需要去重的,在Redis类型中Set
支持去重,第一时间肯定想到的是Set。
但是这里有一个问题,Set
底层使用的是哈希表和整数数组,如果一个网页的UV达到千万级别的话(一个电商网站中何止一个页面),那么对于内存的消耗极大。
Redis提供了一个扩展类型HyperLogLog用于基数统计,计算2^64个元素大概只需要12KB的内存空间
是不是很心动?但是HyperLogLog
是存在误差的,大概是在0.81%
,如果需要精准的统计,还是需要使用Set
。对于这种网页的UV来说,足够了。
在统计网页UV的时候,只需要将用户的唯一id存入HyperLogLog中,如下:
PFADD p1:uv 10001 10002 10003 10004
如果存在重复的元素,将会自动去重。
统计也很简单,使用PFCOUNT
命令,如下:
PFCOUNT p1:uv
本文介绍了统计的几种类型以及应该用什么集合存储,为了方便理解,作者将支持情况和优缺点汇总了一张表格,如下图:
Set
和Sorted Set
支持交集、并集的聚合运算,但是Sorted Set
不支差集运算。
Bitmap
也能对多个Bitmap做与、异或、或的聚合运算。
List
和SortedSet
都支持排序统计,但是List是根据元素先后插入顺序排序,Sorted Set支持权重,相对于List排序来说更加灵活。
对于二值状态统计,判断某个元素是否存在等场景,建议使用Bitmap
,节省的内存空间。
对于基数统计,在大数据量、不要求精准的情况建议使用HyperLogLog
,节省内存空间;对于精准的基数统计,最好还是使用Set
集合。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/eomV9Kh8jrMs3Kq_dKGx7A
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。