目录
一、背景
1.1 企业背景
1.2 面临的问题
1.3 需求
1.4 首期目标
二、早期架构
三、新的架构及方案
3.1 业务架构
3.2 数据模型
3.2.1 纵向分域
3.2.2 横向分层
3.2.3 增量策略
3.2.4 全量策略
四、实践经验
原文大佬的这篇Doris数仓的实战文章写的挺全面(跟本人目前所负责的数仓项目,有些分析场景 很相似),这里直接摘抄下来用作学习和知识沉淀。
一、背景
1.1 企业背景
美联物业目前数仓主要服务和面向内部客户为主,如后勤、行政、开发人员、更多的是房产经纪,这部分在全国约上万人,无需面向C端用户,因此计算方面和面向C端用户的企业(类似贝壳)相比并不算大。
1.2 面临的问题
(1)没有统一的数据管理体系和数据治理,数据质量较差,如多部门,多系统,多字段,命名随意,表结构混乱等。
(2)没有统一的分析处理平台,关系数据库的分库分表操作无法做到上亿数据的秒级分析查询。
(3)没有充分利用数据驱动业务,数据需求流程冗长+烟囱式开发。
(4)没有数据资产管理体系,无法实现数据的降本提效。
(5)部门之间严重依赖文本文档的处理工作,效率低下。
1.3 需求
-
业务部门的数据报表需求
-
app的数据接口需求
-
快速的自助分析场景等
1.4 首期目标
- 建立初期的数据管理体系,搭建美联数据仓库
- 建设业务报表平台和开发流程体系
- 实现报表、分析需求能够快速响应的交付
二、早期架构
和大部分公司的数仓不同的是,我们摒弃了之前使用的Hadoop、Hive、Spark体系建立的传统数仓,改用 Doris作为数仓核心底座进行开发,摒弃Hadoop生态圈主要有已下几个原因:
(1)传统数据架构组件繁多,维护复杂,运维难度非常高。
(2)数据处理链路过长,导致查询延迟变高
(3)数据时效性低:只可满足T+1的数据需求,导致数据分析效率低下
(4)传统公司的计算量和数据量不大,搭建Hadoop生态组件显得杀鸡用牛刀。
在此背景下,需要构建⼀个“极速、易用、实时”的数据架构来解决这些痛点。
改用Apache Doris主要有几个方面原因:
(1)多表Join能力强悍,业务报表分析需求可实现快速响应(极速)
因为无需面对C端群体,不需要要求系统有很高的并发特性和PB级存储,业务需求要快速响应,数据实时交付和分钟级交付的场景繁多。
(2)整体架构简洁易用,极简运维,弹性伸缩,功能完备(易用)
大部分传统公司对数据人员的要求除了数据开发之外,也要兼顾一些运维和架构规划的工作, Doris的组件架构FE+BE理解起来简单,运维工作相对轻松。
(3)健壮活跃
公司没有自研方面的预算,但要求选择的开源产品一定是要有健壮性,不能产生严重的生产故障。Doris在百度内部已经深耕多年,这一点有保障,另外Doris社区的大佬们非常热情和活跃,遇到问题会积极响应。
三、新的架构及方案
3.1 业务架构
- 业务模型是最常见的分钟级调度ETL
- 离线数据利用DataX批量同步,通过Flink CDC将RDS的数据实时同步到Doris,利用Doris的物化视图或者Aggregate模型表进行实时汇总处理。
- 所有层级表模型大部分采用Unique key主键模型,可以有效保证数据脚本的幂等性,解决下游数据重复的问题
- ETL脚本通过Dolphinscheduler(简称DS)进行编排和统一调度
-
帆软BI进行自助取数和分析
一些截图:
DS中的ETL脚本可以进行版本控制,有效控制生产环境发生错误,及时回滚。
发布ETL脚本后导入数据,借助帆软系统进行页面制作,例如:针对数仓的权限管理,可以利用SQL控制到表级别、甚至行级别权限。
在新的架构体系,新增的数据需求直接利用帆软BI进行自助取数和分析,最快可在当天响应交付
3.2 数据模型
3.2.1 纵向分域
房地产中介行业的数据主题大致如下,围绕这些主题进行数仓建模,构建对应的事实表和维表。
3.2.2 横向分层
主要Dolphinscheduler进行调度任务的编排和管理。例如:早上8点到晚上12点基本采用增量策略,凌晨执行全量策略,目标是为了补数和修正历史状态变化数据。
层级 | 备注 | 存储策略 |
ODS | 利用datax doris write进行数据的本地导入要注意参数设置exec_mem_limit参数大小,部分全量数据较大超过限制会导致stream load 失败 | 08:00-00:00:00增量策略;凌晨全量策略一次 |
DWD | 部分事实表涉及缓慢变化维,需要进行拉链存储 | 08:00-00:00:00增量策略;凌晨执行全量策略,部分表拉链存储 |
DWS和ADS | 注意数据校验问题,加入审计时间,如etl_time,last_etl_time,create_time等字段,方便后续故障排查 | 08:00-00:00:00增量策略;凌晨全量策略一次 |
DIM | 维度表存放层,如客户,房源,职员,职级,岗位等 | 每小时整点全量策略一次 |
3.2.3 增量策略
-
where >=业务时间 -1 天
为什么不是where = 业务时间来增量当天数据呢,是为了避免数据漂移的情况。
-
每次跑增量脚本前,需要将表中最大的主键ID存入辅助表,where >= 辅助表记录ID
这种自增策略用在什么场景?比如Doris表如果是Unique key模型,且是组合主键的情况下,主键组合在源表发生了变化,这时候where >= 业务时间-1天会将这种同一记录,但是主键发生了变化的数据给load进来,造成数据重复。
这种自增策略局限性在于,源表需要自带业务自增主键
-
表分区
如日志表的历史数据和状态基本不会变更,由于数据量非常大,建表时,增量数据进行分区替换操作即可。
3.2.4 全量策略
-
Truncate Table清空表插入
如果是面向C端用户的公司和白天调度时间千万别这么做,否则会导致一段时间没有数据,Truncate Table适合数据量较小的表,凌晨没有用户使用系统的公司。
-
ALTER TABLE tbl1 REPLACE WITH TABLE tbl2 表替换
这种方式是一种原子操作,可以每次执行脚本前先create 一张相同的临时表,把全量数据load进去临时表,再执行表替换操作,可以无缝衔接。适合数据量大的全量表。
四、实践经验
-
内存一直不释放
Doris的BE节点在旧版本是开启PageCache 和 ChunkAllocator 的,目的是为了减少查询的延迟,这两个功能会占用一定比例的内存,并且一直不会释放,长此以往就会导致be计算资源越来越紧张。新版本直接禁用了这两个配置,但美联物业数仓是开启了这2项配置,并且每天凌晨进行be滚动重启的,既能保证be内存及时释放,也能降低查询延迟。
-
数据导入和 Catalog Doris
Catalog方式:利用Mysql JDBC类型的连接方式来对Doris生产集群数据进行读取,这样方便生产数据直接load进测试服务器。
但这种方式对FE节点的压力会很大,在导入过程中可明显观察FE节点CPU资源被拉满,如果Fe资源并不充足的情况下,建议选择Stream load的方式进行数据导入,如Datax。
在数据导入方式上,大部分返回结果是异步操作,即在Doris里该导入任务状态有可能是失败的,而Dolphinscheduler会误以为该脚本已经执行成功,因此在bash等脚本里执行Doris的导入操作逻辑时,还需要判断上游任务状态是否成功,可以在脚本里执行show load,再用正则去过滤状态进行判断。
-
前缀索引
尽量把非字符类型的,如int类型的、where条件中最常用的字段放前排36个字节内,在点查场景下,过滤这些字段返回的结果基本可在毫秒级别实现。
-
数据备份
目前Doris的备份依赖Broker load,只能基于BOS、HDFS 等文件系统,对于没有安装HDFS这类的服务器基本用不了。
-
数据字典
利用Doris自带的information_schema元数据可以制作简单的数据字典,这一点对公司还未建立数据治理体系前是非常重要的一步,方便低成本管理数仓人员的操作规范。
参考文章:
美联物业基于Apache Doris数仓实践