导读: 传统行业面对数字化转型往往会遇到很多困难,比如缺乏数据管理体系、数据需求开发流程冗长、烟囱式开发、过于依赖纸质化办公等,美联物业也有遇到类似的问题。本文主要介绍美联物业基于 Apache Doris 在数据体系方面的建设,以及对数据仓库搭建经验进行的分享和介绍,旨在为数据量不大的传统企业提供一些数仓思路,实现数据驱动业务,低成本、高效的进行数仓改造。
作者|美联物业数仓负责人 谢帮桂
美联物业属于香港美联集团成员,于 1973 年成立,并于 1995 年在香港联合交易所挂牌上市(香港联交所编号:1200),2008 年美联工商铺于主板上市(香港联交所编号:459), 成为拥有两家上市公司的地产代理企业。拥有 40 余载房地产销售行业经验,业务涵盖中、小型住宅、豪宅及工商铺,提供移民顾问、金融、测量、按揭转介等服务,业务遍布中国香港地区、中国澳门地区和中国内地等多个重要城市。
本文主要介绍关于美联物业在数据体系方面的建设,以及对数据仓库搭建经验进行的分享和介绍,旨在为数据量不大的传统企业提供一些数仓思路,实现数据驱动业务,低成本、高效的进行数仓改造。
考虑隐私政策,本文不涉及公司任何具体业务数据。
美联物业早在十多年前就已深入各城市开展房地产中介业务,数据体系的建设和发展与大多数传统服务型公司类似,经历过几个阶段时期,如下图所示
我们的数据来源于大大小小的子业务系统和部门手工报表数据等,存在历史存量数据庞大,数据结构多样复杂,数据质量差等普遍性问题。此外,早期业务逻辑处理多数是使用关系型数据库 SQL Server 的存储过程来实现,当业务流程稍作变更,就需要投入大量精力排查存储过程并进行修改,使用及维护成本都比较高。
基于此背景,我们面临的挑战可以大致归纳为以下几点:
针对上述的⼏个需求,我们在平台建设的初期选⽤了 Hadoop、Hive、Spark 构建最初的离线数仓架构,也是比较普遍、常见的架构,运作原理不进行过多赘述。
我们数据体系主要服务对象以内部员工为主,如房产经纪人、后勤人员、行政人事、计算机部门,房产经纪在全国范围内分布广泛,也是我们的主要服务对象。当前数据体系还无需面向 C 端用户,因此在数据计算和资源方面的压力并不大,早期基于 Hadoop 的架构可以满足一部分基本的需求。但是随着业务的不断发展、内部人员对于数据分析的复杂性、分析的效率也越来越高,该架构的弊端日益越发的明显,主要体现为以下几点:
基于上述业务需求及痛点,我们开始了架构升级,并希望在这次升级中实现几个目标:
经过调研了解以及朋友推荐,我们了解到了 Apache Doris ,并很快与社区取得了联系,Apache Doris 的几大优势吸引了我们:
足够简单
美联物业及大部分传统公司的数据人员除了需要完成数据开发工作之外,还需要兼顾运维和架构规划的工作。因此我们选择数仓组件的第一原则就是"简单",简单主要包括两个方面:
极速性能
Doris 依托于列式存储引擎、自动分区分桶、向量计算、多方面 Join 优化和物化视图等功能的实现,可以覆盖众多场景的查询优化,海量数据也能可以保证低延迟查询,实现分钟级或秒级响应。
极低成本
降本提效已经成为现如今企业发展的常态,免费的开源软件就比较满足我们的条件,另外基于 Doris 极简的架构、语言的兼容、丰富的生态等,为我们节省了不少的资源和人力的投入。并且 Doris 支持 PB 级别的存储和分析,对于存量历史数据较大、增量数据较少的公司来说,仅用 5-8 个节点就足以支撑上线使用。
社区活跃
截止目前,Apache Doris 已开源数年,并已支持全国超 1500 企业生产使用,其健壮性、稳定性不可否认。另外社区非常活跃,SelectDB 为社区组建了专职的技术支持团队,任何问题均能快速反馈,提供无偿技术支持,使用起来没有后顾之忧。
在对 Apache Doris 进一步测试验证之后,我们完全摒弃了之前使用 Hadoop、Hive、Spark 体系建立的数仓,决定基于 Doris 对架构进行重构,以 Apache Doris 作为数仓主体进行开发:
1)纵向分域
房地产中介行业的大数据主题大致如下,一般会根据这些主题进行数仓建模。建模主题域核心围绕"企业用户"、“客户”、“房源”、"组织"等几个业务实体展开,进行维度表和事实表的创建。
我们从前线到后勤,对业务数据总线进行了梳理,旨在整理业务实体和业务活动相关数据,如多个系统之间存在同一个业务实体,应统一为一个字段。梳理业务总线有助于掌握公司整体数据结构,便于维度建模等工作。
下图为我们简单的梳理部分房地产中介行业的业务总线:
2)横向分层
数据分层是最常见的 5 层结构主要是利用 Apache Doris + Apache DolphinScheduler 进行层级数据之间 DAG 脚本调度。
存储策略: 我们在 8 点到 24 点之间采用增量策略,0 点到 8 点执行全量策略。采用增量 + 全量的方式是为了在ODS 表因为记录的历史状态字段变更或者 CDC 出现数据未完全同步的情况下,可以及时进行全量补数修正。
3)增量策略
增量的 SQL 语句不使用 where="业务时间当天"
的原因是为了避免数据漂移情况发生,换言之,调度脚本之间存在时间差,如 23:58:00 执行了脚本,脚本的执行周期是 10 分钟/次,但是源库最后一条数据 23:59:00 才进来,这时候 where="业务时间当天"
就会将该数据漏掉。
where >= "辅助表记录ID"
如果 Doris 表使用的是 Unique Key 模型,且恰好为组合主键,当主键组合在源表发生了变化,这时候 where >=" 业务时间-1天"
会记录该变化,把主键发生变化的数据 Load 进来,从而造成数据重复。而使用这种自增策略可有效避免该情况发生,且自增策略只适用于源表自带业务自增主键的情况。
如面对日志表等基于时间的自增数据,且历史数据和状态基本不会变更,数据量非常大,全量或快照计算压力非常大的场景,这种场景需要对 Doris 表进行建表分区,每次增量进行分区替换操作即可,同时需要注意数据漂移情况。
4)全量策略
先清空表格后再把源表数据全量导入,该方式适用于数据量较小的表格和凌晨没有用户使用系统的场景。
ALTER TABLE tbl1 REPLACE WITH TABLE tbl2
表替换这种方式是一种原子操作,适合数据量大的全量表。每次执行脚本前先 Create 一张数据结构相同的临时表,把全量数据 Load 到临时表,再执行表替换操作,可以进行无缝衔接。
EXECUTE CDCSOURCE demo_doris WITH (
'connector' = 'mysql-cdc',
'hostname' = '127.0.0.1',
'port' = '3306',
'username' = 'root',
'p assword' = '123456',
'checkpoint' = '10000',
'scan.startup.mode' = 'initial',
'parallelism' = '1',
'table-name' = 'ods.ods_*,ods.ods_*',
'sink.connector' = 'doris',
'sink.fenodes' = '127.0.0.1:8030',
'sink.username' = 'root',
'sink.password' = '123456',
'sink.doris.batch.size' = '1000',
'sink.sink.max-retries' = '1',
'sink.sink.batch.interval' = '60000',
'sink.sink.db' = 'test',
'sink.sink.properties.format' ='json',
'sink.sink.properties.read_json_by_line' ='true',
'sink.table.identifier' = '${schemaName}.${tableName}',
'sink.sink.label-prefix' = '${schemaName}_${tableName}_1'
);
除以上之外,在容灾恢复、集群监控、数据安全等方面也有应用,比如利用 Doris 备份实现容灾恢复、Grafana+Loki 对集群进行指标规则告警、Supervisor 对节点组件进行守护进程监控,开启 Doris 审计日志对执行 SQL 效率进行监控等,因篇幅限制,此处不进行详细说明。
我们使用 DataX 进行离线数据导入,DataX 采用的是 Stream Load 方式导入,该方式可以通过参数控制导入批次流量,DataX 导入不需要借助计算引擎,开箱即用的特点非常方便。另外,Stream Load 导入是同步返回结果的,其他导入方式一般是异步返回结果,针对我们的架构来说,在 Dolphinscheduler上执行异步导入数据会误以为该脚本已经执行成功,影响其正常运行。如采用其他异步导入方式,建议在 Shell 脚本中 执行 show load
再利用正则过滤状态进行判断。
我们所有层级的表模型大部分采用 Unique Key 模型,该模型可有效保证数据脚本的结果幂等性,Unique Key 模型可以完美解决上游数据重复的问题,大家可以根据业务模式来选择不同的模型建表。
Catalog 方式可以使用 JDBC 外表连接,还可以对 Doris 生产集群数据进行读取,便于生产数据直接 Load 进测试服务器进行测试。另外,新版支持多数据源的 Catalog,可以基于 Catalog 对 ODS 层进行改造,无需使用 DataX 对ODS 层进行导入。
尽量把非字符类型(如 int 类型、where 条件)中最常用的字段放在前排 36 个字节内,在点查表过程中可以快速过滤这些字段(毫秒级别),可以充分利用该特性进行数据表输出。
利用 Doris 自带的 information_schema
元数据制作简单的数据字典,这在还未建立数据治理体系前非常重要,当部门人数较多的时候,沟通成本成为发展过程中最大的“拦路虎”,利用数据字典可快速对表格和字段的全局查找和释义,最低成本形成数仓人员的数据规范,减少人员沟通成本,提高开发效率。
目前我们已经完成数仓建设的初期目标,未来我们有计划基于 Apache Doris 进行中台化的改造,同时 Apache Doris在用户画像和人群圈选场景的能力十分强悍,支持 Bitmap 等格式进行导入和转换,提供了丰富的 Bitmap 分析函数等,后续我们也将利用这部分能力进行客户群体分析,加快数字化转型。
最后,感谢 Apache Doris 社区和 SelectDB 团队对美联物业的快速响应和无偿支持,希望 Doris 发展越来越好,也希望更多的企业可以尝试使用 Apache Doris。