作者|NearFar X Lab 团队 洪守伟、陈超、周志银、左益、武超
整顿|SelectDB 内容团队
导读: 无锡拈花云科技服务有限公司(以下简称拈花云科)是由中国创意文旅集成商拈花湾文旅和北京滴普科技有限公司独特孵化组建的。拈花云科以数字化思维为导向,致力于成为文旅目的地数智化服务商。2022 年底,拈花云科 NearFar X Lab 团队在数据需要的驱动下,开始调研并引进 Apache Doris 作为新架构下的数据仓库选型计划。本文次要介绍了拈花云科数据中台架构从 1.0 到 2.0 的演变过程,以及 Apache Doris 在交付型我的项目和 SaaS 产品中的利用实际,心愿本文分享的内容能对大家有所启发。
业务背景
拈花云科的服务对象次要是国内各个景区、景点,业务范围涵盖文旅行业的多个板块,如票务、交通、批发、住宿、餐饮、演绎、游乐、影院、KTV、租赁、服务、会务、康乐、康养、电商、客服、营销、分销、安防等。多业务线条下用户对于数据应用的时效性需要差别较大,须要咱们可能提供实时、准实时、T+1 的业务撑持能力 。同时依据大部分景区为国有化的特点,咱们也须要具备可能 提供私有化交付部署及 SaaS 化数据中台产品解决方案的双重服务撑持能力。
数据中台 1.0 – Lambda
晚期构建数据中台时,为了优先满足 B 端用户数据整合的需要,以稳固数据输入为出发点,因而咱们基于行业中比拟成熟的 Lambda 架构造成了数据中台 1.0。
在数据中台 1.0 架构中分为三层,别离为 Batch Layer,Speed Layer 和 Serving Layer。其中,Batch Layer 用于批量解决全副的数据,Speed Layer 用于解决增量的数据,在 Serving Layer 中综合 Batch Layer 生成的 Batch Views 和 Speed Layer 生成的 Realtime Views,提供给用户查问最终的后果。
Batch Layer: 在咱们晚期的施行类我的项目中,单纯以离线 T+1 进行数据反对的我的项目占了绝大多数。但施行类我的项目在实现 Lambda 架构的过程中也会面临很多问题。比方数据采集环节,因为我的项目自身起因业务零碎不能凋谢 DB 的 Binlog 供数据仓库采集,因而只能以 JDBC 的形式实现增量或全量的数据同步,而通过该形式同步的数据往往会因为零碎人工补充数据、工夫戳不标准等问题产生同步数据差别的状况产生,最终只能通过额定的数据比照逻辑进行校验,以保障其数据的一致性。
Speed Layer: 我的项目受老本束缚较大,大面积基于流的实时计算对于不论是从硬件老本、部署老本还是施行老本、保护老本等角度均难以撑持。基于该起因,在施行类我的项目中只有局部业务会进行基于流的实时统计计算,同时满足流计算条件的业务上游零碎也必须同时满足同步 Binlog 的应用需要。
Serving Layer: 大部分的预计算后果存储在 MySQL 中提供 Report 反对,局部实时场景通过 Merge Query 对外提供 Ad-Hoc 的查问反对。
随着工夫的推移,大量的我的项目交付使用增多,架构的问题也逐步开始浮现:
- 开发和保护老本高:该架构须要保护两套代码,即批处理和实时处理的代码,这无疑减少了开发和保护的老本。
- 数据处理复杂度高:Lambda 架构须要解决多个档次的数据,包含原始数据、批处理数据和实时处理数据,须要对不同的数据进行荡涤、转换和合并,数据处理的复杂度较高。
- 实时计算反对无限:业务方对于数据时效性要求越来越高,然而该架构能力无限,无奈反对更多、更高要求的的实时计算。
- 资源利用率低:离线资源较多,但咱们仅在凌晨后的调度工夫范畴内应用,资源利用率不高。
- 受老本制约:该架构对于咱们局部用户而言应用老本较高,难以起到降低成本提高效率的作用。
新架构的设计指标
基于以上架构问题,咱们心愿实现一套更加灵便的架构计划,同时心愿新的架构能够满足日益增高的数据时效性要求。在新计划实现之前,咱们必须先对以后的业务利用场景和我的项目类型进行剖析。
咱们业务利用场景分为以下四类,这四类场景的特点和需要别离是:
- 看板类:包含 Web/ 挪动端数据看板和大屏可视化,用于展现景区重要场合的数据,如业务播报(实时在园人数监控、车船调度治理等)、应急治理监控(客流密度监控、景区消防预警、景区能耗监控等)。其组成特点个别为业务汇总指标和监控指标报警,对数据时效性要求较高。
- 报表类:数据报表以图表模式展现,次要服务于各业务部门的一线业务人员。会更多关注垂直业务的数据笼罩水平,会有钻取需要(也可能通过不同报表来体现不同数据粒度)。个别以景区的业务部门为单位构建报表栏目和剖析主题,除财务结算类报表外,个别可承受 T+1 的报表时效。
- 剖析类:自助剖析基于较好的数据模型表(数据宽表)实现,对剖析人员有肯定的数据了解和操作需要,基于咱们提供的 BI 剖析平台,业务人员可基于此数据范畴通过拖拽的形式组合出本人的数据后果,灵便度较高。该场景对数据时效要求不高,更多关注业务数据积淀和与往期历史数据的比照剖析偏重架构的 OLAP 能力。
- 服务类:个别对接三方零碎,由数据中台提供数据计算结果。如画像标签等数据,通过数据接口管制权限提供对外数据服务与其它业务系统集成,须要新架构可能提供稳固的数据服务。
接着咱们对我的项目类型的特点和需要也进行了剖析,并确定新架构须要同时提供施行类我的项目和 SaaS 产品的数据中台撑持能力:
数据中台 2.0 – Apache Doris
联合以上需要,咱们打算对原有架构进行降级,并对新架构的 OLAP 引擎进行选型。在比照了 ClickHouse 等 OLAP 引擎后(社区有十分多的比照文章参考,这里不过多赘述),最终抉择了 Apache Doris 作为数据中台 2.0 的基座。同时,在数据的同步、集成及计算环节,咱们也构建了多套计划来适配以 Apache Doris 为外围的计算链路,以应答不同类型的施行类我的项目及 SaaS 产品需要。
数据中台 2.0 的外围思路是将 Apache Doris 作为外围的数据仓库,并将其作为实时数据同步核心、外围数据计算中心。数据集成环节将专一于数据同步,而计算交由 Apache Doris 实现或由 Doris 辅助计算引擎实现。同时,咱们将在提供多种数据同步至 Apache Doris 的计划以应答不同的我的项目需要。在这个架构下,咱们反对实现实时、准实时、T+1 的计算场景反对,以满足不同业务场景的需要。
新架构数据流转:
- 数据同步集成:架构 2.0 有多种数据同步形式,咱们次要借助 Doris Unique Key 模型实现数据的同步更新。
- 数仓分层计算:依据我的项目资源状况分 View/ 实体表单来构建前面的数据层级(DWD、DWS、ADS)。业务较轻或时效性很高时,通过 View 形式来实现逻辑层面的 DWD,通过这种形式为上游 Ad-hoc 提供宽表查问反对,Doris 的谓词下推及 View 优化的能力为应用视图查问带来了便当。而当业务较重时,通过实体表单 + 微批工作进行实现,依照调度依赖关系逐层实现计算,针对应用场景对表单进行优化。
- 数据计算时效:新架构下的数据时效受具体数据计算链路中的三个方面限度,别离是数据采集时效、批次计算时效、数据查问耗时。在不思考网络吞吐、音讯积压、资源抢占的状况下:
(施行类我的项目常常会遇到第三方不提供 Binlog 的状况,所以这里把通过批次采集数据也作为一个 case 列出来)
在 Doris 中为了达到更好的计算时效,基于 Doris 的数据计算流程相比在 Hive 中的计算流程能够进行肯定的简化,这样可防止过多的冗余计算设计,以此进步计算产出效率。
- 补充架构能力:
- Hadoop:依据不同的我的项目资源及数据状况来决定是否引入 Hadoop 补充大规模离线计算场景。以施行类我的项目为例,Doris 能够涵盖大部分外围业务数据计算场景。
- MySQL:基于预计算的后果数据能够推送到上游 MySQL 中以供 Report 查问,从而扩散 Doris 计算查问的资源耗费,这样能够将资源充沛留给外围且时效性要求高的利用或高频批次工作。如果计算资源短缺,Doris 也能够间接作为应用层的减速查问 DB,而无须引入其它 DB。
新架构收益
通过引入 Apache Doris,咱们胜利构建了高时效、低成本的数据中台 2.0,并胜利满足了交付型我的项目和 SaaS 产品两种需要场景下的应用需要。新架构的收益如下:
- 数据时效性晋升:架构 1.0 中大部分业务为 T+1 的反对形式,而在新架构下大部分业务都可实现实时或小时级计算反对。
- 资源利用率进步:在架构 1.0 中,离线资源在白天大部分工夫处于闲置状态。而在新架构下,数据同步、计算(增量 / 全量)和查问均在同一集群下实现,从而进步了资源利用率。相较于部署一套 CDH,等同资源老本下,部署一套 Doris 能够带来更多的收益。
- 运维治理老本升高:在原有架构下,实时统计需要须要保护十分长的计算链路。而在新架构下,所有计算仅需在一个数据库中实现,更加简略、高效且易于保护。
- 易于业务扩大:Doris 的节点扩大操作十分便捷,这对于业务的增量反对十分敌对。
新架构的落地实际
咱们在 2022 年底首次在测试环境中部署了 Apache Doris 1.1.5 版本,并进行了一些业务数据的导入测试和新架构的可行性验证。在测试后,咱们决定在生产环境中落地实际 Apache Doris。第一次生产环境部署时,咱们应用了过后最新的 1.2.2 版本。目前,新我的项目已降级到 1.2.4 版本并应用。Apache Doris 作为新架构下的外围零碎,在整个架构中施展着重要的作用。上面咱们将从模型抉择、资源布局、表构造同步、计算场景实现、运维保障等几个角度分享咱们基于 Doris 的我的项目落地教训,心愿为正在筹备落地 Doris 计划的读者带来一些参考。
模型抉择
数据模型咱们次要利用了 Doris 提供的 Unique 模型和 Aggregate 模型。
Unique 模型
对于 ODS 层的表单来说,咱们须要 Doris Table 与源零碎数据放弃实时同步。为了保证数据同步的一致性,咱们采纳了 Unique 模型,该模型会依据主键来对数据进行合并。在 1.2.0 版本之前,Unique 模型是 Aggregate 模型的一种特例,应用了 Merge On Read 的实现形式,这种实现形式下 count(*)
的查问效率较低。而在 1.2.0 版本推出之后,采纳了新的 Merge On Write 的数据更新形式,在 Unique Key 写入过程中,Doris 会对新写入的数据和存量数据进行 Merge 操作,从而大幅优化查问性能。在 Merge 过程中,Doris 会查找 Unique Key 索引,并应用 Page Cache 来优化索引查找效率。因而在应用 1.2 版本中,倡议关上 Doris BE 的 Page Cache(在 be.conf
文件中减少配置项 disable_storage_page_cache = false
)。另外在很多状况下,Unique 模型反对多种谓词的下推,这样表单也能够反对从源表间接建设视图的查问形式。
Aggregate 模型
在某些场景下(如维度列和指标列固定的报表查问),用户只关怀最终按维度聚合后的后果,而不须要明细数据的信息。针对这种状况,咱们倡议应用 Aggregate 模型来创立表,该模型以维度列作为 Aggregate Key 建表。在导入数据时,Key 列雷同的行汇聚合成一行(目前 Doris 反对 SUM、REPLACE、MIN、MAX 四种聚合形式)。
Doris 会在三个阶段对数据进行聚合:
- 数据导入的 ETL 阶段,在每一批次导入的数据外部进行聚合;
- 底层 BE 进行数据 Compaction 的阶段;
- 数据查问阶段。
聚合实现之后,Doris 最终只会存储聚合后的数据,这种明细表单数据的预聚合解决大大减少了须要存储和治理的数据量。当新的明细数据导入时,它们会和表单中存储的聚合后的数据再进行聚合,以提供实时更新的聚合后果供用户查问。
资源管理
在生产环境中,咱们应用一套 Doris 数据仓库撑持了多个上游数据利用零碎的应用。这些利用系统对数据拜访的资源耗费能力不同,对应的业务重要等级也不雷同。为了可能更好治理利用资源的应用,防止资源抵触,咱们须要对利用账号进行划分和资源布局,以保障多用户在同一 Doris 集群内进行数据操作时缩小互相烦扰。而 Doris 的多租户和资源隔离性能,能够帮忙咱们更正当地调配集群资源。Doris 对于资源隔离管制有两种形式,一是集群内节点级别的资源组划分,二是针对单个查问的资源限度。这里次要介绍下集群内节点级别的资源组划分过程。
第一步:须要梳理布局各场景的用处、重要等级及资源需要等,举例说明:
第二步:对节点资源进行划分、给节点打上 tag 标签:
alter system modify backend "10.10.101.1:9050" set ("tag.location" = "group_a");
alter system modify backend "10.10.101.2:9050" set ("tag.location" = "group_a");
alter system modify backend "10.10.101.3:9050" set ("tag.location" = "group_b");
alter system modify backend "10.10.101.4:9050" set ("tag.location" = "group_b");
alter system modify backend "10.10.101.5:9050" set ("tag.location" = "group_c");
alter system modify backend "10.10.101.6:9050" set ("tag.location" = "group_c");
第三步:给利用下的表单指定资源组散布,将用户数据的不同正本散布在不同资源组内
create table flume_etl<table>
(k1 int, k2 int)
distributed by hash(k1) buckets 1
properties("replication_allocation"="tag.location.group_a:2, tag.location.group_b:1")
create table cdc_etl<table>
```
"replication_allocation"="tag.location.group_b:2, tag.location.group_c:1"
create table etl<table>
```
"replication_allocation"="tag.location.group_a:1, tag.location.group_c:2"
create table mkui_readonly<table>
```
"replication_allocation"="tag.location.group_a:2, tag.location.group_c:1"
create table SaaS_readonly<table>
```
"replication_allocation"="tag.location.group_a:1, tag.location.group_b:1, tag.location.group_c:1"
create table dev<table>
```
"replication_allocation"="tag.location.group_a:1, tag.location.group_b:1, tag.location.group_c:1"
第四步:设置用户的资源应用权限,来限度某一用户的查问只能应用其指定资源组中的节点来执行。
set property for 'flume_etl' 'resource_tags.location' = 'group_a';
set property for 'cdc_etl' 'resource_tags.location' = 'group_b';
set property for 'etl' 'resource_tags.location' = 'group_c';
set property for 'mkui_readonly' 'resource_tags.location' = 'group_a';
set property for 'SaaS_readonly' 'resource_tags.location' = 'group_a, group_b, group_c';
set property for 'dev' 'resource_tags.location' = 'group_b';
值得一提的是,与社区交换中咱们得悉在行将公布的 Apache Doris 2.0 版本中还基于 Pipeline 执行引擎减少了 Workload Group 能力。该能力通过对 Workload 进行分组治理,以保障内存和 CPU 资源的精细化管控。通过将 Query 与 Workload Group 相关联,能够限度单个 Query 在 BE 节点上的 CPU 和内存资源的百分比,并能够配置开启资源组的内存软限度。当集群资源缓和时,将主动 Kill 组内占用内存最大的若干个查问工作以减缓集群压力。当集群资源闲暇时,一旦 Workload Group 应用资源超过预设值时,多个 Workload 将共享集群可用闲暇资源并主动冲破阙值,持续应用零碎内存以保障查问工作的稳固执行。更具体的 Workload Group 介绍能够参考:https://doris.apache.org/zh-CN/docs/dev/admin-manual/workload…
create workload group if not exists etl_group
properties (
"cpu_share"="10",
"memory_limit"="30%",
"max_concurrency" = "10",
"max_queue_size" = "20",
"queue_timeout" = "3000"
);
批量建表
初始化实现 Doris 的建表映射往往须要构建许多表单,而独自建表低效且易出错。为此,咱们依据官网文档的倡议应用 Cloudcanal 进行表构造同步来批量建表,大大提高了数据初始化的效率。
建表时须要留神的是:以 MySQL 为例,MySQL 数据源映射到 Doris 表构造的过程中须要进行肯定的表结构调整。在 MySQL 中varchar(n)
类型的字段长度是以字符个数来计算的,而 Doris 是以字节个数计算的。因而,在建表时须要将 Doris varchar 类型字段的长度调整到 MySQL 对应字段长度的 3 倍。在应用 Unique 模型时须要留神建表时 UNIQUE KEY 列要放在 Value 列后面申明,且保障有序排列和设置多正本配置。
除了以上形式,日前新公布的 Doris-Flink-Connector 1.4.0 版本中已集成了 Flink CDC、实现了从 MySQL 等关系型数据库到 Apache Doris 的一键整库同步性能,用户无需提前在 Doris 中建表、能够间接应用 Connector 疾速将多个上游业务库的表构造及数据接入到 Doris 中。举荐大家尝试应用。相干链接:https://mp.weixin.qq.com/s/Ur4VpJtjByVL0qQNy_iQBw
计算实现
依据咱们对架构 2.0 的布局,咱们将所有计算转移在 Doris 中实现。然而在撑持实时和准实时的场景下,具体的技术实现会有所不同,次要区别如下:
实时计算
如上文提到咱们会以实时数据采集 + Doris 视图模型的形式提供实时计算结果,而为了在计算过程中达到更高的数据时效反对,应该尽量减少不必要的数据冗余设计。如传统数据仓库会依照 ODS->DWD->DWS->ADS 等分层逐层计算落表。而在实时计算场景下能够适当进行裁剪,裁剪的根据为整体查问时效的满足状况。此外,在理论的业务场景中也会有多层视图嵌套调用的状况。
准实时计算
在业务能承受的准实时场景下(10 分钟、30 分钟、小时级),能够通过实体表单 + 微批工作实现计算,计算过程依照调度层级依赖关系逐层实现。
通过 Java UDF 生成增量 / 全量数据
在理论业务中,存在增量 / 全量的日、月、年等不同工夫频度数据生成需要。咱们通过 Doris 的 Java UDF 性能(1.2 版本后反对) + 调度零碎传参的形式实现了一套脚本动静的生成增量 / 全量及日、月、年等不同的指标汇总。
实现思路:
period_type
:计算频度 D/W/M/Y 代表计算日、周、月、年-
run_type
:INC(增量)/ DF(全量)是通过传递begin_date
,end_datel
来筛选business_date
数据进行汇总。- 增量满足:
begin_date(对应计算频度开始日期) <= business_date <= end_date(对应计算频度完结日期)
- 全量满足:
begin_date(写死一个业务最小日期) <= business_date <= end_date(对应计算频度完结日期)
- 增量满足:
基于以上思路实现 etlbegindate
函数来返回不同计算频度下增量、全量的 begin_date
etlbegindate(run_type,period_type,end_date)
为了在统计不同频度时可能生成对应频度的辨认id
字段,咱们还须要实现一个periodid
函数
periodid(period_type,business_date)
该函数的次要性能为:
- period_type = ‘D’ 返回 business_date 所在日,‘YYYYMMDD’ 格局的 period_id 字段
- period_type = ‘W’ 返回 business_date 所在周的起始日期,‘YYYYMMDDYYYYMMDD’ 格局的 period_id 字段
- period_type = ‘M’ 返回 business_date 所在月,’YYYYMM’ 格局的 period_id 字段
- period_type = ‘Y’ 返回 business_date 所在年,’YYYY’ 格局的 period_id 字段
联合 etlbegindate
与 periodid
两个函数,假设以后工夫为 2023 年 6 月 16 日则相应的实现如下:
SQL 脚本应用函数示例
-- 示例 Demo
select ${period_type} as period_type -- 统计频度 D/W/M/Y
,period_id(${period_type},business_date) as period_id -- 工夫频度 ID
,count(goods_id) as goods_cnt -- 商品数
where business_date >= etlbegindate(${run_type},${period_type},${end_date})
and business_date <= ${end_date}
group by period_id
运行调度前参数配置:
<p align=center><img src=”https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6866d83875f24076af77a8e962ac2c29~tplv-k3u1fbpfcp-zoom-1.image” alt=”” width=”100%”/></p>
工作运行后果示例:W/M/Y 是的实现形式统一,只是数据返回的 period_id
格局会依照上文形容的格局输入。
基于以上办法,咱们高效地为公司 SaaS 产品构建了相应的数据指标库利用。
基于 Doris 的大表优化
咱们的业务波及基于用户页面拜访和景区设施日志信息的统计分析业务,这类指标计算须要解决大量日志数据。接下来,咱们将介绍如何利用 Doris 提供的性能对数据进行优化解决。
数据分辨别桶:
Doris 反对两级分区,第一级叫做 Partition,反对 Range Partitioning 和 List Partitioning 两种分区策略。第二级分区叫做 Bucket,反对 Hash Partitioning 分区策略。
对于用户浏览行为的埋点事件表,咱们依照工夫做为分区(Range Partitioning):
在理论利用中,业务的历史冷数据能够按年进行分区,而近期的热数据能够依据数据量增幅依照日、周、月等进行分区。另外,Doris 自 1.2.0 版本后反对批量创立 RANGE 分区,语法简洁灵便。
从 Doris 1.2.2 版本开始,Doris 反对了主动分桶性能,免去了在分桶下面的投入,一个分桶在物理层面为一个 Tablet,官网文档倡议 Tablet 大小在 1GB – 10GB 之内,Y 因而对于小数据量分桶数不应太多。主动分桶的开启只须要建表时新增一个属性配置:
DISTRIBUTED BY HASH(openid) BUCKETS AUTO PROPERTIES ("estimate_partition_size" = "1G")
Like Query 和 SEQUENCE_COUNT 介绍
Like Query
在应用埋点日志数据进行漏斗剖析时,须要针对某些特定 URL 数据进行汇总剖析。这些 URL 中带有参数信息,以 String 或者 Varchar 类型存储为例,在计算过程中须要对含有特定参数的数据进行筛选。
依据该 Issue:https://github.com/apache/doris/pull/10355,咱们理解到 Doris 对于 like/not like 有肯定的优化解决,操作符能够下推到存储引擎进行数据过滤。因而在这个场景下,咱们尝试应用 like 操作符对数据进行筛选解决。
另外在 Apache Doris 2.0 版本中将减少 Ngram BloomFilter 索引,应用该索引能够用来晋升 Like Query 的性能,未咱们也将进行降级应用。Doris 提供了 gram_size
和 bf_size
两个参数进行配置,示例如下:
CREATE TABLE `test_ngrambf` (`id` int(11),
`str` varchar(32),
INDEX idx_str (`str`) USING NGRAM_BF PROPERTIES("gram_size"="3", "bf_size"="256")
) ENGINE=OLAP
DUPLICATE KEY(`id`)
DISTRIBUTED BY HASH(`id`) BUCKETS 10
PROPERTIES ("replication_num" = "1");
mysql> INSERT INTO test_ngrambf VALUES (1, 'hello world'), (2, 'ngram test');
Query OK, 2 rows affected (0.18 sec)
{'label':'insert_fbc5d3eca7204d52_965ce9de51508dec', 'status':'VISIBLE', 'txnId':'11008'}
mysql> SELECT * FROM test_ngrambf WHERE str LIKE '%hel%';
+------+-------------+
| id | str |
+------+-------------+
| 1 | hello world |
+------+-------------+
1 row in set (0.03 sec)
mysql> SELECT * FROM test_ngrambf WHERE str LIKE '%abc%';
Empty set (0.02 sec)
mysql> SELECT * FROM test_ngrambf WHERE str LIKE '%llm%';
Empty set (0.04 sec)
上面对 Ngram BloomFilter 索引的原理作简要介绍:
如果将 “hello world"
存入 Bloom Filter 中,将 gram_size
配置为 3,这时会将"hello world"
分为 ["hel","ell","llo",...]
别离进行存储,每个 gram 通过 N 个哈希函数 h1, h2, …, hn 映射到 Bloom Filter 中,对应的索引值设为 1。当解决 where column_name like'hel'
这样的查问语句时,'hel'
会通过雷同哈希函数的映射和 Bloom Filter 进行比拟,如果映射出的索引和 Bloom Filter 的索引的值都是 1,那么判断 'hel'
在 Bloom Filter 中(True Positive),但也存在肯定概率会将原本不在 Bloom Filter 中的元素判断为在汇合中(False Positive),比方上图中的'llm'
,但将其判断为不在 Bloom Filter 中的元素(True Negative)肯定不会存在,比方图中的过滤条件like'abc'
。
在理论应用 Ngram BloomFilter 索引时有一些注意事项:
- 应用 Ngram BloomFilter 索引时须要依据理论查问状况合理配置
gram_size
的大小。小的gram_size
反对搜寻查问更多的 String,然而同时也带来更多数量的 ngram 和须要利用更多的哈希函数,这将会增大 False Positive 的概率。 - 因为存在 False Positive 的可能性,Ngram BloomFilter 索引不能被用来解决
column_name != 'hello'
或者column_name not like '%hello%'
这样应用负运算符的过滤条件。
SEQUENCE_COUNT
针对用户留存或漏斗剖析等指标的计算,能够应用 Doris 提供的 SEQUENCE_COUNT(pattern, timestamp, cond1, cond2, ...)
函数。这里 pattern
参数用来指定用户一系列浏览行为的事件链,比方:
-- 计算用户浏览商品、退出购物车以及领取这一连串事件的数量
SELECT SEQUENCE_COUNT('(?1)(?2)(?3)', timestamp, event = 'view_product', event = 'add_cart', event = 'pay') FROM user_event;
通过 SEQUENCE_COUNT
能够十分不便地计算咱们指定的事件链的数量。
Doris Borker 的协同计算
业务中存在局部大数据量的历史数据统计需要,针对这部分需要咱们进行了协同计算解决
- FlinkCDC 读取 Binglog 实时同步数据到 Doris 明细表
- Doris 明细表会存储近 30 日热数据(须要进行 TTL 治理)
- Doris 每日通过 Borker Export 同步一份日增量数据至 HDFS,并加载至 Hive 中
- Hive 中贮存所有明细数据,数据初始化生成计算结果在 Hive 中实现 Borker Load 至 Doris
- Doris 在生成后果数据时仅生成以后日期数据,每天的增量生成积淀为历史后果
- 当业务有须要时通过 Borker Export 加载 Hive 全量计算后果刷新 Doris 后果表
- 当业务有基于此明细数据的新开发需要时,可在 Hive 中计算实现初始化后果至 Doris
数据导出(Export): Export 是 Doris 提供的一种将数据导出的性能。该性能能够将用户指定的表或分区的数据以文本的格局,通过 Broker 过程导出到远端存储上,如 HDFS 或对象存储(反对 S3 协定)等。用户提交一个 Export 作业后,Doris 会统计这个作业波及的所有 Tablet,而后对这些 Tablet 进行分组,每组生成一个非凡的查问打算。这些查问打算会读取所蕴含的 Tablet 上的数据,而后通过 Broker 将数据写到远端存储指定的门路中。
数据导入(Broker load): Broker Load 是 Doris 的一种异步数据导入形式,能够导入 Hive、HDFS 等数据文件。Doris 在执行 Broker Load 时占用的集群资源比拟大,个别适宜数据量在几十到几百 GB 级别下应用。同时须要留神的是单个导入 BE 最大的处理量为 3G,如果超过 3G 的导入需要就须要通过调整 B roker Load 的导入参数来实现大文件的导入。
联邦查问在数据分析场景下的尝试
因为上游数据源较多,咱们仅对罕用的数据表单进行了数据仓库采集建模,以便更好地进行治理和应用。对于不罕用到的数据表单,咱们没有进行入仓,但业务方有时会长期提出未入仓数据的统计需要,针对这种状况,咱们能够通过 Doris 的 Multi-Catalog 进行疾速响应、实现数据分析,待需要常态化后再转换成采集建模的解决形式。
Multi-Catalog 是 Doris 1.2.0 版本中推出的重要性能。该性能反对将多种异构数据源疾速的接入 Doris,包含 Hive、Iceberg、Hudi、MySQL、Elasticsearch 和 Greenplum 等。应用 Catalog 性能,能够在 Doris 中对立的实现异构数据源之间的关联计算。Doris 1.2.0 当前的版本官网举荐通过 Resource 来创立 Catalog,这样在多个应用场景下能够复用雷同的 Resource。上面是 Doris 本地表与通过 Multi-Catalog 映射的近程表单组合实现关联计算的场景示例。
Multi-Catalog 带来的收益:
- 更高的灵活性:通过 Multi-Catalog,用户能够灵便地治理不同数据源的数据,并在不同的数据源之间进行数据交换和共享。这能够进步数据利用的可扩展性和灵活性,使其更适应不同的业务需要。
- 高效的多源治理:因为 Multi-Catalog 能够治理多个数据源,用户能够应用多个 Catalog 来查问和解决数据,解决了用户跨库拜访不便的问题,从而进步数据利用的效率。
社区中曾经有十分多的搭档基于 Multi-Catalog 性能落地了利用场景。另外如果要深度应用该性能,倡议建设专门用于联邦计算的 BE 节点角色,当查问应用 Multi-Catalog 性能时,查问会优先调度到计算节点。
运维保障
守护过程
为了保障 Doris 过程的继续运行,咱们依照 Doris 官网的倡议在生产环境中将所有实例都的守护过程启动,以保障过程退出后主动拉起。咱们还装置部署了 Supervisor 来进行过程治理,Supervisor 是用 Python 开发的一套通用的过程管理程序,能够将一个一般的命令行过程变为后盾 Daemon 并监控过程状态,当过程异样退出时主动重启。应用守护过程后,Doris 的过程变成了 Supervisor 的子过程,Supervisor 以子过程的 PID 来治理子过程,并能够在异样退出时收到相应的信号量。
配置 Supervisor 时的注意事项:
- 通过
supervisorctl status
查问进去的过程 id 不是 Fe、Be、Broker 的过程 ID,而是启动它们的 Shell 过程 ID。在start_xxx.sh
中会启动真正的 Doris 过程,因而才有了过程树的说法。 stopasgroup=true ;
是否进行子过程、killasgroup=true ;
是否杀死子过程,须要保障这两个参数为true
,否则通过supervisorctl
管制 Doris 的后盾过程是有效的,这也是通过 Supervisor 守护 Doris 过程的要害。
配置完 Supervisor 后则通过守护过程的形式来治理 FE、BE、Borker……
因为 Superviosr 自带的 Web UI 不反对跨机器治理,当多节点时治理十分不便,这里能够应用 Cesi 来对 Supervisor 进行合并治理:
Grafana 监控报警
对于 Doris 的运行监控,咱们依照官网相干内容部署了 Prometheus 和 Grafana,并进行监控项的采集。同时对于一些要害指标进行了预报警,利用企微 Bot 实现信息推送。
以下为测试环境示例图:
集群 CPU 闲暇状况:
集群内存应用状况: 之前发现集群存在内存泄露
BDBJE 写入状况: 超过秒级可能会呈现元数据写入提早的问题
开始调度运行的 Tablet 数量: 失常状况该值根本为 0 或个位数,呈现稳定的 Tablet 阐明可能在进行 Recovery 或 Balance。
<img src=”https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/88773f37feba4bed99e048bfbc1458e5~tplv-k3u1fbpfcp-zoom-1.image” alt=”” width=”100%” />
除此之外,咱们还应用 QPC/99th Latency……等指标来查看监测集群服务能力,倡议能够在 Doris 监控的根底上额定退出集群机器的监控,因为咱们的机器部署在 VM 中,已经呈现过硬盘问题、内存问题、网络稳定、专线异样等状况,多一层报警机制就多一份稳定性保障。
总结收益
通过新架构的胜利搭建,实现了以 Apache Doris 为外围数据仓库 + OLAP 引擎的应用形式(All in One),无效缩减了数据处理流程,大大降低了投递型我的项目的施行老本。在旧架构下,须要部署、适配、保护十分多的组件,无论是施行还是运维都会比拟沉重。相比之下,新架构下的 Doris 易于部署、扩大和保护,组合计划也灵便多变。在咱们近半年的应用工夫内,Doris 运行十分稳固,为我的项目交付提供了强有力的计算服务保障能力。
此外,基于 Apache Doris 丰盛的性能、欠缺的文档,咱们能够针对离线和在线场景进行高效且粗疏的数据开发和优化。通过引入 Doris 咱们在数据服务时效性方面也有了大幅提高,以后咱们曾经胜利地落地了多个数据我的项目,并孵化出了一个基于 Doris 的 SaaS 产品。同时,Doris 领有一个成熟沉闷的社区,SelectDB 技术团队更是为社区提供了一支全职的技术团队,推动产品迭代、解决用户问题,也正是这强有力的技术支持,帮忙咱们更快上线生产,疾速解决了咱们在生产使用中遇到的问题。
将来布局
将来,咱们将亲密关注 Apache Doris 社区的倒退,并打算构建基于 K8S 的 Doris 服务形式。在我的项目交付场景下,经常须要进行整套环境的部署。目前,咱们曾经在 K8S 上集成了 2.0 版本架构下除 Doris 以外的其余数据服务组件。随着 Doris 社区 2.0 版本全面反对 K8S 的打算,咱们也会将计划集成到咱们的新体系中,以不便前期的我的项目投递。除此之外,咱们还将联合 Doris 的性能个性提炼基于 Doris 的数仓方法论,优化开发过程。Doris 是一个包容性十分好的存储计算引擎,而想要将原有的数据仓库开发内容全副适配在 Doris 上还须要一直的学习、优化与调整,以充分发挥 Doris 的劣势,同时咱们也将在此基础上积淀一套与之相匹配的开发标准。
最初,我十分举荐大家应用 Apache Doris 作为数据我的项目的解决方案。它具备功能强大、包容性强、社区沉闷、迭代更新快等劣势,这些劣势将助推你的我的项目达成指标。在此,我要感激 Apache Doris 社区和 SelectDB 的同学们给予咱们的反对和帮忙,也祝福 Apache Doris 社区越来越壮大。