跳至主要內容

美联物业基于 Apache Doris 数仓实践

PowerData大约 11 分钟数据中台

本文由 PowerData 谢帮桂贡献
姓名:谢帮桂
花名:谢帮桂
微信:xc606060_
年龄:90 后
工作经验:5-10 年
工作内容:数仓, 数分
自我介绍:一美联物业数仓负责人,主要负责数仓规划和数据开发,下方是作者帅照喔。


全文共 2969 个字,建议阅读 13 分钟

一、背景

企业背景

美联物业属于香港美联集团成员,于 1973 年成立,并于 1995 年在香港联合交易所挂牌上市 (香港联交所编号: 1200),2008 年美联工商铺于主板上市(香港联交所编号: 459), 成为拥有两家上市公司的地产代理企业。拥有 40 余载房地产销售行业经验,业务涵盖中、小型住宅、豪宅及工商铺,提供移民顾问、金融、测量、按揭转介等服务,业务遍布中国香港地区、中国澳门地区、中国内地。

美联物业目前数仓主要服务和面向内部客户为主,如后勤、行政、开发人员、更多的是房产经纪,这部分在全国约上万人,无需面向 C 端用户,因此计算方面和面向 C 端用户的企业 (类似贝壳) 相比并不算大。

其次,美联物业是一家传统型的老牌企业,深耕香港和深圳多年,在以前大多数的数据分析工作都基于文本文件和依赖人力手工进行统计,为实现数据驱动业务,方便进行有效的目标管理,搭建数仓体系。

面临的问题

  • 没有统一数据管理体系和数据治理,数据质量较差,如多部门、多系统、多字段,命名随意、表违反范式结构混乱。

  • 没有统一的分析处理平台,关系数据库分表分库无法做到上亿数据秒级分析查询。

  • 没有充分利用数据驱动业务,数据需求流程冗长 + 烟囱式开发。

  • 没有数据资产管理体系,无法实现数据的降本复用。

  • 部门之间严重依赖文本文档处理工作,效率低下。

主要需求

  • 业务部门的数据报表需求

  • app 的数据接口需求

  • 快速的自助分析场景等

首期目标

  • 建立初段数据管理体系,搭建美联数据仓库。

  • 搭建业务报表平台和报表需求 + 开发流程体系。

  • 实现报表和分析需求能够快速反应和交付

二、总体架构

运行架构

和大部分公司的数仓有不同的是,我们摒弃了之前使用的 Hadoop、Hive、Spark 体系建立的数仓,完全改用 Apache Doris 作为数仓主体进行开发,摒弃 Hadoop 全家桶主要有是几个原因:

①过于笨重:对于传统公司的计算量和数据量,Hadoop 显得杀鸡用牛刀。

②效率低下:T-1 的调度时效和脚本动辄花费 1 小时的计算时间很影响数据开发工作。

③维护成本高:组件过多,排查故障链路过长,且部门同事之间熟悉各个组件需要大量沟通成本。

改用 Apache Doris 主要有几个方面原因:

足够简单

传统公司数据部门不像互联网公司一样,数据部门几十个人,传统公司大部分对数据人员的要求除了数据开发之外,也要兼顾一些运维和架构规划的工作,因此我们选择数仓组件的第一原则就是 "简单",比如统一开发语言 SQL,部门之间以 SQL 为主的开发语言,统一语言利于开发效率和共识统一,Apache Doris 基本脚本就是 SQL 开发。另外 Apache Doris 的组件架构 FE+BE 理解起来也非常简单,运维工作相对轻松,排查故障的链路也非常清晰。

快速响应

无需面对 C 端群体,不需要要求系统有很高的并发特性和 PB 级存储,销售行业讲究的是业务需求要快速响应,因此很多时候需要数据实时交付和分钟级交付。Doris 也满足这点。

健壮活跃

选择开源组件也是因为公司没有自研方面的预算,但要求选择的开源产品一定是要有健壮性,不能产生严重的生产故障。Doris 在百度内部已经深耕多年,这一点也是有保障,另外 Doris 社区和 SelectDB 社区的大佬们也非常热情和活跃,遇到问题大家会积极响应。

业务模型

  • 业务模型是最常见的分钟级调度 ETL。

  • 离线数据利用 DataX 进行增量和全量调度,部分指标需要实时统计,因此也借助了 Flink CDC 对源表进行实时同步,利用 Doris 的物化视图或者 Aggregate 模型表进行实时汇总处理。

  • 脚本语言采用 bash+SQL,或者是纯 SQL,在 Apache Dolphinscheduler 上进行管理和发布。

  • 所有层级表模型大部分采用 Unique key 模型,可以有效保证数据脚本的结果幂等性,Unique key 模型完美解决下游数据重复的问题,但是要注意主键不可以重复。

  • BI 系统选择的帆软

一些截图:

Apache Dolphinscheduler 的 Doris 脚本可以进行版本控制,有效控制生产环境发生错误,及时回滚。

发布 ETL 脚本后导入数据,直接帆软系统进行页面制作,可以基于登陆账号控制页面权限,也可以利用 SQL 控制到表级别、甚至行级别权限。

一键发布及热部署数据报表

整个业务链路在美联物业提出数据需求,最快可以在当天进行数据交付,直接在帆软 BI 进行自助取数和分析,另外整个数仓的权限控制、容灾恢复、集群监控、数据安全内容较多,此处不过多展开。

数据模型

纵向分域

房地产中介行业的大数据主题大致如上,围绕这些主题进行数仓建模。建模主题域核心围绕 "企业用户"" 客户 ""房源"" 组织 " 几个业务实体展开的以部门功能为依据的主题域数据模型, 核心也是围绕这些个业务实体进行维度表和事实表创建等。

横向分层

主要是利用 Apache Doris + Apache Dolphinscheduler 进行调度脚本处理。

早上 8 点到晚上 12 点基本采用增量策略,凌晨执行全量策略,目的是为了补数和修正历史状态变化数据。

层级备注存储策略
ODS利用 Datax Doris write 进行数据的本地导入要注意参数设置 exec_mem_limit 参数大小,部分全量数据较大超过限制会导致 stream load 失败8-0 点增量策略凌晨全量策略一次
DWD部分事实表涉及缓慢变化维,需要进行拉链存储。8-0 点增量策略凌晨全量策略一次部分表拉链存储
DWS 与 ADS注意数据校验问题,加入审计时间,如 etl_time,last_etl_time,create_time 等字段,方便后续故障排查8-0 点增量策略凌晨全量策略一次
DIM维度表存放层,基于业务实体,如客户,房源,职员,职级,岗位等每小时整点全量

增量策略

  • where >= 业务时间 -1 天

为什么不是 where = 业务时间来增量当天数据,是为了避免数据漂移的情况。

  • 每次跑增量脚本前获取表中最大的主键 ID 存入辅助表,where >= 辅助表记录 ID

这种自增策略用在什么场景?比如 Doris 表如果是 Unique key 模型,恰好是组合主键,主键组合在源表发生了变化,这时候 where >= 业务时间 - 1 天会将这种同一记录,但是主键发生了变化的数据给 load 进来,造成数据重复。

但是这种自增策略存在局限性就是,要建立在源表自带业务自增主键的情况

  • 表分区

如日志表等是基于时间自增数据,且历史数据和状态基本不会变更,数据量非常大,这种存储需要对 Doris 表进行建表分区,每次增量进行分区替换操作即可。

全量策略

  • Truncate Table  清空表插入

后再把源表表进行导入。如果是面向 C 端用户的公司和白天调度时间千万别这么做,会有一段时间没有数据,适合数据量较小的表格和凌晨没有用户使用系统的公司。

  • 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。

在数据导入方式上,大部分返回结果不是同步的,是异步操作,但是在 Dolphinscheduler 上会误以为该脚本已经执行成功,但在 Doris 里该导入任务状态有可能是失败的,因此在 bash 等脚本里执行 Doris 的导入操作,记得去判断上游任务状态是否成功,可以在脚本里执行 show load 再利用正则去过滤状态进行判断。

  • 数据备份

目前 Doris 的备份依赖 Broker load,只能基于 BOS、HDFS 等文件系统,对于没有安装 HDFS 这类的服务器基本用不了。

这一部分只能依赖其他第三方运维组件进行数据表的备份操作了,希望后期可以直接基于服务器本地进行备份操作。

  • 前缀索引

尽量把非字符类型的,如 int 类型的、where 条件中最常用的字段放前排 36 个字节内,在点查表过程中过滤这些字段,基本是毫秒级别,充分利用这个特性进行数据表输出。

  • 数据字典

利用 Doris 自带的 information_schema 元数据可以制作简单的数据字典,这一点对公司还未建立数据治理体系前是非常重要的一步,方便低成本管理数仓人员的操作规范。

想要加入社区或对本文有任何疑问,可直接添加作者微信交流。

图:作者微信

我们是由一群数据从业人员,因为热爱凝聚在一起,以开源精神为基础,组成的 PowerData 数据之力社区。

关注公众号后点击 “加入我们”,与 PowerData 一起成长