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

本文涉及的产品
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

目录
相关文章
|
2月前
|
存储 NoSQL 前端开发
Redis专题-实战篇一-基于Session和Redis实现登录业务
本项目基于SpringBoot实现黑马点评系统,涵盖Session与Redis两种登录方案。通过验证码登录、用户信息存储、拦截器校验等流程,解决集群环境下Session不共享问题,采用Redis替代Session实现数据共享与自动续期,提升系统可扩展性与安全性。
232 3
Redis专题-实战篇一-基于Session和Redis实现登录业务
|
2月前
|
存储 缓存 NoSQL
Redis专题-实战篇二-商户查询缓存
本文介绍了缓存的基本概念、应用场景及实现方式,涵盖Redis缓存设计、缓存更新策略、缓存穿透问题及其解决方案。重点讲解了缓存空对象与布隆过滤器的使用,并通过代码示例演示了商铺查询的缓存优化实践。
189 1
Redis专题-实战篇二-商户查询缓存
|
5月前
|
缓存 监控 NoSQL
Redis 实操要点:Java 最新技术栈的实战解析
本文介绍了基于Spring Boot 3、Redis 7和Lettuce客户端的Redis高级应用实践。内容包括:1)现代Java项目集成Redis的配置方法;2)使用Redisson实现分布式可重入锁与公平锁;3)缓存模式解决方案,包括布隆过滤器防穿透和随机过期时间防雪崩;4)Redis数据结构的高级应用,如HyperLogLog统计UV和GeoHash处理地理位置。文章提供了详细的代码示例,涵盖Redis在分布式系统中的核心应用场景,特别适合需要处理高并发、分布式锁等问题的开发场景。
390 41
|
5月前
|
缓存 NoSQL 算法
高并发秒杀系统实战(Redis+Lua分布式锁防超卖与库存扣减优化)
秒杀系统面临瞬时高并发、资源竞争和数据一致性挑战。传统方案如数据库锁或应用层锁存在性能瓶颈或分布式问题,而基于Redis的分布式锁与Lua脚本原子操作成为高效解决方案。通过Redis的`SETNX`实现分布式锁,结合Lua脚本完成库存扣减,确保操作原子性并大幅提升性能(QPS从120提升至8,200)。此外,分段库存策略、多级限流及服务降级机制进一步优化系统稳定性。最佳实践包括分层防控、黄金扣减法则与容灾设计,强调根据业务特性灵活组合技术手段以应对高并发场景。
1556 7
|
5月前
|
机器学习/深度学习 存储 NoSQL
基于 Flink + Redis 的实时特征工程实战:电商场景动态分桶计数实现
本文介绍了基于 Flink 与 Redis 构建的电商场景下实时特征工程解决方案,重点实现动态分桶计数等复杂特征计算。通过流处理引擎 Flink 实时加工用户行为数据,结合 Redis 高性能存储,满足推荐系统毫秒级特征更新需求。技术架构涵盖状态管理、窗口计算、Redis 数据模型设计及特征服务集成,有效提升模型预测效果与系统吞吐能力。
559 2
|
存储 缓存 NoSQL
Redis实战之入门进阶到精通
Redis 是一个远程内存数据库,它不仅性能强劲,而且还具有复制特性以及为解决问题而生的独一无二的数据模型。Redis 提供了 5 种不同类型的数据结构,各式各样的问题都可以很自然地映射到这些数据结构上:Redis 的数据结构致力于帮助用户解决问题,而不会像其他数据库那样,要求用户扭曲问题来适应数据库。除此之外,通过复制、持久化(persistence)和客户端分片(client-side sharding)等特性,用户可以很方便地将 Redis 扩展成一个能够包含数百 GB 数据、每秒处理上百万次请求的系统。
Redis实战之入门进阶到精通
|
存储 NoSQL Java
当Java遇到Redis:Jedis实战入门
Redis是一个开源,高级的键值存储和一个适用的解决方案,用于构建高性能,可扩展的Web应用程序。本文将概要介绍Redis的特性和语法,并以实例代码的形式介绍如何通过Jedis在java语言环境下控制Redis,帮助各位读者快速入门。
1762 0
|
NoSQL 数据库 Redis
Redis学习到实战(一)基础与入门
一、前言 一直都说要写一些redis,但是苦于网上资料甚少,Redis又不是基于java的,源码也没深究。
897 0
下一篇
oss云网关配置