职贝云数AI新零售门户

标题: 知乎实时数仓架构及演进 [打印本页]

作者: taojin168    时间: 2022-12-31 11:44
标题: 知乎实时数仓架构及演进
转载自 https://blog.csdn.net/weixin_34064653/article/details/89089961
“数据智能” (Data Intelligence) 有一个必须且基础的环节,就是数据仓库的建设,同时,数据仓库也是公司数据发展到一定规模后必然会提供的一种基础服务。从智能商业的角度来讲,数据的结果代表了用户的反馈,获取结果的及时性就显得尤为重要,疾速的获取数据反馈可以协助公司更快的做出决策,更好的停止产品迭代,实时数仓在这一过程中起到了不可替代的作用。
本文次要讲述知乎的实时数仓实际以及架构的演进,这包括以下几个方面
实时数仓 1.0 版本

1.0 版本的实时数仓次要是对流量数据做实时 ETL,并不计算实时目的,也未建立起实时数仓体系,实时场景比较单一,对实时数据流的处理次要是为了提升数据平台的服务才能。实时数据的处理向上依赖数据的搜集,向下关系到数据的查询和可视化,下图是实时数仓 1.0 版本的全体数据架构图。
(, 下载次数: 3)


第一部分是数据采集,由三端 SDK 采集数据并经过 Log Collector Server 发送到 Kafka。第二部分是数据 ETL,次要完成对原始数据的清洗和加工并分实时和离线导入 Druid。第三部分是数据可视化,由 Druid 担任计算目的并经过 Web Server 配合前端完成数据可视化。
其中第一、三部分的相关内容请分别参考:知乎客户端埋点流程、模型和平台技术,Druid 与知乎数据分析平台,此处我们详细引见第二部分。由于实时数据流的波动性不如离线数据流,当实时流出现成绩后需求离线数据重刷历史数据,因此实时处理部分我们采用了 lambda 架构。
Lambda 架构有高容错、低延时和可扩展的特点,为了完成这一设计,我们将 ETL 工作分为两部分:Streaming ETL 和 Batch ETL。
Streaming ETL

这一部分我会引见实时计算框架的选择、数据正确性的保证、以及 Streaming 中一些通用的 ETL 逻辑,最后还会引见 Spark Streaming 在实时 ETL 中的波动性实际。
计算框架选择

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

Spark Streaming 的端到端 Exactly-once 需求下游支持幂等、下游支持流量重放,这里我们在 Spark Streaming 这一层做到了 At-least-once,正常状况下数据不重不少,但在程序重启时能够会重发部分数据,为了完成全局的 Exactly-once,我们在下游做了去重逻辑,关于如何去重后面我会讲到。
通用 ETL 逻辑

ETL 逻辑和埋点的数据结构毫不相关,我们一切的埋点共用同一套 Proto Buffer Schema,大致如下所示。
message LogEntry {  optionalBaseInfo base = 1;  optionalDetailInfo detail = 2;  optionalExtraInfo extra = 3;}
BaseInfo:日志中最基本的信息,包括用户信息、客户端信息、工夫信息、网络信息等日志发送时的必要信息。DetailInfo:日志中的视图信息,包括当前视图、上一个视图等用于定位用户所在地位的信息。ExtraInfo:日志中与特定业务相关的额外信息。
针对上述三种信息我们将 ETL 逻辑分为通用和非通用两类,通用逻辑和各个业务相关,次要运用于 Base 和 Detail 信息,非通用逻辑则是由需求方针对某次需求提出,次要运用于 Extra 信息。这里我们罗列 3 个通用逻辑停止引见,这包括:动态配置 Streaming、UTM 参数解析、新老用户辨认。
动态配置 Streaming

由于 Streaming 义务需求 7 * 24 小时运转,但有些业务逻辑,比如:存在一个元数据信息中心,当这个元数据发生变化时,需求将这种变化映射到数据流上方便下游运用数据,这种变化能够需求中止 Streaming 义务以更新业务逻辑,但元数据变化的频率非常高,且在元数据变化后如何及时告诉程序的维护者也很难。动态配置 Streaming 为我们提供了一个处理方案,该方案如下图所示。
(, 下载次数: 3)


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

UTM 的全称是 Urchin Tracking Module,是用于追踪网站流量来源的利器,关于 UTM 背景知识引见可以参考网上其他内容,这里不再赘述。下图是我们解析 UTM 信息的残缺逻辑。
(, 下载次数: 3)


流量数据经过 UTM 参数解析后,我们可以很容易满足以下需求
新老用户辨认

对于互联网公司而言,增长是一个永久的话题,实时拿到新增用户量,对于增长运营非常重要。例如:一次投放 n 个渠道,假如能拿到每个渠道的实时新增用户数,就可以疾速判别出那些渠道更有价值。我们用下图来表达 Streaming ETL 中是如何辨认新老用户的。
(, 下载次数: 3)


判别一个用户是不是新用户,最简单的办法就是维护一个历史用户池,对每条日志判别该用户能否存在于用户池中。 由于日志量宏大,为了不影响 Streaming 义务的处理速度,我们设计了两层缓存:Thread Local Cache 和 Redis Cache,同时用 HBase 做持久化存储以保存历史用户。访问速度:本地内存 \u0026gt; 远端内存 \u0026gt; 远端磁盘,对于我们这个义务来说,只要 1% 左右的央求会打到 HBase,日志高峰期 26w/s,完全不会影响义务的实时性。当然本地缓存 LruCache 的容量大小和 Redis 的功能也是影响实时性的两个要素。
Streaming ETL 除了上述几个通用场景外,还有一些其他逻辑,这些逻辑的存在有的是为了满足下游更方便的运用数据的需求,有的是对某些错误埋点的修复,总之 Streaming ETL 在整个实时数仓中处于目的计算的下游,有着不可替代的作用。
Spark Streaming 在实时数仓 1.0 中的波动性实际

Batch ETL

接上去要引见的是 Lambda 架构的第二个部分:Batch ETL,此部分我们需求处理数据落地、离线 ETL、数据批量导入 Druid 等成绩。针对数据落地我们自研了 map reduce 义务 Batch Loader,针对数据修复我们自研了离线义务 Repair ETL,离线修复逻辑和实时逻辑共用一套 ETL Lib,针对批量导入 ProtoParquet 数据到 Druid,我们扩展了 Druid 的导入插件。
Repair ETL

数据架构图中有两个 Kafka,第一个 Kafka 存放的是原始日志,第二个 Kafka 存放的是实时 ETL 后的日志,我们将两个 Kafka 的数据全部落地,这样做的目的是为了保证数据链路的波动性。由于实时 ETL 中有大量的业务逻辑,未知需求的逻辑也许会给整个流量数据带来安全隐患,而下游的 Log Collect Server 不存在任何业务逻辑只担任收发日志,相比之下第一个 Kafka 的数据要安全和波动的多。Repair ETL 并不是常常启用,只要当实时 ETL 丢失数据或者出现逻辑错误时,才会启用该程序用于修复日志。
Batch Load 2 HDFS

后面曾经引见过,我们一切的埋点共用同一套 Proto Buffer Schema,数据传输格式全部为二进制。我们自研了落地 Kafka PB 数据到 Hdfs 的 Map Reduce 义务 BatchLoader,该义务除了落地数据外,还担任对数据去重。在 Streaming ETL 阶段我们做到了 At-least-once,经过此处的BatchLoader 去重我们完成了全局 Exactly-once。BatchLoader 除了支持落地数据、对数据去重外,还支持多目录分区(p_date/p_hour/p_plaform/p_logtype)、数据回放、自依赖管理(早期没有一致的调度器)等。截止到目前,BatchLoader 落地了 40+ 的 Kakfa Topic 数据。
Batch Load 2 Druid

采用 Tranquility 实时导入 Druid,这种方式强迫需求一个工夫窗口,当下游数据延迟超过窗值后会丢弃窗口之外的数据,这种状况会导致实时报表出现目的错误。为了修复这种错误,我们经过 Druid 发起一个离线 Map Reduce 义务定期重导上一个工夫段的数据。经过这里的 Batch 导入和后面的实时导入,完成了实时数仓的 Lambda 架构。
实时数仓 1.0 的几个不足之处

到目前为止我们曾经引见完 Lambda 架构实时数仓的几个模块,1.0 版本的实时数仓有以下几个不足
实时数仓 2.0 版本

随着数据量的暴涨,Druid 中的流量数据源常常查询超时同时各业务消费实时数据的需求也末尾增多,假如继续沿用实时数仓 1.0 架构,需求付出大量的额外成本。于是,在实时数仓 1.0 的基础上,我们建立起了实时数仓 2.0,梳理出了新的架构设计并末尾着手建立实时数仓体系,新的架构如下图所示。
(, 下载次数: 3)


原始层

实时数仓 1.0 我们只对流量数据做 ETL 处理,在 2.0 版本中我们加入了对业务库的变更日志 Binlog 的处理,Binlog 日志在原始层为库级别或者 Mysql 实例级别,即:一个库或者实例的变更日志存放在同一个 Kafka Topic 中。同时随着公司业务的发展不断有新 App 产生,在原始层不只采集「知乎」日志,像知乎极速版以及外部孵化项目的埋点数据也需求采集,不同 App 的埋点数据依然运用同一套 PB Schema。
明细层

明细层是我们的 ETL 层,这一层数据是由原始层经过 Streaming ETL 后得到。其中对 Binlog 日志的处理次要是完成库或者实例日志到表日志的拆分,对流量日志次要是做一些通用 ETL 处理,由于我们运用的是同一套 PB 结构,对不同 App 数据处理的逻辑代码可以完全复用,这大大降低了我们的开发成本。
汇总层之明细汇总

明细汇总层是由明细层经过 ETL 得到,次要以宽表方式存在。业务明细汇总是由业务理想明细表和维度表 Join 得到,流量明细汇总是由流量日志按业务线拆分和流量维度 Join 得到。流量按业务拆分后可以满足各业务虚时消费的需求,我们在流量拆分这一块做到了自动化,下图演示了流量数据自动切分的过程。
(, 下载次数: 3)


Streaming Proxy 是流量分发模块,它消费下游 ETL 后的全量数据并定期读取埋点元信息,经过将流量数据与元信息数据停止「Join」完成按业务停止流量拆分的逻辑,同时也会对切分后的流量按业务做 ETL 处理。 只需埋点元信息中新增一个埋点,那么这个埋点对应的数据就会自动切分到该业务的 Kafka 中,最终业务 Kafka 中的数据是独属于当前业务的且曾经被通用 ETL 和业务 ETL 处理过,这大大降低了各个业务运用数据的成本。
汇总层之目的汇总

目的汇总层是由明细层或者明细汇总层经过聚合计算得到,这一层产出了绝大部分的实时数仓目的,这也是与实时数仓 1.0 最大的区别。知乎是一个消费内容的平台,对业务目的的汇总我们可以从内容角度和用户角度停止汇总,从内容角度我们可以实时统计内容(内容可以是答案、成绩、文章、视频、想法)的被点赞数、被关注数、被收藏数等目的,从用户角度我可以实时统计用户的粉丝数、回答数、发问数等目的。对流量目的的汇总我们分为各业务目的汇总和全局目的汇总。对各业务目的汇总,我们可以实时统计首页、搜索、视频、想法等业务的卡片曝光数、卡片点击数、CTR 等,对全局目的汇总我们次要以实时会话为主,实时统计一个会话内的 PV 数、卡片曝光数、点击数、阅读深度、会话时长等目的。
目的汇总层的存储选型

不同于明细层和明细汇总层,目的汇总层需求将实时计算好的目的存储起来以供运用层运用。我们根据不同的场景选用了 HBase 和 Redis 作为实时目的的存储引擎。Redis 的场景次要是满足带 Update 操作且 OPS 较高的需求,例如:实时统计全站一切内容(成绩、答案、文章等)的累计 PV 数,由于阅读内容产生大量的 PV 日志,能够高达几万或者几十万每秒,需求对每一条内容的 PV 停止实时累加,这种场景下选用 Redis 更为合适。HBase 的场景次要是满足高频 Append 操作、低频随机读取且目的列较多的需求,例如:每分钟统计一次一切内容的被点赞数、被关注数、被收藏数等目的,将每分钟聚合后的结果行 Append 到 HBase 并不会带来功能和存储量的成绩,但这种状况下 Redis 在存储量上能够会出现瓶颈。
目的计算打通目的系统和可视化系统

目的口径管理依赖目的系统,目的可视化依赖可视化系统,我们经过下图的需求开发过程来讲解如何将三者联络起来。
(, 下载次数: 3)



运用层

运用层次要是运用汇总层数据以满足业务需求。运用层次要分三块:1.经过直接读取目的汇总数据做实时可视化,满足固化的实时报表需求,这部分由实时大盘服务承担;2.引荐算法等业务直接消费明细汇总数据做实时引荐;3.经过 Tranquility 程序实时摄入明细汇总数据到 Druid,满足实时多维即席分析需求。
实时数仓 2.0 中的技术完成

相比实时数仓 1.0 以 Spark Streaming 作为次要完成技术,在实时数仓 2.0 中,我们将 Flink 作为目的汇总层的次要计算框架。Flink 相比 Spark Streaming 有更分明的优势,次要体如今:低延迟、Exactly-once 语义支持、Streaming SQL 支持、形态管理、丰富的工夫类型和窗口计算、CEP 支持等。
我们在实时数仓 2.0 中次要以 Flink 的 Streaming SQL 作为完成方案。运用 Streaming SQL 有以下优点:易于平台化、开发效率高、维度成本低等。目前 Streaming SQL 运用起来也有一些缺陷:1.语法和 Hive SQL 有一定区别,初运用时需求顺应;2.UDF 不如 Hive 丰富,写 UDF 的频率高于 Hive。
实时数仓 2.0 获得的停顿

实时数仓将来展望

从实时数仓 1.0 到 2.0,不管是数据架构还是技术方案,我们在深度和广度上都有了更多的积累。随着公司业务的疾速发展以及新技术的诞生,实时数仓也会不断的迭代优化。短期可预见的我们会从以下方面进一步提升实时数仓的服务才能。





欢迎光临 职贝云数AI新零售门户 (https://www.taojin168.com/cloud/) Powered by Discuz! X3.5