OLAP
OLAP介绍
Rollup
OLAP(在线分析处理)的上下文中,"Rollup"是一个重要的概念,它指的是在多维数据集中自动地聚合数据到更高的层次或维度的过程。这种操作通常用于快速计算和展示汇总数据,以便于用户进行数据分析和决策支持。
Rollup的工作原理
在多维数据模型中,数据通常按照不同的维度(如时间、地理位置、产品等)和层次结构进行组织。例如,一个销售数据模型可能包含日期(日、月、季度、年)、地区(国家、省/州、城市)和产品等维度。
当进行Rollup操作时,OLAP系统会自动将低层次的详细数据聚合到上一层次。以时间维度为例,Rollup操作可以将各个日销售数据汇总到月份,或者进一步汇总到季度和年份。这样,用户就可以快速查看每个月、季度或全年的销售总额,而不需要手动进行计算。
Rollup的应用场景
- 快速汇总:用户在进行数据分析时,经常需要查看不同层次的汇总数据,Rollup操作可以迅速提供这些信息。
- 数据钻取:在数据钻取(Drill-down)操作中,用户可能从高层次的汇总数据开始,然后逐步深入到更详细的数据。Rollup操作是钻取操作的逆过程,它帮助用户快速回到高层次的视图。
- 性能优化:通过预先计算和存储Rollup数据,可以提高数据查询的响应速度,尤其是在处理大规模数据集时。
- 数据可视化:在制作报表和仪表板时,Rollup操作可以帮助快速生成各种汇总图表和图形,提高数据可视化的效率。
Rollup的实现方式
Rollup操作可以通过多种方式实现,包括:
- 预定义的聚合:在数据模型设计阶段,可以预先定义好各种Rollup规则和聚合指标,以便在查询时自动应用。
- 动态聚合:某些OLAP系统支持在查询时动态生成Rollup操作,用户可以根据自己的需要选择聚合的层次和维度。
- 物化视图:为了提高性能,可以将Rollup结果存储在物化视图中,这样在查询时可以直接访问预聚合的数据,而不需要实时计算。
结论
Rollup是OLAP中一个非常关键的特性,它使得用户能够轻松地在不同层次的数据之间进行切换,快速获取汇总信息,从而提高数据分析的效率和效果。通过有效地利用Rollup操作,用户可以更好地理解数据,发现潜在的趋势和模式,支持更加明智的业务决策。
Slicing(切片)
Slicing操作指的是在多维数据集中沿着某个特定的维度进行选择,从而减少数据集的维度。简单来说,就是在数据立方体中选择一个维度,并固定该维度的一个或多个值,以此来"切"出一个新的子数据集。
例如,如果有一个包含时间、地区和产品三个维度的销售数据立方体,通过在时间维度上进行Slicing,选择"2023年",就会得到一个只包含2023年销售数据的子立方体,此时数据集的维度从三个减少到了两个,即地区和产品。
Slicing操作通常用于对数据进行筛选,以便集中分析特定条件下的数据。例如,分析特定时间段、特定地区或者特定产品类别的数据表现。
Dicing(切块)
Dicing操作则是在多维数据集中同时选择多个维度的特定值,从而将数据集划分成更小的子集。与Slicing不同,Dicing操作会减少数据集的维度,并且创建出多个较小的数据子集。
继续使用上述销售数据立方体的例子,通过在地区维度选择"北美"和产品维度选择"电子产品",进行Dicing操作,将会得到一个只包含2023年北美地区电子产品销售数据的子集。这样,原始的三维数据立方体被划分成了多个二维或一维的子数据集。
Dicing操作常用于深入分析特定细分市场或特定产品类别的表现,或者用于创建详细的报表和图表。
结合使用Slicing和Dicing
在实际的数据分析过程中,Slicing和Dicing操作经常被结合使用,以便用户可以从多个角度探索数据。例如,首先通过Slicing操作筛选出特定时间段的数据,然后再通过Dicing操作进一步细化到特定的地区和产品类别。
这种灵活的数据分析方式极大地提高了OLAP系统在支持复杂查询和深入分析方面的能力,使得用户能够根据自己的需求快速得到有价值的信息和见解。通过Slicing和Dicing,企业可以更好地理解市场趋势,优化产品策略,提高决策的准确性和效率。
doris介绍
MPP数据库
MPP数据库,即大规模并行处理(Massively Parallel Processing)数据库,是一种旨在通过并行处理多个数据节点来提高查询速度和数据处理能力的数据库系统。MPP数据库采用了分布式架构,可以在多个服务器、计算节点或实例上同时执行数据的存储、管理和计算任务。
MPP数据库的特点
- 并行处理:MPP数据库的核心特点在于其能够同时在多个节点上执行查询和数据操作,这样可以显著提高处理速度,尤其是在处理大型数据集时。
- 分布式架构:数据被分布在多个节点上,每个节点都可以独立地执行任务,这样可以提高数据的可用性和容错性。
- 高可伸缩性:MPP数据库可以通过增加更多的节点来提升系统的处理能力,从而应对数据量的增长和更复杂的查询需求。
- 数据局部性优化:MPP数据库通常具有数据局部性优化机制,即数据的计算尽可能地在存储该数据的节点上执行,这样可以减少数据在网络中的传输,提高效率。
- 负载均衡:通过在多个节点间均衡分配计算和I/O负载,MPP数据库可以避免单个节点的过载,从而提高整体系统的性能。
MPP数据库的应用场景
MPP数据库适用于需要高性能和高并发处理能力的场景,例如:
- 数据仓库和分析:MPP数据库可以加速复杂的数据分析和报告任务,支持即时查询和决策制定。
- 大数据处理:对于需要快速处理和分析大量数据的应用,如日志分析、实时数据处理等,MPP数据库能够提供所需的性能。
- 在线分析处理(OLAP):MPP数据库非常适合执行OLAP查询,支持用户进行多维数据分析和数据挖掘。
- 实时数据流处理:MPP数据库可以实时处理数据流,适用于金融交易、物联网等需要快速响应的应用场景。
MPP数据库的优势
- 提高查询速度:通过并行处理,MPP数据库能够显著减少查询响应时间。
- 增强系统稳定性:分布式架构提高了系统的容错能力,即使部分节点出现故障,系统仍可继续运行。
- 灵活的扩展性:可以根据业务需求灵活地增加或减少计算资源,保护投资。
- 优化资源利用:负载均衡和数据局部性优化可以提高资源的利用率,降低能耗。
MPP数据库通过其高效的并行处理能力和可伸缩的分布式架构,在大数据分析和实时处理领域发挥着重要作用,为企业提供了强大的数据处理解决方案。
DorisDB是由Apache Doris核心研发团队打造的新一代企业级MPP数据库。它继承了Apache Doris项目十多年研发成果,累积了线上数千台服务器稳定运行经验,并在此基础上,对传统MPP数据库进行了开创性的革新。
DorisDB重新定义了MPP分布式架构,集群可扩展至数百节点,支持PB级数据规模,是当前唯一可以在大数据规模下进行在线弹性扩展的企业级分析型数据库。
DorisDB还打造了全新的向量化执行引擎,单节点每秒可处理多达100亿行数据,查询速度比其他产品快10-100倍!
架构
极简架构
- FE前端节点-主要负责元数据的管理、查询调度,解析sql的执行计划给BE,
- BE-数据的存储和执行的引擎,这里存储和计算还是在一起的;
- FE:leader 、follower(参与选举),水平扩容
- 对外提供了mysql兼容的协议;
其他架构对比
- 跟传统架构的区别:
- 通过分布式拆分成不同的task,再在中心节点汇聚;
- druid、clickhouse都是类型;
- MR是任务的拆分、落盘;
- doris是MPP架构,任务之间分成task、全都在内存中执行和传输,所有任务都是流水线,没有磁盘IO,适用于低延迟亚秒级查询;
逻辑架构
Doris是一个海量分布式 KV 存储系统,其设计目标是支持中等规模高可用可伸缩的 KV 存储集群。Doris可以实现海量存储,线性伸缩、平滑扩容,自动容错、故障转移,高并发,且运维成本低。部署规模,建议部署4-100+台服务器。
Doris采用两层架构,Client 和 DataServer+Store。 有四个核心组件,Client、DataServer、Store、Administration。 应用程序通过Client SDK进行Doris的访问,每台服务器上部署一个Data Sever做服务器的管理,每台服务器上有自己的存储Store,整个集群的数据存储,每台机器独立部署。数据通过路由选择写入到不同的机器中。 Administration为管理中心,提供配置、管理和监控。 config指应用程序启动一个Data Server,在启动时要配置管理中心的ip地址,通关管理中心。管理中心会修改配置项感知到集群中加了新机器,对新机器管理,扩容等。待机器处于可用状态,将该机器的配置项通知给KV Client。从而KV Client进行新的路由选择。扩容、下线机器等的控制台界面通过Management管理。Monitor监控机器是否正常。
sql查询过程
- 解析成逻辑执行计划-A|B两个表的scan -> Join ->聚合(group by K1 sum(V1) ),聚合操作 -> 最后再sort by sum(V1)排序 ;
- MPP架构就是可以把执行计划转换成物理层面的,
- 假设有3个节点,会把执行计划类似fregment(有节点的组合)
- scanB扫描B表的数据,可能通过一个brokercust、dataSink和exchange这样的节点会把fregment串联起来,每个fregment中会有不同的计算节点;比如数据经过广播跟A表join,之后进行聚合操作;
- 一个MPP就是支持两层的聚合,每个节点做完聚合操作后最后汇总到一个节点再做一次;在doris中支持在中间做一次shuffle,shuffle完成之后在上层再做一次聚合,这样子就不会有大单点的计算瓶颈。再推给上层去做排序。
- 根据不同的机器每个fregment会拆成instent它执行的子单元,就可以充分发挥MPP的多基多合的能力,根据机器数量和设置的并行度,充分利用资源。
用户可使用MySQL客户端连接FE,执行SQL查询, 获得结果。
查询流程如下:
① MySQL客户端执行DQL SQL命令。 ② FE解析, 分析, 改写, 优化和规划, 生成分布式执行计划。 ③ 分布式执行计划由 若干个可在单台be上执行的plan fragment构成, FE执行exec_plan_fragment, 将plan fragment分发给BE,指定其中一台BE为coordinator。 ④ BE执行本地计算, 比如扫描数据。 ⑤ 其他BE调用transimit_data将中间结果发送给BE coordinator节点汇总为最终结果。 ⑥ FE调用fetch_data获取最终结果。 ⑦ FE将最终结果发送给MySQL client。
执行计划在BE上的实际执行过程比较复杂, 采用向量化执行方式,比如一个算子产生4096个结果,输出到下一个算子参与计算,而非batch方式或者one-tuple-at-a-time。
导入数据流程
用户创建表之后, 导入数据填充表.
- 支持导入数据源有: 本地文件, HDFS, Kafka和S3.
- 支持导入方式有: 批量导入, 流式导入, 实时导入.
- 支持的数据格式有: CSV, Parquet, ORC等.
- 导入发起方式有: 用RESTful接口, 执行SQL命令.
数据导入的流程如下:
① 用户选择一台BE作为协调者, 发起数据导入请求, 传入数据格式, 数据源和标识此次数据导入的label, label用于避免数据重复导入. 用户也可以向FE发起请求, FE会把请求重定向给BE. ② BE收到请求后, 向FE master节点上报, 执行loadTxnBegin, 创建全局事务。 因为导入过程中, 需要同时更新base表和物化索引的多个bucket, 为了保证数据导入的一致性, 用事务控制本次导入的原子性. ③ BE创建事务成功后, 执行streamLoadPut调用, 从FE获得本次数据导入的计划. 数据导入, 可以看成是将数据分发到所涉及的全部的tablet副本上, BE从FE获取的导入计划包含数据的schema信息和tablet副本信息. ④ BE从数据源拉取数据, 根据base表和物化索引表的schema信息, 构造内部数据格式. ⑤ BE根据分区分桶的规则和副本位置信息, 将发往同一个BE的数据, 批量打包, 发送给BE, BE收到数据后, 将数据写入到对应的tablet副本中. ⑥ 当BE coordinator节点完成此次数据导入, 向FE master节点执行loadTxnCommit, 提交全局事务, 发送本次数据导入的 执行情况, FE master确认所有涉及的tablet的多数副本都成功完成, 则发布本次数据导入使数据对外可见, 否则, 导入失败, 数据不可见, 后台负责清理掉不一致的数据.
表设计详解
数据存储基本原理
查找维度列的前缀的查找过程为: 先查找shortkey index, 获得逻辑块的起始行号, 查找维度列的行号索引, 获得目标列的数据块, 读取数据块, 然后解压解码, 从数据块中找到维度列前缀对应的数据项.
加速数据处理
- 列式存储
DorisDB的表和关系型数据相同, 由行和列构成. 每行数据对应用户一条记录, 每列数据有相同数据类型. 所有数据行的列数相同, 可以动态增删列. DorisDB中, 一张表的列可以分为维度列(也成为key列)和指标列(value列), 维度列用于分组和排序, 指标列可通过聚合函数SUM, COUNT, MIN, MAX, REPLACE, HLL_UNION, BITMAP_UNION等累加起来. 因此, DorisDB的表也可以认为是多维的key到多维指标的映射.
在DorisDB中, 表中数据按列存储, 物理上, 一列数据会经过分块编码压缩等操作, 然后持久化于非易失设备, 但在逻辑上, 一列数据可以看成由相同类型的元素构成的数组. 一行数据的所有列在各自的列数组中保持对齐, 即拥有相同的数组下标, 该下标称之为序号或者行号. 该序号是隐式, 不需要存储的, 表中的所有行按照维度列, 做多重排序, 排序后的位置就是该行的行号.
查询时, 如果指定了维度列的等值条件或者范围条件, 并且这些条件中维度列可构成表维度列的前缀, 则可以利用数据的有序性, 使用range-scan快速锁定目标行.
- 稀疏索引
当范围查找时, 如何快速地找到起始的目标行呢? 答案是shortkey index. 如下图所示: shortkey索引为稀疏索引,
表模型介绍
为了描述方便, 我们借鉴关系模式中的主键概念, 称DorisDB表的维度列的取值构成数据表的排序键, DorisDB的排序键对比传统的主键具有:
- 数据表所有维度列构成排序键, 所以后文中提及的排序列, key列本质上都是维度列.
- 排序键可重复, 不必满足唯一性约束.
- 数据表的每一列, 以排序键的顺序, 聚簇存储.
- 排序键使用稀疏索引.
对于摄入(ingest)的主键重复的多行数据, 填充于(populate)数据表中时, 按照三种处理方式划分:
- 明细模型: 表中存在主键重复的数据行, 和摄入数据行一一对应, 用户可以召回所摄入的全部历史数据.
- 聚合模型: 表中不存在主键重复的数据行, 摄入的主键重复的数据行合并为一行, 这些数据行的指标列通过聚合函数合并, 用户可以召回所摄入的全部历史数据的累积结果, 但无法召回全部历史数据.
- 更新模型: 聚合模型的特殊情形, 主键满足唯一性约束, 最近摄入的数据行, 替换掉其他主键重复的数据行. 相当于在聚合模型中, 为数据表的指标列指定的聚合函数为REPLACE, REPLACE函数返回一组数据中的最新数据.
需要注意:
- 建表语句, 排序列的定义必须出现在指标列定义之前.
- 排序列在建表语句中的出现次序为数据行的多重排序的次序.
- 排序键的稀疏索引(shortkey index)会选择排序键的若干前缀列.
明细模型
DorisDB建表的默认模型是明细模型。
一般用明细模型来处理的场景有如下特点:
- 需要保留原始的数据(例如原始日志,原始操作记录等)来进行分析;
- 查询方式灵活, 不局限于预先定义的分析方式, 传统的预聚合方式难以命中;
- 数据更新不频繁。导入数据的来源一般为日志数据或者是时序数据, 以追加写为主要特点, 数据产生后就不会发生太多变化。
聚合模型
在数据分析领域,有很多需要对数据进行统计和汇总操作的场景。比如:
- 分析网站或APP访问流量,统计用户的访问总时长、访问总次数;
- 广告厂商为广告主提供的广告点击总量、展示总量、消费统计等;
- 分析电商的全年的交易数据, 获得某指定季度或者月份的, 各人口分类(geographic)的爆款商品.
适合采用聚合模型来分析的场景具有如下特点:
- 业务方进行的查询为汇总类查询,比如sum、count、 max等类型的查询;
- 不需要召回原始的明细数据;
- 老数据不会被频繁更新,只会追加新数据。
更新模型
有些分析场景之下,数据会更新, DorisDB采用更新模型来满足这种需求。比如在电商场景中,定单的状态经常会发生变化,每天的订单更新量可突破上亿。在这种量级的更新场景下进行实时数据分析,如果在明细模型下通过delete+insert的方式,是无法满足频繁更新需求的; 因此, 用户需要使用更新模型来满足数据分析需求。
以下是一些适合更新模型的场景特点:
- 已经写入的数据有大量的更新需求;
- 需要进行实时数据分析。
基本访问架构
- 为了保证高可用。doris所有服务分成2个组,两组服务器对等。两个group是可以有不同数量的服务器。
- 写操作时,client的路由算法在两个group分别选2个服务器,分别(同时)写入,两个服务器全部返回后,再继续向下进行。读操作时,从两个服务器随机选一个读。这样,提高可用性,数据持久性,不会丢失。
智能CBO查询优化器
- dorisDB跟开源的apache doris有几个改造点:
- 在FE这边的改造:
- plan会根据cpu的成本预估,加入更多的统计信息(列的基数、直方图等等),能够更准确的预估表的执行计划。
- 两个表join时,使用brokercast join还是shuffle join还是其他join的一些方式,左右表过滤出来应该有多少行数等,哪个表作为左右表等;聚合函数用1层还是2层等等
极速向量化引擎
- BE
- 计算+存储,
- 计算层: 向量化引擎,即把内存结构按照列的方式进行组织;跟之前按行来处理不一样的地方是可以充分利用全新的cpu指令(单、多数据流),一条指令可以处理很多的数据。
高效的列式存储
- 列式存储:
- 支持排序,选择排序键,二分查找等方式。
- 支持二级索引:bitmap、 bloom filter等
- 会把复杂查询推到存储层。
现代化物化视图加速
- 不同场景下预处理:
- kylin的cube,doris中的物化视图;
- doris的物化视图跟clickhouse的区别:clickhouse中是直接去查询它的物化视图,doris中会有一个路由,查询的时候还是原表它会路由到最好的一张物化视图中。
实时构建DWS数据
- 实时数据分析报表的场景:
- flume-kafka-doris(进行实时数据的聚合)-BI工具的展示
- Join优化 — colocated Join
- doris多表关联有一个明显的优势:
- 原来的建模倾向于宽表,一旦维度的变更就会导致数据的重新刷新,灵活性降低。
- 现场关联,秒级查询返回;
- 除了高效的shuffle join外还会有一个colocate join 降低特别大的两个表的数据传输量。
- colocate join 在建表时就数据的分布方式,相同的数据可以哈希到一个桶中,所有的数据都可以在本地进行关联操作,最后再在上层做一次数据的聚合。
极简运维,弹性伸缩
doris能力
通过doris,可以根据场景不同,使用不同的能力,比如:
- 预计算能力和rollup表: 对于大多数效果数据报表,查询维度相对固定且可控,且满足毫秒级返回数据。Doris支持的聚合模型可以进行数据的预聚合,将多种维度数据汇总到建表时指定的维度。
此外,Doris支持建立Rollup表(即物化视图)也可以在不同维度上进行预聚合,这种自定义的方式相比Kylin的自动构建cube,有效避免了数据的膨胀,在满足查询时延的要求下,降低了磁盘占用。Doris还可以通过Rollup表对维度列的顺序进行调整,避免了Kylin中因过滤维度列在HBase RowKey后部而造成的查询性能低下。
- 现场计算能力:某些场景下列维度数量极多,且不固定,大部分查询要求按照所有维度列进行聚合,由于维度列较多,这种查询只能依赖于现场计算能力。对于这类场景,可以尽量将其数据均匀分布到多台BE上,利用Doris MPP架构的特性,并行计算,并通过控制查询时间范围(一个月),可以使TP99达到3s左右。
- 支持online schema change。 Doris支持Online Schema Change,相比原有系统Schema Change需要多个模块联动,耗费多个人力数天才能进行的操作,Doris只需一条SQL且在较短时间内就可以完成。对于日常需求来说,最常见的Schema Change 操作就是加列,Doris对于加列操作使用的是Linked Schema Change方式,该方式可以无需转换数据,直接完成,新导入的数据按照新的Schema进行导入,旧数据可以按照新加列的默认值进行查询,无需重刷历史数据。
- 近似、精确去重功能。Doris通过HLL列和BITMAP列支持了近似/精确去重的功能,解决了之前无法计算UV的问题。
- 日常业务中,无法避免进行数据修复操作。日常数据修复,相较于以前有了更多的方式可以选择。对于一些不是很敏感的数据,我们可以删除错误数据并进行重新导入;对于一些比较重要的线上数据,我们可以使用Spark on Doris计算正确数据和错误数据之间的差值,并导入增量进行修复。这样的好处是,不会暴露一个中间状态给广告主。我们还有一些业务会对一个或多个月的数据进行重刷。我们目前在测试使用Doris 0.12版本提供的Temp Partition功能,该功能可以先将正确数据导入到Temp Partition中,完成后可以将要删除的Partition和Temp Partition进行交换,交换操作是原子性的,对于上层用户无感知。
- 负载均衡、数据迁移。Doris添加新的BE节点后可以自动迁移Tablet到新节点上,达到数据负载均衡。通过添加FE节点,则可以支撑更高的查询峰值,满足大促高并发的要求。
doris缺点:
– Doris支持低延时的高并发查询和高吞吐的Ad-hoc查询,但是这两类查询会相互影响,迁移到Doris的初期日常线上的主要问题就是高吞吐的查询占用资源过多,导致大量低延时的查询超时。后来我们使用两个集群来对两类查询进行物理隔离,解决了该问题。
– Doris在0.11版本时FE的MySQL服务IO线程模型较为简单,使用一个Acceptor+ThreadPool来完成MySQL协议的通信过程,单个FE节点在并发较高(2000+qps左右)的时候会出现连接不上的问题,但此时CPU占用并不高。在0.12版本的时候,Doris支持了NIO,解决了这个问题,可以支撑更高的并发。也可以使用长连接解决这个问题,但需要注意Doris默认对连接数有限制,连接占满了就无法建立新的连接了。
参考:
Apache Doris在京东广告的应用实践:Apache Doris在京东广告的应用实践-腾讯云开发者社区-腾讯云
doris详细分析和实战:悄悄学习Doris,偷偷惊艳所有人 | Apache Doris四万字小总结-腾讯云开发者社区-腾讯云