Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO(上)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO

Redis案例实战之Bitmap、Hyperloglog、GEO


经典面试题


面试题1


抖音电商直播,主播介绍的商品有评论,一个商品对应了一系列的评论,排序+展现+取前10条记录


用户在手机APP上的签到打卡信息:一天对应一系列用户的签到记录,新浪微博、钉钉签到,来没来如何统计?


应用网站上的网页访问信息:一个网页对应一系列的访问点击,淘宝网首页,每天有多少人浏览首页?


你们公司系统上线后,说一下UV、PV、DAU分别是多少?


面试题2


面试问


记录对集合中的数据进行统计


在移动应用中,需要统计每天的新增用户数和第2天的留存用户数;


在电商网站的商品评论中,需要统计评论列表中的最新评论;


在签到打卡中,需要统计一个月内连续打卡的用户数;


在网页访问记录中,需要统计独立访客(Unique Visitor,UV)量。


痛点:类似今日头条、抖音、淘宝这样的额用户访问级别都是亿级的,请问如何处理?


需求痛点


亿级数据的收集+清洗+统计+展现


一句话:存的进+取得快+多维度


真正有价值的是统计…


统计的类型有哪些?


亿级系统中常见的四种统计


聚合统计


统计多个集合元素的聚合结果,就是前面讲解过的交差并等集合统计


排序统计


抖音短视频最新评论留言的场景,请你设计一个展现列表。这个主要考察的就是数据结构和设计思路


设计思路


以抖音vcr最新的留言评价为案例,所有评论需要两个功能,按照时间排序(正序、反序)+分页显示

能够排序+分页显示的redis数据结构是什么合适?

在面对需要展示最新列表、排行榜等场景时,如果数据更新频繁或者需要分页显示的话,建议使用Zset

按照时间戳进行排列即可。


二值统计


集合元素的取值就只有0和1两种。


在钉钉上班签到打卡的场景中,我们只用记录有签到(1)或没签到(0)特指bigmap


基数统计


指统计一个集合中不重复的元素个数,特指hyperloglog


Hyperloglog


行业术语


什么是UV


Unique Visitor 独立访客,一般理解为客户单ip,一般需要做去重考虑。


什么是PV


Page View 页面浏览量,不需要考虑去重


什么是DAU


Daily Active User 日活跃用户量:登陆或者使用了某个产品的用户数(去掉重复登陆的用户)


常用于反应网站、互联网应用或者网络游戏的运营情况


什么是MAU


Monthly Active User:月活跃用户量


需求


很多计数类场景,比如 每日注册 IP 数、每日访问 IP 数、页面实时访问数 PV、访问用户数 UV等。


因为主要的目标高效、巨量地进行计数,所以对存储的数据的内容并不太关心。


也就是说它只能用于统计巨量数量,不太涉及具体的统计对象的内容和精准性。


统计单日一个页面的访问量(PV),单次访问就算一次。


统计单日一个页面的用户访问量(UV),即按照用户为维度计算,单个用户一天内多次访问也只算一次。


多个key的合并统计,某个门户网站的所有模块的PV聚合统计就是整个网站的总PV。


Hyperloglog是什么?


基数


是一种数据集,去重复后的真实个数

去重复统计功能的基数估计算法,就是Hyperloglog


基数统计


用于统计一个集合中不重复的元素个数,就是对集合去重复后剩余元素的计算


总之就是去重脱水后的真实数据


基本命令



原理


如果说去重统计你会先想到那些方式呢?


HashSet


bitmap


如果数据显较大亿级统计,使用bitmaps同样会有这个问题。


bitmap是通过用位bit数组来表示各元素是否出现,每个元素对应一位,所需的总内存为N个bit。


基数计数则将每一个元素对应到bit数组中的其中一位,比如bit数组010010101(按照从零开始下标,有的就是1、4、6、8)。


新进入的元素只需要将已经有的bit数组和新加入的元素进行按位或计算就行。这个方式能大大减少内存占用且位操作迅速。


But,假设一个样本案例就是一亿个基数位值数据,一个样本就是一亿


如果要统计1亿个数据的基数位值,大约需要内存100000000/8/1024/1024约等于12M,内存减少占用的效果显著。


这样得到统计一个对象样本的基数值需要12M。


如果统计10000个对象样本(1w个亿级),就需要117.1875G将近120G,可见使用bitmaps还是不适用大数据量下(亿级)的基数计数场景,


但是bitmaps方法是精确计算的。


结论


样本元素越多,内存消耗急剧增大,难以管控+各种慢,对于亿级统计不太适合,大数据害死人,简单说就是量变引起质变。


方法


通过牺牲准确率来换取空间,对于不要求绝对准确率的场景下可以使用,因为概率算法不直接存储数据本身,通过一定的概率统计方法预估基数值,同时保证误差在一定范围内,由于又不储存数据故此可以大大节约内存。


HyperLogLog就是一种概率算法的实现。


原理


其本质就只是进行不重复的技术统计,不是集合也不保存数据,只记录数量而不是具体内容。


但是缺点就是有误差,其提供不准确的去重计数方案,牺牲准确率来换取空间,官网上说误差仅仅只是0.81%左右。


这个误差如何得来的呢?


淘宝网站首页亿级UV的Redis统计方案


需求


UV的统计需要去重,一个用户一天内的多次访问只能算作一次


淘宝、天猫首页的UV,平均每天是1~1.5亿左右


每天存1.5亿的IP,访问者来了后先去查是否存在,不存在就加入


方案设计


mysql


数据量太大,且没意义


redis的hash结构存储

redis——hash = >


按照ipv4的结构来说明,每个ipv4的地址最多是15个字节(ip = “192.168.111.1”,最多xxx.xxx.xxx.xxx)


某一天的1.5亿 * 15个字节= 2G,一个月60G,redis死定了。


hyperloglog


HyperLogLogService


@Service
@Slf4j
public class HyperLogLogService
{
    @Resource
    private RedisTemplate redisTemplate;
    /**
     * 模拟后台有用户点击首页,每个用户来自不同ip地址
     */
    @PostConstruct
    public void init()
    {
        log.info("------模拟后台有用户点击首页,每个用户来自不同ip地址");
        new Thread(() -> {
            String ip = null;
            for (int i = 1; i <=200; i++) {
                Random r = new Random();
                ip = r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256) + "." + r.nextInt(256);
                Long hll = redisTemplate.opsForHyperLogLog().add("hll", ip);
                log.info("ip={},该ip地址访问首页的次数={}",ip,hll);
                //暂停几秒钟线程
                try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); }
            }
        },"t1").start();
    }
}


Redis系列-8.Redis案例实战之Bitmap、Hyperloglog、GEO(下):https://developer.aliyun.com/article/1414711

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
14天前
|
存储 NoSQL PHP
如何用Redis高效实现点赞功能?用Set?还是Bitmap?
在众多软件应用中,点赞功能几乎成为标配。本文从实际需求出发,探讨如何利用 Redis 的 `Set` 和 `Bitmap` 数据结构设计高效点赞系统,分析其优缺点,并提供 PHP 实现示例。通过对比两种方案,帮助开发者选择最适合的存储方式。
27 3
|
25天前
|
NoSQL 关系型数据库 MySQL
MySQL与Redis协同作战:优化百万数据查询的实战经验
【10月更文挑战第13天】 在处理大规模数据集时,传统的关系型数据库如MySQL可能会遇到性能瓶颈。为了提升数据处理的效率,我们可以结合使用MySQL和Redis,利用两者的优势来优化数据查询。本文将分享一次实战经验,探讨如何通过MySQL与Redis的协同工作来优化百万级数据统计。
55 5
|
27天前
|
存储 NoSQL 定位技术
Redis geo原理
Redis的GEO功能基于Earth Mapper(http://earth-api.org/)库,它允许存储地理位置信息并执行一些基于该信息的操作。
25 3
|
27天前
|
存储 NoSQL 定位技术
Redis GEO
10月更文挑战第19天
31 1
|
29天前
|
NoSQL 算法 关系型数据库
Redis HyperLogLog
10月更文挑战第17天
18 2
|
1月前
|
缓存 NoSQL Java
Spring Boot与Redis:整合与实战
【10月更文挑战第15天】本文介绍了如何在Spring Boot项目中整合Redis,通过一个电商商品推荐系统的案例,详细展示了从添加依赖、配置连接信息到创建配置类的具体步骤。实战部分演示了如何利用Redis缓存提高系统响应速度,减少数据库访问压力,从而提升用户体验。
72 2
|
1月前
|
消息中间件 分布式计算 NoSQL
大数据-41 Redis 类型集合(2) bitmap位操作 geohash空间计算 stream持久化消息队列 Z阶曲线 Base32编码
大数据-41 Redis 类型集合(2) bitmap位操作 geohash空间计算 stream持久化消息队列 Z阶曲线 Base32编码
27 2
|
2月前
|
缓存 NoSQL 应用服务中间件
Redis实战篇
Redis实战篇
|
1月前
|
消息中间件 缓存 NoSQL
Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。
【10月更文挑战第4天】Redis 是一个高性能的键值对存储系统,常用于缓存、消息队列和会话管理等场景。随着数据增长,有时需要将 Redis 数据导出以进行分析、备份或迁移。本文详细介绍几种导出方法:1)使用 Redis 命令与重定向;2)利用 Redis 的 RDB 和 AOF 持久化功能;3)借助第三方工具如 `redis-dump`。每种方法均附有示例代码,帮助你轻松完成数据导出任务。无论数据量大小,总有一款适合你。
77 6
|
10天前
|
缓存 NoSQL 关系型数据库
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题
本文详解缓存雪崩、缓存穿透、缓存并发及缓存预热等问题,提供高可用解决方案,帮助你在大厂面试和实际工作中应对这些常见并发场景。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:如何解决Redis缓存雪崩、缓存穿透、缓存并发等5大难题