热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Hologres如何支持亿级用户UV计算

背景介绍在用户行为分析和圈人场景中,经常需要从亿级甚至十亿级用户中快速筛选出符合特定标签的用户统计,很多企业会使用ApacheKylin(

背景介绍

在用户行为分析和圈人场景中,经常需要从亿级甚至十亿级用户中快速筛选出符合特定标签的用户统计,很多企业会使用Apache Kylin(下文简称Kylin)来支持这样的场景。但是Apache Kylin的核心是预计算,当遇上设计不合理的Cube,或者需求维度多的场景时,会遇到维度爆炸,Cube构建时间长,SQL函数不支持等问题。

本文将介绍阿里云Hologres如何基于RoaringBitmap进行UV等高复杂度计算的方案,实现亿级用户万级标签亚秒级分析,帮助用户从Kylin平滑迁移到Hologres,实现更实时、开发更灵活、功能更完善的多维分析能力。

Apache Kylin与Hologres的对比


对比项Apache KylinHologres差异点
定位MOLAP on HadoopReal-Time MPP Data Warehouse-
建模方式星型、雪花模型宽表模型、主题模型Hologres无需复杂建模理论和建模过程,数据导入即可查
核心原理空间换时间,减少运行时计算,预计算Cube,依赖Hadoop并行计算、列存、向量化,充分利用多节点,多核计算资源Hologres没有存储爆炸问题,无需预构建等待
运维方式依赖YARN,HBase,ZK等,外部依赖多计算存储分离,弹性伸缩,升级平滑,无外部依赖Hologres托管式运维,运维简单,无需Hadoop技能
使用场景固定报表,固定维度组合,固定指标服务,秒级响应敏捷自助报表、自助式分析、探索式分析、自助取数、在线数据服务,秒级响应Hologres分析更敏捷,无限制,支持完善的SQL Join,嵌套查询,窗口函数等
查询接口自定义JDBC,ODBC,有限SQL能力兼容PostgreSQL,标准JDBC、ODBC,支持标准SQLHologres兼容开源生态,SQL标准
开发效率依赖于建模人员的熟练度,掌握Kylin的复杂建模技巧针对“表”设计,概念简单Hologres上手容易,学习门槛低
数据时效性T+1,加工流程长,数据修正慢,模型修改成本非常高实时,写入即可查,数据可更新,模型可变更Hologres T+0,全实时

使用Hologres方案的收益:实时、灵活、简单

基于上述的比较,我们看到Kylin和Hologres拥有一些共同的场景:海量数据交互式分析、亚秒级响应、横向扩展能力。Kylin有很多优点,包括:最小化查询开销,以点查的性能完成多维分析,查询性能更稳定,利用Bitmap支持全局精确去重。同时也发现了一些Kylin的使用难点,包括:建模复杂(主要由IT团队负责建模),Cube膨胀(存储成本高),构建Cube时间长(业务不实时,构建任务资源消耗大),模型不可变(业务不敏捷),SQL支持能力弱(固定的Join连接条件、有限的SUM COUNT算子,BI兼容度低,SQL协议不标准),可扩展能力弱(UDF少)。

迁移到Hologres之后,可以获得的收益包括:建模简单(面向表,DWD&DWS),SQL能力强(兼容PostgreSQL11,支持Ad-Hoc Query),数据链路实时(写入即可见),运维简单(无Hadoop依赖)

如何从Kylin迁移到Hologres


  • 架构调整:从Hadoop/HBase架构,调整到MPP数据仓库Hologres,去Hadoop,ZK等依赖
  • 建模上:从面向指标的多维建模,调整为面向表的DWD、DWS分层建模,DWD为主,性能敏感时补充DWS甚至ADS,关注Query SLA,避免超大Query,通过基础聚合结果集作为轻量汇总的DWS,满足95%场景。
  • 学习上:学习Cube优化技巧到学习Hologres索引设计、查询优化、资源监控
  • 存储上:从单一的HBase存储,到冷热数据分层存储(Hologres+MaxCompute)
  • 场景上:通过Hologres提供更敏捷、更灵活的自助式分析,加速数据产品创新
  • 分工上:IT从关注建模的构建质量到关注平台的开发效率,更多服务业务价值

实现原理

在场景迁移之前,首先介绍以下精确去重和累加计算在Kylin和Hologres上不同的实现方式,以便于根据不同场景选用不同的方式去迁移原有业务。

如下图所示,Kylin根据维度和度量,进行多次预计算生成2^n个cuboid(n为维度数量)来构建cube。查询时,根据查询的维度,映射到相应的cuboid得到度量结果。Cube相比原始明细数据会有N倍的数据膨胀,且非常不灵活。

图1 Kylin精确去重和累加计算实现

对于Hologres来说,去做精确去重和累加计算则更为灵活:

  • 明细数据不多或者QPS要求不高的场景:直接利用SQL语句从明细表中对统计维度进行Group by,对指标用聚合函数计算度量结果。这种方法可以获得最大的灵活性,能充分利用Hologres强大的计算能力,可进行任意复杂的查询,实现数亿条记录的毫秒级分析。
  • 数据量大且高QPS场景:在Hologres中将明细表按照基础维度最细粒度做Group by,对指标进行预聚合运算生成一份DWS表。查询时对DWS表按照统计维度Group by,对指标的预聚合结果进行聚合计算即可。通过DWS层,极大的减少数据量,从而实现高QPS的查询要求。相比于DWD(明细层),DWS层的数据量正常只有DWD层的1/100甚至更少,这点类似于Kylin中的Base Cuboid结构。
  • 当然在Hologres上也可以采用类似Kylin构建Cube的方式:将明细表按照所需的各种维度组合做Group by,或者Cube、Rollup、Grouping Sets等原生表达式,对指标进行预聚合运算。但是同样也会存在数据膨胀问题,一般情况下按照上述方案即可。

 

图2 Hologres不同场景下精确去重和累加计算

综上所述,Kylin对可累加指标或精确去重指标的查询时,需构建Cube才能获取较高性能,这将引入额外的预计算和数据膨胀。而Hologres则更为灵活:

    • 对于DWD层数据量不大或者查询QPS要求不高的场景,无需预计算,可直接在DWD层上进行查询,即可获得很好的性能与最大的灵活性;
    • 对于DWD层数据量较大且有高QPS查询的场景,可根据基础维度进行一次预计算,并只生成一份DWS表,查询时按需选取维度查询即可。不会引入过多的预计算和数据膨胀问题。

本文下面将会介绍基于Hologres的DWS层构造和查询方案。

迁移可累加指标


  1. 明细数据导入Hologres,数据结构采用原始Hive中的事实表、维度表结构,可以通过“DataWorks数据集成批量同步”完成数据迁移。
  2. 数据源数据对应DWD层,包含明细数据和维度数据,如果数据是行为数据,根据日期字段建成分区表,如果是订单数据,不需要分区表。
  3. 对于QPS要求不高的场景:DWD表通过JDBC、ODBC暴露给BI应用。
  4. 对于QPS要求高的场景:继续加工DWD生成DWS表,在Hologres中,针对Cube的连接条件,生成基础聚合表BasicSummaryTable,如Kylin中 Fact A left join Fact B,指标:Sum(a), count(b),Hologres中执行 insert into BasicSummaryTable(col1, col2, ..., coln, sum_a, count_b) select col1, col2, ..., coln, sum(a), count(b) from A left join b group by col1, col2, ..., coln. 结果保存为BasicSummaryTable表。
  5. Hologres通过JDBC、ODBC暴露BasicSummaryTable表给BI应用。

DWS层的构造中,最重要的就是各种度量数据(指标)的聚合,需要保证各指标都是可累计的。对于SUM、COUNT、MIN、MAX、AVG(可通过保留两个字段:sum和count来解决),指标的可累计是非常简单的。

但对于COUNT DISTINCT类的指标(需要精确去重的指标,例如UV),也需要保证在DWS中,这个指标是可累计的,可通过Hologres原生支持的RoaringBitmap数据类型来进行计算和保存。

迁移不可累加指标(精确去重场景)

下面通过一个案例介绍Hologres中通过DWS来计算大时间范围的PV、UV的最佳实践。

PV (Page View): 字面含义页面访问量,比如一天内页面的累计访问量。其实也可引申为某段时间内某个指标的累加量。比如:双十一期间某件商品的点击量,活动促销期间某个地区的订单量等。

UV (Unique Visitor) : 访问网页的自然人,如果有20个人一天访问某个页面100次,这一天就是20个UV。可以引申为某段时间内某个指标精确去重后的量。

PV和UV是分析场景中比较重要的两个指标,下面将以T+1离线场景为案例,进行PV UV计算的介绍。

案例背景

每天有几亿条数据,客户总量千万级,每日UV在百万级,需要T+1根据十个左右维度(支持维度间任意组合)查询一天,一周,或者一个月甚至半年期间相应的用户数去重统计信息,得出用户数精确去重指标UV,以及访问量PV。

一般方式的UV PV计算

如果不采取任何预聚合运算,上述场景计算用户数精确去重指标UV和访问量PV,SQL如下:

select count(distinct uid) as uv, count(1) as pv from src_t group by dim1, dim2where ymd ='20210426';select count(distinct uid) as uv, count(1) as pv from src_t group by dim1, dim5, dim9where ymd like '202103%'; --查询区间为3月份--group by的字段是固定维度的中任意维度的组合
--where 过滤的区间范围 从一天到半年不等--因此有多少维度和时间的组合需求,就需要查询多少个这样count distinct sql,每条在查询时都需要大量计算

这种方式下,根据查询区间,每次查询要对几亿条到几十亿甚至几百亿条数据进行多个维度的Group by,然后再使用COUNT DISTINCT进行精确去重,会产生大量的数据交换计算,实时地得到结果需要一定量的计算资源,大大增加用户的成本。

基于Bitmap方式计算精确去重

Hologres内置Bitmap类型,通过计算一定维度组合条件下的Bitmap结果集,把维度的所有组合生成预计算的结果表,简单原理如下:

查询时,根据查询时的维度,查询对应的预计算结果表对桶进行聚合运算即可达到亚秒级查询。

--计算bitmapinsert into result_t select RB_BUILD_AGG(uid) as uv_bitmap, count(1) as pvfrom src_tgroup by dim, ymd; --存在跨天查询的需求,日期也必须加到group by维度中--查询时
select RB_CARDINALITY(RB_OR_AGG(uv_bitmap)), pv from result_t where ymd &#61; &#39;20210426&#39;select RB_CARDINALITY(RB_OR_AGG(uv_bitmap)), pv from result_twhere ymd >&#61; &#39;20210301&#39; and ymd <&#61; &#39;20210331&#39;

后面我们将会陆续推出Hologres基于RoaringBitmap的高效UV计算最佳实践&#xff0c;主要内容如下&#xff0c;敬请期待&#xff1a;

  • Hologres使用RoaringBitmap实现高效UV计算
  • Hologres使用Flink&#43;RoaringBitmap实现实时UV计算

原文链接

本文为阿里云原创内容&#xff0c;未经允许不得转载。


推荐阅读
  • 2018年人工智能大数据的爆发,学Java还是Python?
    本文介绍了2018年人工智能大数据的爆发以及学习Java和Python的相关知识。在人工智能和大数据时代,Java和Python这两门编程语言都很优秀且火爆。选择学习哪门语言要根据个人兴趣爱好来决定。Python是一门拥有简洁语法的高级编程语言,容易上手。其特色之一是强制使用空白符作为语句缩进,使得新手可以快速上手。目前,Python在人工智能领域有着广泛的应用。如果对Java、Python或大数据感兴趣,欢迎加入qq群458345782。 ... [详细]
  • 本文介绍了在MySQL8.0中如何查看性能并解析SQL执行顺序。首先介绍了查询性能工具的开启方法,然后详细解析了SQL执行顺序中的每个步骤,包括from、on、join、where、group by、having、select distinct、union、order by和limit。同时还介绍了虚拟表的概念和生成过程。通过本文的解析,读者可以更好地理解MySQL8.0中的性能查看和SQL执行顺序。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
  • 本文介绍了一个在线急等问题解决方法,即如何统计数据库中某个字段下的所有数据,并将结果显示在文本框里。作者提到了自己是一个菜鸟,希望能够得到帮助。作者使用的是ACCESS数据库,并且给出了一个例子,希望得到的结果是560。作者还提到自己已经尝试了使用"select sum(字段2) from 表名"的语句,得到的结果是650,但不知道如何得到560。希望能够得到解决方案。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • 一次上线事故,30岁+的程序员踩坑经验之谈
    本文主要介绍了一位30岁+的程序员在一次上线事故中踩坑的经验之谈。文章提到了在双十一活动期间,作为一个在线医疗项目,他们进行了优惠折扣活动的升级改造。然而,在上线前的最后一天,由于大量数据请求,导致部分接口出现问题。作者通过部署两台opentsdb来解决问题,但读数据的opentsdb仍然经常假死。作者只能查询最近24小时的数据。这次事故给他带来了很多教训和经验。 ... [详细]
  • ZooKeeper 学习
    前言相信大家对ZooKeeper应该不算陌生。但是你真的了解ZooKeeper是个什么东西吗?如果别人面试官让你给他讲讲ZooKeeper是个什么东西, ... [详细]
  • BPM是什么软件?1、BPM是BusinessProcessManagement的简称,译为业务流程管理,它是一种以规范化的构造端到端的卓越业务流程为中心以持续的提高组织业务绩效为 ... [详细]
author-avatar
漂漂雪飘飘业_348
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有