桔妹导读:随着滴滴业务的高速发展,业务对于数据时效性的需求愈来愈高,而伴随着实时技术的不断发展和成熟,滴滴也对实时建设作了大量的尝试和实践。本文主要以顺风车这个业务为引子,从引擎侧、平台侧和业务侧各个不一样方面,来阐述滴滴所作的工做,分享在建设过程当中的经验。mysql
随着互联网的发展进入下半场,数据的时效性对企业的精细化运营愈来愈重要,商场如战场,在天天产生的海量数据中,如何能实时有效的挖掘出有价值的信息, 对企业的决策运营策略调整有很大帮助。redis
其次从智能商业的角度来说,数据的结果表明了用户的反馈,获取结果的及时性就显得尤其重要,快速的获取数据反馈可以帮助公司更快的作出决策,更好的进行产品迭代,实时数仓在这一过程当中起到了不可替代的做用。算法
从目前数仓建设的现状来看,实时数仓是一个容易让人产生混淆的概念,根据传统经验分析,数仓有一个重要的功能,即可以记录历史。一般,数仓都是但愿从业务上线的第一天开始有数据,而后一直记录到如今。但实时流处理技术,又是强调当前处理状态的一个技术,结合当前一线大厂的建设经验和滴滴在该领域的建设现状,咱们尝试把公司内实时数仓建设的目的定位为,以数仓建设理论和实时技术,解决因为当前离线数仓数据时效性低解决不了的问题。sql
现阶段咱们要建设实时数仓的主要缘由是:数据库
在公司内部,咱们数据团队有幸与顺风车业务线深刻合做,在知足业务方实时数据需求的同时,不断完善实时数仓内容,经过屡次迭代,基本知足了顺风车业务方在实时侧的各种业务需求,初步创建起顺风车实时数仓,完成了总体数据分层,包含明细数据和汇总数据,统一了DWD层,下降了大数据资源消耗,提升了数据复用性,可对外输出丰富的数据服务。json
数仓具体架构以下图所示:安全
从数据架构图来看,顺风车实时数仓和对应的离线数仓有不少相似的地方。例如分层结构;好比ODS层,明细层,汇总层,乃至应用层,他们命名的模式可能都是同样的。但仔细比较不难发现,二者有不少区别:架构
与离线数仓相比,实时数仓的层次更少一些app
从目前建设离线数仓的经验来看,数仓的数据明细层内容会很是丰富,处理明细数据外通常还会包含轻度汇总层的概念,另外离线数仓中应用层数据在数仓内部,但实时数仓中,app应用层数据已经落入应用系统的存储介质中,能够把该层与数仓的表分离。运维
应用层少建设的好处:实时处理数据的时候,每建一个层次,数据必然会产生必定的延迟。
汇总层少建的好处:在汇总统计的时候,每每为了容忍一部分数据的延迟,可能会人为的制造一些延迟来保证数据的准确。举例,在统计跨天相关的订单事件中的数据时,可能会等到 00:00:05 或者 00:00:10再统计,确保 00:00 前的数据已经所有接受到位了,再进行统计。因此,汇总层的层次太多的话,就会更大的加剧人为形成的数据延迟。 * 与离线数仓相比,实时数仓的数据源存储不一样
在建设离线数仓的时候,目前滴滴内部整个离线数仓都是创建在 Hive 表之上。可是,在建设实时数仓的时候,同一份表,会使用不一样的方式进行存储。好比常见的状况下,明细数据或者汇总数据都会存在 Kafka 里面,可是像城市、渠道等维度信息须要借助Hbase,mysql或者其余KV存储等数据库来进行存储。 接下来,根据顺风车实时数仓架构图,对每一层建设作具体展开:
根据顺风车具体场景,目前顺风车数据源主要包括订单相关的binlog日志,冒泡和安全相关的public日志,流量相关的埋点日志等。这些数据部分已采集写入kafka或ddmq等数据通道中,部分数据须要借助内部自研同步工具完成采集,最终基于顺风车数仓ods层建设规范分主题统一写入kafka存储介质中。
命名规范:ODS层实时数据源主要包括两种。
一种是在离线采集时已经自动生产的DDMQ或者是Kafka topic,这类型的数据命名方式为采集系统自动生成规范为:cn-binlog-数据库名-数据库名 eg:cn-binlog-ihap_fangyuan-ihap_fangyuan
一种是须要本身进行采集同步到kafka topic中,生产的topic命名规范同离线相似:ODS层采用:realtime_ods_binlog_{源系统库/表名}/ods_log_{日志名} eg: realtime_ods_binlog_ihap_fangyuan
根据顺风车业务过程做为建模驱动,基于每一个具体的业务过程特色,构建最细粒度的明细层事实表;结合顺风车分析师在离线侧的数据使用特色,将明细事实表的某些重要维度属性字段作适当冗余,完成宽表化处理,以后基于当前顺风车业务方对实时数据的需求重点,重点建设交易、财务、体验、安全、流量等几大模块;该层的数据来源于ODS层,经过大数据架构提供的Stream SQL完成ETL工做,对于binlog日志的处理主要进行简单的数据清洗、处理数据漂移和数据乱序,以及可能对多个ODS表进行Stream Join,对于流量日志主要是作通用的ETL处理和针对顺风车场景的数据过滤,完成非结构化数据的结构化处理和数据的分流;该层的数据除了存储在消息队列Kafka中,一般也会把数据实时写入Druid数据库中,供查询明细数据和做为简单汇总数据的加工数据源。
命名规范:DWD层的表命名使用英文小写字母,单词之间用下划线分开,总长度不能超过40个字符,而且应遵循下述规则:realtime_dwd_{业务/pub}{数据域缩写}[{业务过程缩写}]_[{自定义表命名标签缩写}]
{业务/pub}:参考业务命名
{数据域缩写}:参考数据域划分部分
{自定义表命名标签缩写}:实体名称能够根据数据仓库转换整合后作必定的业务抽象的名称,该名称应该准确表述实体所表明的业务含义
样例:realtime_dwd_trip_trd_order_base
公共维度层,基于维度建模理念思想,创建整个业务过程的一致性维度,下降数据计算口径和算法不统一风险;
DIM 层数据来源于两部分:一部分是Flink程序实时处理ODS层数据获得,另一部分是经过离线任务出仓获得;
DIM 层维度数据主要使用 MySQL、Hbase、fusion(滴滴自研KV存储) 三种存储引擎,对于维表数据比较少的状况可使用 MySQL,对于单条数据大小比较小,查询 QPS 比较高的状况,可使用 fusion 存储,下降机器内存资源占用,对于数据量比较大,对维表数据变化不是特别敏感的场景,可使用HBase 存储。
命名规范:DIM层的表命名使用英文小写字母,单词之间用下划线分开,总长度不能超过30个字符,而且应遵循下述规则:dim_{业务/pub}{维度定义}[{自定义命名标签}]:
{业务/pub}:参考业务命名
{维度定义}:参考维度命名
{自定义表命名标签缩写}:实体名称能够根据数据仓库转换整合后作必定的业务抽象的名称,该名称应该准确表述实体所表明的业务含义 样例:dim_trip_dri_base
在建设顺风车实时数仓的汇总层的时候,跟顺风车离线数仓有不少同样的地方,但其具体技术实现会存在很大不一样。
第一:对于一些共性指标的加工,好比pv,uv,订单业务过程指标等,咱们会在汇总层进行统一的运算,确保关于指标的口径是统一在一个固定的模型中完成。对于一些个性指标,从指标复用性的角度出发,肯定惟一的时间字段,同时该字段尽量与其余指标在时间维度上完成拉齐,例如行中异常订单数须要与交易域指标在事件时间上作到拉齐。
第二:在顺风车汇总层建设中,须要进行多维的主题汇总,由于实时数仓自己是面向主题的,可能每一个主题会关心的维度都不同,因此须要在不一样的主题下,按照这个主题关心的维度对数据进行汇总,最后来算业务方须要的汇总指标。在具体操做中,对于pv类指标使用Stream SQL实现1分钟汇总指标做为最小汇总单位指标,在此基础上进行时间维度上的指标累加;对于uv类指标直接使用druid数据库做为指标汇总容器,根据业务方对汇总指标的及时性和准确性的要求,实现相应的精确去重和非精确去重。
第三:汇总层建设过程当中,还会涉及到衍生维度的加工。在顺风车券相关的汇总指标加工中咱们使用Hbase的版本机制来构建一个衍生维度的拉链表,经过事件流和Hbase维表关联的方式获得实时数据当时的准确维度
命名规范:DWM层的表命名使用英文小写字母,单词之间用下划线分开,总长度不能超过40个字符,而且应遵循下述规则:realtime_dwm_{业务/pub}{数据域缩写}{数据主粒度缩写}[{自定义表命名标签缩写}]{统计时间周期范围缩写}:
{业务/pub}:参考业务命名
{数据域缩写}:参考数据域划分部分
{数据主粒度缩写}:指数据主要粒度或数据域的缩写,也是联合主键中的主要维度
{自定义表命名标签缩写}:实体名称能够根据数据仓库转换整合后作必定的业务抽象的名称,该名称应该准确表述实体所表明的业务含义
{统计时间周期范围缩写}:1d:天增量;td:天累计(全量);1h:小时增量;th:小时累计(全量);1min:分钟增量;tmin:分钟累计(全量)
样例:realtime_dwm_trip_trd_pas_bus_accum_1min
该层主要的工做是把实时汇总数据写入应用系统的数据库中,包括用于大屏显示和实时OLAP的Druid数据库(该数据库除了写入应用数据,也能够写入明细数据完成汇总指标的计算)中,用于实时数据接口服务的Hbase数据库,用于实时数据产品的mysql或者redis数据库中。
命名规范:基于实时数仓的特殊性不作硬性要求
截止目前,一共为顺风车业务线创建了增加、交易、体验、安全、财务五大模块,涉及40+的实时看板,涵盖顺风车所有核心业务过程,实时和离线数据偏差<0.5%,是顺风车业务线数据分析方面的有利补充,为顺风车当天发券动态策略调整,司乘安全相关监控,实时订单趋势分析等提供了实时数据支持,提升了决策的时效性。同时创建在数仓模型之上的实时指标能根据用户需求及时完成口径变动和实时离线数据一致性校验,大大提升了实时指标的开发效率和实时数据的准确性,也为公司内部大范围建设实时数仓提供了有力的理论和实践支持。
目前公司内部的实时数仓建设,须要依托数据平台的能力才能真正完成落地,包括StreamSQL能力,数据梦工程StreamSQL IDE环境和任务运维组件,实时数据源元数据化功能等。
StreamSQL是滴滴大数据引擎部在Flink SQL 基础上完善后造成的一个产品。使用 StreamSQL 具备多个优点:
StreamSQL 相对于 Flink SQL (1.9以前版本)的完善:
完善 DDL:包括上游的消息队列、下游的消息队列和各类存储如 Druid、HBase 都进行了打通,用户方只须要构建一个 source 就能够将上游或者下游描述出来。
内置消息格式解析:消费数据后须要将数据进行提取,但数据格式每每很是复杂,如数据库日志 binlog,每一个用户单独实现,难度较大。StreamSQL 将提取库名、表名、提取列等函数内置,用户只需建立 binlog 类型 source,并内置了去重能力。对于 business log 业务日志 StreamSQL 内置了提取日志头,提取业务字段并组装成 Map 的功能。对于 json 数据,用户无需自定义 UDF,只需经过 jsonPath 指定所需字段。
扩展UDX:丰富内置 UDX,如对 JSON、MAP 进行了扩展,这些在滴滴业务使用场景中较多。支持自定义 UDX,用户自定义 UDF 并使用 jar 包便可。兼容 Hive UDX,例如用户原来是一个 Hive SQL 任务,则转换成实时任务不须要较多改动,有助于批流一体化。
Join 能力扩展:
① 基于 TTL 的双流 join:在滴滴的流计算业务中有的 join 操做数据对应的跨度比较长,例如顺风车业务发单到接单的时间跨度可能达到一个星期左右,若是这些数据的 join 基于内存操做并不可行,一般将 join 数据放在状态中,窗口经过 TTL 实现,过时自动清理。
② 维表 join 能力:维表支持 HBase、KVStore、Mysql 等,同时支持 inner、left、right、full join 等多种方式。
StreamSQL IDE:
提供经常使用的SQL模板:在开发流式 SQL 时不须要从零开始,只须要选择一个 SQL 模板,并在这个模板之上进行修修改改便可达到指望的结果
提供 UDF 的库:至关于一个库若是不知道具备什么含义以及如何使用,用户只须要在 IDE 上搜索到这个库,就可以找到使用说明以及使用案例,提供语法检测与智能提示
提供代码在线DEBUG能力:能够上传本地测试数据或者采样少许 Kafka 等 source 数据 debug,此功能对流计算任务很是重要。提供版本管理功能,能够在业务版本不断升级过程当中,提供任务回退功能。
任务运维:任务运维主要分为四个方面
日志检索:Flink UI 上查询日志体验很是糟糕,滴滴将 Flink 任务日志进行了采集,存储在 ES 中,经过 WEB 化的界面进行检索,方便调查。
指标监控:Flink 指标较多,经过 Flink UI 查看体验糟糕,所以滴滴构建了一个外部的报表平台,能够对指标进行监控。
报警:报警须要作一个平衡,如重启报警有多类如 ( 机器宕机报警、代码错误报警 ),经过设置一天内单个任务报警次数阈值进行平衡,同时也包括存活报警 ( 如 kill、start )、延迟报警、重启报警和 Checkpoint 频繁失败报警 ( 如 checkpoint 周期配置不合理 ) 等。
血缘追踪:实时计算任务链路较长,从采集到消息通道,流计算,再到下游的存储常常包括4-5个环节,若是没法实现追踪,容易产生灾难性的问题。例如发现某流式任务流量暴涨后,须要先查看其消费的 topic 是否增长,topic 上游采集是否增长,采集的数据库 DB 是否产生不恰当地批量操做或者某个业务在不断增长日志。这类问题须要从下游到上游、从上游到下游多方向的血缘追踪,方便调查缘由。
将topic引入成实时表,metastore统一管理元数据,实时开发中统一管理DDL过程。对实时数仓来讲,经过元数据化,能够沉淀实时数仓的建设成果,使数仓建模能更好的落地
目前数据梦工厂支持的元数据化实时数据源包括Postgre、DDMQ、Mysql、Druid、ClickHouse、Kylin、Kafka。
虽然目前滴滴在实时数仓建设方面已初具规模,但其面临的问题也不容忽视。
问题:为了快速响应业务需求,同时知足数仓的需求开发流程,迫切须要建设一套面向实时数据开发的规范白皮书,该白皮书须要涉及需求对接、口径梳理、数据开发、任务发布、任务监控、任务保障
目前解决方案:目前由数据BP牵头,制定了一套面向实时数据指标的开发规范:
常规流程:需求方提出需求,分析师对接需求,提供计算口径,编写需求文档。以后由数仓BP和离线数仓同窗check计算口径,并向实时数仓团队提供离线hive表,实时数仓同窗基于离线hive表完成数据探查,基于实时数仓模型完成实时数据需求开发,经过离线口径完成数据自查,最终交付给分析师完成二次校验后指标上线。
口径变动--业务方发起:业务方发起口径变动,判断是否涉及到实时指标,数仓BP对离线和实时口径进行拉齐,向离线数仓团队和实时数仓团队提供更口口径和数据源表,实时数仓团队先上测试看板,验收经过后切换到正式看板
存在的不足:
当针对某个业务进行新的实时数据建设时,会有一个比较艰难的初始化过程,这个初始化过程当中,会和离线有较多耦和,须要肯定指标口径,数据源,并进行大量开发测试工做
在指标口径发生变动的时候,须要有一个较好的通知机制,目前仍是从人的角度来进行判断。
目前解决办法:由业务、BP、离线数仓共同保证数据源、计算口径与离线一致,数据加工过程,逐层与离线进行数据比对,并对指标结果进行详细测试,数据校验经过并上线后,根据离线周期进行实时和离线数据的校验
待解决的问题:结合指标管理工具,保证指标口径上的一致性,扩展数据梦工厂功能,在指标加工过程当中,增长实时离线比对功能,下降数据比对成本。
虽然 Flink 具有批流一体化能力,但滴滴目前并无彻底批流一体化,但愿先从产品层面实现批流一体化。经过 Meta 化建设,实现整个滴滴只有一个 MetaStore,不管是 Hive、Kafka topic、仍是下游的 HBase、ES 都定义到 MetaStore 中,全部的计算引擎包括 Hive、Spark、Presto、Flink 都查询同一个 MetaStore,实现整个 SQL 开发彻底一致的效果。根据 SQL 消费的 Source 是表仍是流,来区分批处理任务和流处理任务,从产品层面上实现批流一体化效果。
团队介绍
本文内容涉及三个滴滴云平台事业群团队,云平台事业部大数据架构团队,主要负责大数据底层引擎的建设,建设并维护公司内部,离线、OLAP、实时、保障等底层引擎。云平台事业部大数据平台部,主要负责公司内部通用平台建设,包括一站式开发平台,内置业界沉淀多年的数据开发流程及规范,知足用户对数据开发、数据安全、质量管理、数据管理需求。云平台事业部实时数仓团队,主要负责滴滴内部各业务线的实时数据建设、以及实时数据规范的沉淀,中间层的数据建设等。
做者介绍
负责实时数据仓库建设,多年数据相关工做经验,专一数据建模、数据仓库、实时数据技术等领域。
主要从事实时数据仓库建设,专一实时和离线数仓技术,对数仓建模、数据研发和数仓中间层建设有必定积累。
内容编辑 | Charlotte
联系咱们 | DiDiTech@didiglobal.com
滴滴技术 出品