Redis之bitmap/hyperloglog/GEO

news2024/12/26 21:34:07

Redis之bitmap/hyperlog/GEO

  • 一 面试题引入
  • 二 统计的类型
  • 三 hyperloglog
    • 3.1 行业术语
    • 3.2 hyperloglog基础
      • 3.2.1 基数
      • 3.2.2 定义
      • 3.2.3 基数统计
      • 3.2.4 基本命令
    • 3.3 HyperLogLog原理
      • 3.3.1 去重复统计的方式
      • 3.3.2 原理
    • 3.4 HyperLogLog案例实战
      • 3.4.1 需求
      • 3.4.2 方案讨论
      • 3.4.3 HyperLogLogService
  • 四 GEO
    • 4.1 面试题引入
    • 4.2 redis GEO 基础命令
    • 4.3 案例
      • 4.3.1 关键点
      • 4.3.2 代码实战
  • 五 bitmap
    • 5.1 面试题引入
    • 5.2 定义
    • 5.3 作用
    • 5.4 基础命令

一 面试题引入

  • 抖音电商直播,主播介绍的商品有评论,1个商品对应1系列的评论,排序+展现+提取10条记录。
  • 用户在手机APP上的签到打卡信息,1天对应1系列哟冰壶的签到记录,钉钉打卡签到,来没来如何统计?
  • 应用网站上的网页访问信息:1个网页对应1系列的访问点击,淘宝网首页,每天有多少人浏览首页?
  • 公司系统上线后,说一下UV、PV、DAU分别是多少?
  • 对集合中数据进行统计:
    • 在移动应用中,需要统计每天的新增用户数和第2天的留存用户数。
    • 在电商网站的商品评论中,需要统计评论表中的最新评论。
    • 在签到打卡中,需要统计一个月内连续打卡的用户数。
    • 在网页访问记录中,需要统计独立访客(Unique Visitor,VU)量
    • 痛点: 类似今日头条、抖音、淘宝这些的用户访问级别都是亿级的,请问如何处理?

二 统计的类型

在亿级系统中,常见的统计有四种

  • 聚合统计:统计多个集合元素的聚合结果(交差并等集合统计)在这里插入图片描述

  • 排序统计:抖音短视频最新评论留言的场景,请你设计一个展现列表。考察对数据结构的理解及设计思路

    • zset: 在这里插入图片描述

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

  • 二值统计:集合元素的取值就只有0和1两种,在钉钉上班签到打卡的场景中,我们只用记录有签到(1)或没签到(0)。(bitmap)

  • 基数统计:指统计一个集合中不重复的元素个数。(hyperloglog)

三 hyperloglog

3.1 行业术语

  • UV:Unique Visitor,独立访客,一般理解为客户端IP。需要去重考虑
  • PV:Page View,页面浏览量。
  • DAU:Daily Active User,日活跃用户量。登录或者使用了某个产品的用户数(去重复登录的用户),常用户反映网站、互联网应用或者网络游戏的运营情况。
  • MAU:Monthly Active User,月活跃用户量。

3.2 hyperloglog基础

3.2.1 基数

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

3.2.2 定义

Redis Hyperloglog是用来做基数统计的算法,hyperloglog的优点是,在输入元素的数量或者体积非常大时,计算基数所需的空间总是固定的,并且是很小的。
在Redis里面,每个HyperLogLog键只需要花费12KB内存,就可以计算接近2^64个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为HyperLogLog只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog不能像集合那样,返回输入的各个元素。

3.2.3 基数统计

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

3.2.4 基本命令

在这里插入图片描述

3.3 HyperLogLog原理

3.3.1 去重复统计的方式

  • HashSet

  • bitMap

    如果数据量较大亿级统计,使用bitmaps同样会有这个问题。
    bitmap是通过用位bit数组来表示各元素是否出现,每个元素对应一位,所需的总内存为N个bit。
    基数基数则将每一个元素对应的bit数组中的其中一位,比如bit数组010010101(按照从零开始下标,有的就是1、4、6、8)。
    新进入的元素只需要将已经有的bit输入和新加入的元素进行按位或计算就行。这个方式能大大减少内存占用且位操作迅速。
    But, 假设一个样本案例就是一亿个基数位值数据,一个样本就是一亿。
    如果要统计1亿个数据的基数位值,大约需要内存100000000/8/1024/1024约等于12M,内存减少占用的效果显著。这样得到统计一个对象样本的基数值需要12M。
    如果统计10000个对象样本,就需要117.18G将近120G,可见使用bitmaps还是不适用大数据量下(亿级)的基数计数场景。
    bitmaps方法是精确计算的。

  • 上述小结

    样本元素越多内存消耗急剧增大,难以管控+各种慢,对于亿级统计不太合适。

  • 解决方案:概率算法

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

3.3.2 原理

HyperLogLog只是进行不重复的基数统计,不是集合也不保存数据,只记录数量而不是具体内容。
有误差: HyperLogLog提供不精确的去重计数方案,牺牲准确率来换取空间,误差仅仅只是0.81%左右。

3.4 HyperLogLog案例实战

3.4.1 需求

  • UV的统计需要去重,一个用户一天内的多次访问只能算作一次。
  • 淘宝、天猫首页的UV,平均每天是1~1.5个亿左右。
  • 每天存1.5个亿的IP。访问者来了先去查是否存在,不存在加入。

3.4.2 方案讨论

  • 用mysql (o(╥﹏╥)o)

  • 用redis的hash结构存储

    redis — hash = <keyDay, <ip,1>>
    按照ipv4的结构来说明,每个ipv4的地址最多是15个字节,某一天的1.5亿*15个字节 = 2G,一个月60G,存储量过大。

  • hyperLogLog:在这里插入图片描述

3.4.3 HyperLogLogService

@Service
public class HyperLogLogService{

	@Resource
	private RedisTemplate redisTemplate;
	
	//模拟ip点击访问
	@PostConstruct
	public void initIp(){
		new Thread(()->{
			String ip = null;
			for(int i =0;i<200;i++){
				Random random = new Random();
				ip = random.nextInt(256) + "." + 
					random.nextInt(256) + "." + 
					random.nextInt(256) + "." + 
					random.nextInt(256) ;
				
				redisTemplate.opfForHyperLogLog().add("hll",ip);

				//模拟暂停3秒
				try{
					TimeUnit.SECODNS.sleep(3);
				}catch(InterruptedException e){
					e.printStackTrace();
				}
			}
		},"t1").start();

	}

	//获取UV
	public long uv(){
		return redisTemplate.opsForHyperLogLog().size("hll");
	}

}

四 GEO

4.1 面试题引入

移动互联网时代LBS应用越来越多,交友软件中附件的人、外卖软件中附件的美食商铺、打车软件附件的车辆等等。那这种附件各种形形色色的XXX地址位置选择是如何实现的?
会存在什么问题呢?

  • 查询性能问题,如果并发高,数据量大这种查询是要搞垮mysql数据库的。
  • 一般mysql查询的是一个平面矩形访问,而轿车服务是以我为中心N公里为半径的圆形覆盖。
  • 精准度问题,我们知道地球不是平面坐标系,而是一个圆球,这种矩形计算在长距离计算时会有很大误差,mysql不合适。

4.2 redis GEO 基础命令

  • GEOADD :添加经纬度坐标
  • GEOPOS:返回经纬度
  • GEOHASH:返回坐标的GEOHASH表示
  • GEODIST:两个位置之间距离
  • GEORADIUS:以半径为中心,查找附近的XXX
    在这里插入图片描述
  • GEORADIUSBYMEMBER:

4.3 案例

4.3.1 关键点

GEORADIUS:以给定的经纬度为中心,找出某一半径内的元素。

4.3.2 代码实战

GeoController

@RestController
public class GeoController{

	@Resource
	private GeoService geoService;

	//添加经纬度坐标
	@GetMapping("/geoadd")
	public String geoAdd(){
		return geoService.getAdd();
	}
	//获取经纬度坐标geopos
	@GetMapping("/geopos")
	public Point position(String member){
		return geoService.position(member);
	}

	//获取经纬度生成的base32编码值geohash
	@GetMapping("/geohash")
	public Point hash(String member){
		return geoService.hash(member);
	}

	//获取经纬度生成的base32编码值geohash
	@GetMapping("/geohash")
	public Point hash(String member){
		return geoService.hash(member);
	}

	//获取给定两个位置之间的距离
	@GetMapping("/geodist")
	public Distance distance(String member1,String memeber2){
		return geoService.distance(member1,member2);
	}

	//通过经纬度获取在某个固定点附件的位置(位置写死)
	@GetMapping("/georadius")
	public GeoResults radiuByxy(){
		return geoService.radiuByxy();
	}
}

GeoService

@Service
public class GeoService{
	
	public static final String CITY = "city";
	
	@Autowired
	private RedisTemplate redisTemplate;

	public String geoAdd(){
		Map<String,Point> map = new HashMap<>();
		map.put("天安门",new Point(116.41338 , 39.91092 ));
		map.put("故宫",new Point(116.40341 , 39.92409 ));
		map.put("长城",new Point(116.02407 , 40.36264 ));				
		redisTemplate.opsForGeo().add(CITY,map);
		return map.toString();
	}

	public Point position(String member){
		List<Point> list = redisTemplate.opsForGeo().position(CITY,member);
		return list.get(0);
	}

	public Point hash(String member){
		List<String> list = redisTemplate.opsForGeo().hash(CITY,member);
		return list.get(0);
	}

	public Distance distance(String member1,String memeber2){
		Distance distance = redisTemplate.opsForGeo().distance(CITY,member1,member2,
			RedisGeoCommands.DistanceUnit.KILOMETERS);
		return distance;
	}

	public GeoResults radiuByxy(){
		//经纬度:116.40048 , 39.91680  中山公园
		Circle circle = new Circle(116.40048 , 39.91680,Metrics.KILMETERS.getMultiplier());
		//返回50条
		RedisGeoCommands.GeoRadiusCommandArgs args=RedisGeoCommands.GeoRadiusCommandArgs
			.newGeoRadiusArgs().includeDistance()
			.includeCoordinates().sortDescending().limit(50);
		GeoResults redius = redisTemplate.opsForGeo().radius(CITY,circle,args)
		return redius;
	}
}

五 bitmap

5.1 面试题引入

  • 日活统计
  • 连续签到打卡
  • 最近一周的活跃用户
  • 统计指定用户一年之中的登录天数
  • 用户按照一年365天,哪几天登录过,那几天没有登录,全年中登录的天数共计多少?

5.2 定义

由0和1状态表现的二进制位的bit数组。
在这里插入图片描述
用String类型作为底层数据结构实现的一种统计二值状态的数据类型。
位图本质是数组,它是基于String数据类型的按位的操作。该数组由多个二进制位组成,每个二进制位都对应一个偏移量(我们可以称之为一个索引或者位格)。Bitmap支持的最大位数是2^32位,它可以极大的节约存储空间,使用512内存就可以存储多达42.9亿的字节信息。

5.3 作用

用于状态统计,Y、N,类似AtomicBoolean。

  • 用户是否登录过Y、N
  • 电影、广告是否被点击播放过
  • 钉钉打卡上下班,签到统计

5.4 基础命令

Bitmap的偏移量时从零开始算的.
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/562339.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五、SpringMVC从入门到入坟

一、SpringMVC概念 SpringMVC 是 Spring 框架中的一个模块&#xff0c;它是一个基于 MVC设计模式的 Web 框架&#xff0c;用于构建基于 Java 技术的 Web 应用程序。Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。 它的主要原理是将 Web 应用程序分成模型&…

实时频谱-2.4窗口函数

窗口函数 在离散傅立叶变换(DFT)分析运算中&#xff0c;一个固有的假设是要处理的数据是单个周期定期重复的信号。例如&#xff0c;在图2-8中的帧2上应用DFT处理时&#xff0c;信号上会进行周期性扩展。 在连续的帧之间一般会发生不连续点&#xff0c;如图 2-9 所示。 这些人…

平板电脑哪种电容笔更好用?平价好用的iPad电容笔推荐

我是一个非常喜欢数码产品的发烧者&#xff0c;多少了解一些关于电容笔的知识。我想&#xff0c;苹果原装的电容笔与普通的电容笔的不同之处就是他们所能产生的压力感觉不同。由于苹果的电容笔拥有独一无二的“重力压感”&#xff0c;使得它可以让我们在一幅画面中快速填充色彩…

Docker笔记8 | Docker内部以及容器之间如何管理数据?

8 | Docker内部以及容器之间如何管理数据&#xff1f; 1 数据卷1.1 什么是数据卷&#xff1f;1.2 数据卷的特性1.3 创建数据卷1.4 查看数据卷1.5 启动挂在数据卷的容器1.6 删除数据卷 2 挂在主机目录2.1 挂载主机目录作为数据卷2.2 查看数据卷信息2.3 挂载本地主机文件作为数据…

深度学习基础入门篇-序列模型[11]:循环神经网络 RNN、长短时记忆网络LSTM、门控循环单元GRU原理和应用详解

【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化算法、卷积模型、序列模型、预训练模型、对抗神经网络等 专栏详细介绍&#xff1a;【深度学习入门到进阶】必看系列&#xff0c;含激活函数、优化策略、损失函数、模型调优、归一化…

中原雄狮官网上线 | LTD物流服务行业案例分享

​一、公司介绍 中原雄狮崛起于2017年&#xff0c;彼时&#xff0c;全国货运行业存在许多不良行为&#xff0c;无赖货主和黑心货站恶意拖欠货车司机运费&#xff0c;而货车司机作为弱势群体却势单力薄无依无助的问题&#xff0c;为了让司机的血汗钱能颗粒归仓&#xff0c;中原雄…

一个活人的标准:灵·魂·身体到底是咋回事儿

正常情况 人类对自我的探求一直没有减弱过&#xff0c;总是在发现并给我们带来惊喜。今天也通过神赐给我们的圣经来跟大家分享一下灵魂身体之间的关系。 神创造了人&#xff0c;并给了人独一的灵。所以人是万物的灵长&#xff0c;比任何生物都聪明。一个“活人”必须要有的就是…

计算机图形学 | 有趣的测试和合并——片元操作

计算机图形学 | 有趣的测试和合并——片元操作 计算机图形学 | 有趣的测试和合并——片元操作10.1 再看片元操作片元操作几个重要的缓冲区 10.2 谁遮住了我&#xff1f;消隐的概念面剔除深度测试深度缓冲器算法&#xff08;Z-buffer算法&#xff09;深度排序算法&#xff08;de…

新华三发布绿洲平台3.0,五大能力升级,构筑坚实用数底座

当前我国数字经济飞速发展&#xff0c;据中国信息通信研究院发布的《中国数字经济发展研究报告&#xff08;2023年&#xff09;》显示&#xff0c;2022年&#xff0c;我国数字经济规模达到50.2万亿元&#xff0c;同比名义增长10.3%&#xff0c;已连续11年显著高于同期GDP名义增…

HTTP协议概述(见过花开就好了,何必在意花落谁家呢)

文章目录 一、简介二、HTTP版本三、HTTP 方法四、HTTP状态码五、HTTP 请求流程分析1.请求报文2.响应报文 一、简介 客户端输入域名&#xff0c;经域名解析成IP地址&#xff0c;在与服务端建立数据传输之前&#xff0c;要先建立TCP连接&#xff08;三次握手&#xff09;&#x…

Day03 02-MySQL多表查询详解

文章目录 第八章 多表查询8.1 多表查询介绍8.1.1 什么是多表查询8.1.2 多表查询基本写法8.1.3 笛卡尔积8.1.4 连接查询条件限制 8.2 连接查询分类8.2.1 内连接8.2.2 外连接8.2.3 全连接8.2.4 自然连接 8.3 子查询8.3.1 子查询简介8.3.2 在where子句中8.3.3 在from子句中8.3.4 在…

是德科技keysight E8257D信号发生器

产品概览 Keysight E8257D (Agilent) PSG 模拟信号发生器提供业界领先的输出功率、电平精度和高达 67 GHz 的相位噪声性能&#xff08;工作频率可达 70 GHz&#xff09;。Agilent PSG 模拟信号发生器的高输出功率和卓越的电平精度通常无需使用外部放大器来测试高功率设备&…

国内热门AI智能音箱品牌都采用了哪些功放芯片

音频功放IC是各类音响、耳机等器材不可或缺的一部分&#xff1b;音频功率放大器芯片俗称“扩音器”&#xff0c;是音响系统中最基本的设备&#xff0c;负责将来自信号源的微弱电信号进行放大&#xff0c;以驱动扬声器发声&#xff0c;从而将声音传至我们的听觉系统。 现如今&a…

浅谈电解电容在电路设计中的作用

谈起电解电容我们不得下多了解一下它的作用 1、滤波作用 在电源电路中&#xff0c;整流电路将交流变成脉动的直流&#xff0c;而在整流电路之后接入一个较大容量的电解电容&#xff0c;利用其充放电特性(储能作用)&#xff0c;使整流后的脉动直流电压变成相对比较稳定的直流电…

启动页/闪屏/引导页-你还傻傻分不清?

启动页/闪屏/引导页-你还傻傻分不清&#xff1f;&#xff08;转载&#xff09; - 知乎 今天就跟大家一起来认识一下开屏三姐妹&#xff1a;启动页/闪屏/引导页。 通常三姐妹出场顺序如下&#xff1a; 下面我们来深入认识一下这三姐妹&#xff1a; 1、启动页 定义&#xff1…

ChatGPT:你真的了解网络安全吗?浅谈网络安全攻击防御进行时之传统的网络安全

ChatGPT&#xff1a;你真的了解网络安全吗&#xff1f;浅谈网络安全攻击防御进行时 传统的网络安全 ChatGPT&#xff08;全名&#xff1a;Chat Generative Pre-trained Transformer&#xff09;&#xff0c;美国OpenAI 研发的聊天机器人程序&#xff0c;是人工智能技术驱动的自…

搭建hadoop集群

搭建Hadoop集群 1&#xff0c;准备环节 Hadoop完全分布式集群式&#xff08;master/slave&#xff09;主从架构。 因为Hadoop是由java编写的&#xff0c;所以需要Java的环境支持&#xff0c;作为开发者我们需要安装jdk。 安装jdk的教程http://t.csdn.cn/6qJKg 下载Hadoop的…

spring(不是springboot)集成apllo方案

现在到处都是基于 springboot 的微服务项目。 不巧手头碰到了一个 spring 的项目&#xff0c;打war包直接放到tomcat中启动的。 现在要将apollo集成进来&#xff0c;要求 Access Key 不可以放在properties 配置文件中&#xff0c;要统一使用apollo来管理。 步骤如下&#xff1a…

《计算机网络——自顶向下方法》精炼——3.5.5-3.6.1

学习是劳动&#xff0c;是充满思想的劳动。——乌申斯基 文章目录 TCP流量控制TCP连接管理建立TCP连接拆除TCP连接TCP状态的转换 TCP拥塞控制情况1&#xff1a;两个发送方&#xff0c;一个无限缓存的路由器情况2&#xff1a;两台主机&#xff0c;一台具有有限缓存的路由器情况3…

【源码解析】EasyExcel导入导出源码解析

EasyExcel介绍 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存&#xff0c;poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题&#xff0c;但POI还是有一些缺陷&#xff0c;比如07版Excel解压缩以及解压后存储都…