万字详解实时数仓建设及菜鸟仓储,知乎案例

中科荣膺公益中国 http://m.39.net/disease/a_6108173.html

“数据智能”(DataIntelligence)有一个必须且基础的环节,就是数据仓库的建设,同时,数据仓库也是公司数据发展到一定规模后必然会提供的一种基础服务。从智能商业的角度来讲,数据的结果代表了用户的反馈,获取结果的及时性就显得尤为重要,快速的获取数据反馈能够帮助公司更快的做出决策,更好的进行产品迭代,实时数仓在这一过程中起到了不可替代的作用。

一、实时数仓建设的背景

传统意义上的数据仓库主要处理T+1数据(即:今天产生的数据分析结果明天才能看到)。

随着互联网的发展,越来越多的业务指标需要实时查看,以便于更好的进行业务分析,尤其在举行活动的时候,能够更好的把握活动的各项指标趋势,从而更好的调整策略,达到活动的目标。

随着数据时效性在企业运营中的重要性日益凸现,例如,实时推荐、精准营销、广告投放效果、实时物流等。数据的实时处理能力成为企业提升竞争力的一大因素,最初阶段企业主要采用来一个需求,编写一个实时计算任务的方式来处理实时数据,随着需求的增多,计算任务也相应增多,并且不同任务的开发人员不同,导致开发风格差异化,该阶段的实时数据处理缺乏统一的规划,代码风格差异化严重,在维护成本和开发效率上有很大障碍。

为避免上述问题,人们参照数据仓库的概念和模型来重新规划和设计实时数据处理,在此基础上产生了实时数据仓库(实时数仓)。

1.实时数仓与离线数仓的对比

首先,从架构上,实时数仓与离线数仓有比较明显的区别,实时数仓以Kappa架构为主,而离线数仓以传统大数据架构为主。Lambda架构可以认为是两者的中间态。

其次,从建设方法上,实时数仓和离线数仓基本还是沿用传统的数仓主题建模理论,产出事实宽表。另外实时数仓中实时流数据的join有隐藏时间语义,在建设中需注意。

最后,从数据保障看,实时数仓因为要保证实时性,所以对数据量的变化较为敏感。在大促等场景下需要提前做好压测和主备保障工作,这是与离线数据的一个较为明显的区别。

一、实时需求

1日常统计报表或分析图中需要包含当日部分

对于日常企业、网站的运营管理如果仅仅依靠离线计算,数据的时效性往往无法满足。通过实时计算获得当日、分钟级、秒级甚至亚秒的数据更加便于企业对业务进行快速反应与调整。

所以实时计算结果往往要与离线数据进行合并或者对比展示在BI或者统计平台中

2实时数据大屏监控

数据大屏,相对于BI工具或者数据分析平台是更加直观的数据可视化方式。尤其是一些大促活动,已经成为必备的一种营销手段。另外还有一些特殊行业,比如交通、电信的行业,那么大屏监控几乎是必备的监控手段。

3数据预警或提示

经过大数据实时计算得到的一些风控预警、营销信息提示,能够快速让风控或营销部分得到信息,以便采取各种应对。

比如,用户在电商、金融平台中正在进行一些非法或欺诈类操作,那么大数据实时计算可以快速的将情况筛选出来发送风控部门进行处理,甚至自动屏蔽。或者检测到用户的行为对于某些商品具有较强的购买意愿,那么可以把这些“商机”推送给客服部门,让客服进行主动的跟进。

4实时推荐系统

实时推荐就是根据用户的自身属性结合当前的访问行为,经过实时的推荐算法计算,从而将用户可能喜欢的商品、新闻、视频等推送给用户。这种系统一般是由一个用户画像批处理加一个用户行为分析的流处理组合而成。

二、技术选型

与flink实时处理最密不可分的就是kafka,其次flink实时数据存储还有mysql、hbase、es、Druid等还有部分公司内部开发的数据存储。作为刚开始的公司构建实时数仓,选用市面上开源的数据库就足够可以使用了。

1、实时数仓各层级的技术选型

数据源:直接配置为kafka实时消息传输;

数据明细层:一般也会选择kafka作为数据存储,如果是这层做成大宽表的话,可以选择druid/hbase

数据汇总层:对数据进行高度汇总后的数据,这层一般也会选择kafka作为数据存储,这样需要保证各层级的数据通过kafka能够产生依赖。

应用层:应用层根据不同的业务类型选用不同的数据存储,如果结果需要能够快速搜索,可以选用es,如果结果需要进行多维数据统计分析,可以选用druid,如果结果数据量不是很大的话,最好选用mysql,相对来说,mysql的稳定性要好一点。

维度存储:维度如果是稳定并且数据量不大的情况下可以选择mysql,但是如果维度经常变动或者字段经常增加的话,最好选用hbase进行存储redis

三、实时数仓的架构设计:

离线大数据架构:HDFS存储,hive、mr、spark进行离线计算;

Lambda架构:在离线大数据架构的基础上增加新链路用于实时数据处理,需要维护离线处理和实时处理两套代码;

Kappa架构:批流合一,离线处理和实时处理整合成一套代码,运维成本小,这就是现今flink之所以火的原因。Kappa架构已成为数据仓库架构的新趋势。

计算框架选型:storm/flink等实时计算框架,强烈推荐flink,其『批量合一』的特性及活跃的开源社区,有逐渐替代spark的趋势。

数据存储选型:首要考虑查询效率,其次是插入、更新等问题,可选择apachedruid,不过在数据更新上存在缺陷,选型时注意该问题频繁更新的数据建议不要采用该方案。当然存储这块需要具体问题具体分析,不同场景下hbase、redis等都是可选项。

实时数仓分层:为更好的统一管理数据,实时数仓可采用离线数仓的数据模型进行分层处理,可以分为实时明细层写入druid等查询效率高的存储方便下游使用;轻度汇总层对数据进行汇总分析后供下游使用。

数据流转方案:实时数仓的数据来源可以为kafka消息队列,这样可以做到队列中的数据即可以写入数据湖用于批量分析,也可以实时处理,下游可以写入数据集市供业务使用。

综上,实时数仓主要解决数据时效性问题,结合机器学习框架可以处理实时推荐、实时获取广告投放效果等智能化业务场景。实时数仓的建设应早日提上日程,未来企业对数据时效性的要求会越来越高,实时数仓会很好的解决该问题。

案例一:菜鸟仓配实时数据仓库

本案例参考自菜鸟仓配团队的分享,涉及全局设计、数据模型、数据保障等几个方面。

5.1整体设计

基于业务系统的数据,数据模型采用中间层的设计理念,建设仓配实时数仓;

计算引擎,选择更易用、性能表现更佳的实时计算作为主要的计算引擎;

数据服务,选择天工数据服务中间件,避免直连数据库,且基于天工可以做到主备链路灵活配置秒级切换;

数据应用,围绕大促全链路,从活动计划、活动备货、活动直播、活动售后、活动复盘五个维度,建设仓配大促数据体系。

5.2数据模型

不管是从计算成本,还是从易用性,还是从复用性,还是从一致性,我们都必须避免烟囱式的开发模式,而是以中间层的方式建设仓配实时数仓。与离线中间层基本一致,我们将实时中间层分为两层。

第一层DWD公共实时明细层

实时计算订阅业务数据消息队列,然后通过数据清洗、多数据源join、流式数据与离线维度信息等的组合,将一些相同粒度的业务系统、维表中的维度属性全部关联到一起,增加数据易用性和复用性,得到最终的实时明细数据。这部分数据有两个分支,一部分直接落地到ADS,供实时明细查询使用,一部分再发送到消息队列中,供下层计算使用;

第二层DWS公共实时汇总层

以数据域+业务域的理念建设公共汇总层,与离线数仓不同的是,这里汇总层分为轻度汇总层和高度汇总层,并同时产出,轻度汇总层写入ADS,用于前端产品复杂的olap查询场景,满足自助分析和产出报表的需求;高度汇总层写入Hbase,用于前端比较简单的kv查询场景,提升查询性能,比如实时大屏等;

注:

1.ADS是一款提供OLAP分析服务的引擎。开源提供类似功能的有,ElasticSearch、Kylin、Druid等;

2.案例中选择把数据写入到Hbase供KV查询,也可根据情况选择其他引擎,比如数据量不多,查询压力也不大的话,可以用mysql

3.因主题建模与业务关系较大,这里不做描述

5.3数据保障

集团每年都有双十一等大促,大促期间流量与数据量都会暴增。

实时系统要保证实时性,相对离线系统对数据量要更敏感,对稳定性要求更高。

所以为了应对这种场景,还需要在这种场景下做两种准备:

大促前的系统压测;

大促中的主备链路保障;

案例二:知乎实时数仓架构实践及演进

一、实时数仓1.0版本

1.0版本的实时数仓主要是对流量数据做实时ETL,并不计算实时指标,也未建立起实时数仓体系,实时场景比较单一,对实时数据流的处理主要是为了提升数据平台的服务能力。实时数据的处理向上依赖数据的收集,向下关系到数据的查询和可视化,下图是实时数仓1.0版本的整体数据架构图。

第一部分是数据采集,由三端SDK采集数据并通过LogCollectorServer发送到Kafka。(客户端埋点流程、模型和平台技术)

第二部分是数据ETL,主要完成对原始数据的清洗和加工并分实时和离线导入Druid(Druid数据库)。

第三部分是数据可视化,由Druid负责计算指标并通过WebServer配合前端完成数据可视化。

Lambda架构有高容错、低延时和可扩展的特点,为了实现这一设计,我们将ETL工作分为两部分:StreamingETL和BatchETL。

StreamingETL

这一部分我会介绍实时计算框架的选择、数据正确性的保证、以及Streaming中一些通用的ETL逻辑,最后还会介绍SparkStreaming在实时ETL中的稳定性实践。

计算框架选择

在年年初,业界用的比较多的实时计算框架有Storm和SparkStreaming。Storm是纯流式框架,SparkStreaming用MicroBatch模拟流式计算,前者比后者更实时,后者比前者吞吐量大且生态系统更完善,考虑到知乎的日志量以及初期对实时性的要求,我们选择了SparkStreaming作为实时数据的处理框架。

数据正确性保证

SparkStreaming的端到端Exactly-once需要下游支持幂等、上游支持流量重放,这里我们在SparkStreaming这一层做到了At-least-once,正常情况下数据不重不少,但在程序重启时可能会重发部分数据,为了实现全局的Exactly-once,我们在下游做了去重逻辑,关于如何去重后面我会讲到。

通用ETL逻辑

ETL逻辑和埋点的数据结构息息相关,我们所有的埋点共用同一套ProtoBufferSchema,大致如下所示。

messageLogEntry{

optionalBaseInfobase=1;

optionalDetailInfodetail=2;

optionalExtraInfoextra=3;

}

BaseInfo:日志中最基本的信息,包括用户信息、客户端信息、时间信息、网络信息等日志发送时的必要信息。DetailInfo:日志中的视图信息,包括当前视图、上一个视图等用于定位用户所在位置的信息。ExtraInfo:日志中与特定业务相关的额外信息。

针对上述三种信息我们将ETL逻辑分为通用和非通用两类,通用逻辑和各个业务相关,主要应用于Base和Detail信息,非通用逻辑则是由需求方针对某次需求提出,主要应用于Extra信息。这里我们列举3个通用逻辑进行介绍,这包括:动态配置Streaming、UTM参数解析、新老用户识别。

动态配置Streaming

由于Streaming任务需要7*24小时运行,但有些业务逻辑,比如:存在一个元数据信息中心,当这个元数据发生变化时,需要将这种变化映射到数据流上方便下游使用数据,这种变化可能需要停止Streaming任务以更新业务逻辑,但元数据变化的频率非常高,且在元数据变化后如何及时通知程序的维护者也很难。动态配置Streaming为我们提供了一个解决方案,该方案如下图所示。

我们可以把经常变化的元数据作为StreamingBroadcast变量,该变量扮演的角色类似于只读缓存,同时针对该变量可设置TTL,缓存过期后Executor节点会重新向Driver请求最新的变量。通过这种机制可以非常自然的将元数据的变化映射到数据流上,无需重启任务也无需通知程序的维护者。

UTM参数解析

UTM的全称是UrchinTrackingModule,是用于追踪网站流量来源的利器,关于UTM背景知识介绍可以参考网上其他内容,这里不再赘述。下图是我们解析UTM信息的完整逻辑。

流量数据通过UTM参数解析后,我们可以很容易满足以下需求

查看各搜索引擎导流情况以及这些流量来自于哪些热门搜索词。

市场部某次活动带来的流量大小,如:页面浏览数、独立访问用户数等。

从站内分享出去的链接在各分享平台(如:


转载请注明:http://www.aierlanlan.com/tzrz/5304.html