写点什么

关于大规模实时数仓搭建,我有几条心得...

2021 年 7 月 30 日

关于大规模实时数仓搭建,我有几条心得...

现状

闲鱼作为一款闲置交易 APP,在二手交易市场中是当之无愧的佼佼者。闲鱼从 2014 年诞生到现在七整年间持续增长,在这高速增长的背后带来的是每天近百亿的曝光点击浏览等数据,在这些数据规模如此庞大的背后也会带来诸多关于实时性的问题:

  • 用户反馈商品曝光异常,如何快速定位?

  • 产品同学圈了一批商品,如何查看该样本的实时报表?

  • 发现问题总是晚一步,如何在第一时间获取自定义的预警信息?   

  •  ......

为了解决上述的这些问题,我们开始了打造闲鱼实时数仓的探索之路。

预研

数仓调研

在开始设计闲鱼的实时数据仓库之前,我们也调研了集团内外的各种数据仓库的设计与架构,一些是比较老的架构设计,另外一些是由于技术突破后进而带来的创新性的解决方案。本文不妨将这些实时数据仓库的新老设计做一下分类:


  • 第一类:从无到有

当 Apache Storm(开源的分布式实时计算系统)问世后,大数据不在依靠 MapReduce 这种单一的计算方式,拥有了当日数据当日处理的能力。

  • 第二类:从有到全

以 Lambda 和 Kappa 为代表的架构,能够将实时与离线架构结合在一起,一套产品可以实现多种数据更新策略。

  • 第三类:从全到简

以 Flink 为代表的支持窗口计算的流式框架出现,使离线和实时的逻辑能够统一起来,一套代码实现两种更新策略,避免了因为开发方式不统一导致的数据不一致问题。

  • 第四类:架构走向工具

以 Hologres 为代表的 HSAP(Hybrid Serving/Analytical Processing)引擎,用服务分析一体化的设计理念,统一分析型数据库和业务数据库,再配合 Flink,真正实现数仓的彻底实时化。

首先我们摒弃了比较古老的方案,由于现在的技术创新非常快,涌现出很多优秀的产品可供我们去使用,另外基于闲鱼自身的业务需求,最终选择了 Hologres[1]+Blink[2]来构建实时数据仓库。

数据模型

不管是从计算成本,易用性,复用性,还是一致性等方面,我们都必须避免烟囱式的开发模式,而是以中间层的方式去建设实时数仓,烟囱式架构有很大弊端,它无法与其他系统进行有效协调工作,不利于业务沉淀,而且后期维护成本非常大。下图展示了闲鱼实时数仓的数据模型设计架构图。


null


从上图可以看出我们将实时数仓的数据模型分为 4 层,自底向上依次为 ODS、DWD、DWS 和 ADS。通过多层设计可以将处理数据的流程沉淀在各层完成。比如在数据明细层统一完成数据的过滤、清洗、规范、脱敏流程;在数据汇总层加工共性的多维指标汇总数据,提高了代码的复用率和整体生产效率。同时各层级处理的任务类型相似,可以采用统一的技术方案优化性能,使数仓技术架构更简洁。下面对这四层进行简单的介绍:


  • ODS(Operational Data Store): 贴源层

这一层又叫做贴源层,最为接近数据源的一层,需要存储的数据量是最大的,存储的数据也是最原始。对众多数据源而言,他们的数据格式基本不一致,经过统一规格化后可以得到规整的数据,将数据源中的数据经过抽取、清洗、传输后装入 ODS 层。

  • DWD(Data Warehouse Detail):数据明细层

业务层与数据仓库的隔离层,主要对 ODS 层做一些数据清洗和规范化的操作,并且可以按照不同的行为维度对数据进行划分,例如本文对数据源就进行了划分,主要分为浏览、曝光、点击、交易等不同的维度,这些不同的维度能够对上层调用方提供更细粒度的数据服务。

  • DWS(Data WareHouse Servce):数据服务层

对各个域进行了适度汇总,主要以数据域+业务域的理念建设公共汇总层,与离线数仓不同的是,实时数仓的汇总层分为轻度汇总层和高度汇总层,例如将轻度汇总层数据写入 ADS,用于前端产品复杂的 OLAP 查询场景,满足自助分析和产出报表的需求。

  • ADS(Application Data Store):应用数据服务层

主要是为了具体需求而构建的应用层,通过 RPC 框架对外提供服务,例如本文中提到的数据报表分析与展示、监控告警、流量调控、开放平台等应用。

  • DIM(Dimension):维表

在实时计算中非常重要,也是重点维护的部分,维表需要实时更新,且下游基于最新的维表进行计算,例如闲鱼的实时数仓维表会用到闲鱼商品表、闲鱼用户表、人群表、场景表、分桶表等。

方案实现

整体架构

上面对闲鱼实时数仓的数据模型进行了解剖并详细地介绍了模型的各层次设计思想和实际运用。下面是根据数据模型构建的技术架构图,共分为五个层次,自底向上分别为数据源、数据接入层、数据计算层、数据服务层和应用层。


null


数据源是整个实时数仓的底座,闲鱼拥有众多场景,例如首页推荐、猜你喜欢、搜索等,在这些场景中会有不同的用户行为,用户产生的曝光、点击、浏览等行为日志会被上层存储工具收集。如上图中的数据接入层,可以将数据源接入到 UT[3]日志、黄金令箭、数据备库或服务端日志中存储。数据清洗与规整是构建实时数仓的核心过程,数据计算层利用 Blink 的实时处理能力将不同格式的数据统一清洗、补充和规整后存入 TT[4]中。数据服务层是实时数仓的网关层,将实时数据进行逻辑处理后对外提供数据服务和 API 网关能力。应用层是最贴近用户的层次,这一层是为了具体需求而构建的,可以对各个维度数据进行实时报表展示,对线上异常流量监控告警,对商品域进行流量调控,还可供其他应用开放相关接口等。

技术难点

整体的技术架构如上图所示,构建实时数仓的关键是实时数据处理以及实时交互的能力,闲鱼每日产生近百亿的埋点数据以及服务器日志,在构建实时数仓有以下关键难点:


  • 数据量大,需要处理的埋点数据以及服务器日志达百亿。

  • 实时性能要求高,监控告警需要较高的实时性。

  • 分析交互需求强,数据分析场景复杂且交互频繁。

  • 异构数据源多,闲鱼各个系统模块产生各类格式的数据。


首先如何能够即稳定又高效地处理数据是我们亟待解决的问题,在面临海量数据计算处理时,我们选用了集团内部的流式计算框架 Blink,它是基于开源框架 Flink 的再封装的新一代流式计算引擎,经过多年双 11 的考验,其实时计算能力对我们系统来说是毋庸置疑的。我们在做实时报表展示时结合性能和实际情况,会对实时数据进行分钟级别的数据聚合,通过 Blink 提供的滚动窗口聚合就能够高效地解决该问题。滚动窗口将每个元素分配到一个指定窗口大小的窗口中,滚动窗口有一个固定的大小,并且不会出现重叠。例如:如果指定了一个 1 分钟大小的滚动窗口,那么无限流的数据会根据时间划分成[0:00 - 0:01), [0:01, 0:02), [0:02, 0:03)... 等窗口,滚动窗口划分形式如下图所示。


null

我们在编写分钟级别的 Blink 任务时,只需要在 GROUP BY 子句中定义滚动窗口即可,伪代码如下:

GROUP BY TUMBLE(<time-attr>, <size-interval>)
复制代码

上述 SQL 中的参数必须是流中的一个合法的时间属性字段,有两种类型:processing time 或是 event time。


• Event Time:用户提供的事件时间(通常是数据的最原始的创建时间),event time 一定是用户提供在表的 schema 里的数据。

• Processing Time:表示系统对事件进行处理的本地系统时间,单位为毫秒。


根据项目实际情况,因为我们聚合的是埋点事件当时的数据,所以选择使用 Event Time,选择该类型时间的另一好处是在重跑某个时间段的任务时也能够保持结果的一致性。


通过 Blink 的这个法宝我们能够高效实时地处理海量数据,那在面临数据分析场景复杂并且交互非常频繁的这种情况下,我们又如何去避免传统 OLAP 的存储计算弊端呢?在寻找实时的并且兼并服务/分析一体化的系统工具时我们发现了一款利器,它就是 Hologres(Holographic+Postgres),它支持对万亿级数据进行高并发低延时多维分析透视和业务探索,可以轻松而且经济的使用现有 BI 工具分析所有数据,在面临 PB 级数据时依然能够保持秒级响应的能力,并且简单易用,能够快速上手。Hologres 是基于存储计算分离的设计模式而构建的,数据全部存在一个分布式文件系统中,存储引擎的总体架构如下图所示:


null

每个分片(shard)构成了一个存储管理和恢复的单元(recovery unit),上图展示了一个分片的基本架构,一个分片由多个 tablet 组成,这些 tablet 会共享一个日志(Write-Ahead Log,简称 WAL,所有的新数据都是以 append-only 的形式插入的。当写操作不断进来,每个 tablet 里会积累出很多文件。当一个 tablet 里小文件积累到一定数量时,存储引擎会在后台把小文件合并起来,能减少使用系统资源且合并后的文件减少了,提高了读的性能,为实时高效分析提供了可能性。


上面详细描述了海量数据的实时处理、数据存储以及分析的解决方案,那在面对异构数据源接入又是如何处理的呢?闲鱼由于场景众多,业务复杂,在处理异构数据源时我们采用领域维度统计的方式,将不同领域的各类数据源字段统一化,在 Blink 清洗数据时会结合场景、人群、分桶等维度信息来解决异构数据源的问题。


null


由上图可知,领域模块主要分为流量域、用户域、交易域、互动域等,每个领域中都会抽象出相应的对象,例如流量域中有商品、广告和运营投放;用户域中有用户、设备、卖家和买家;交易域中有询单、成交、GMV;互动域中有收藏、超赞和评论。在设计异构数据源的解决方案时也考虑到后面打造开放平台的需求,所以将数据接入层抽象成不同领域的接口对外提供接入服务并且在应用层也开放了各个维度的统计接口。这样对有接入实时数仓的业务需求时可以通过数据层和应用层开放的抽象接口快速接入,不用考虑整个链路中间的细节,能够极大地减少开发周期。

阶段性成果

本文中所构建的实时数仓在实时报表,曝光异常反馈等方面有所应用,通过平台可以实时地浏览系统大盘、首页、猜你喜欢、搜索等场景的各个维度数据,提升了闲鱼各个场景的实时数据的丰富度。目前通过实时数仓的应用,也取得了一些成果:

  • 能够实时评估线上策略的最终效果;

  • 能够快速排查定位用户反馈的曝光异常问题;

  • 能够给产品同学提供圈品后的实时报表信息等等。


null

展望

目前我们对实时数仓的开发还处于初期阶段,后续我们会加大力度投入研发,使实时数仓在更多的场景应用起来,打造一个实时、全面、稳定的流量应用平台。后期我们将会在以下几个方面深挖和优化:

• 与集团内的其他监控告警平台对接,使得在本平台内不仅能够更细粒度地监控各个场景的商品流量异常情况,而且能够收获一个拥有监控、预警、定位、自修复一站式的安保平台。

• 打造实时数仓的开放平台提供给其他团队使用,能够节约更多的人力资源和开发周期。


注释:

[1] Hologres: Hologres 是阿里巴巴自主研发的一款交互式分析产品,兼容 PostgreSQL 11 协议,与大数据生态无缝连接,支持高并发和低延时地分析处理 PB 级数据。

[2] Blink:Blink 是阿里巴巴实时计算部通过改进开源 Apache Flink 项目而创建的阿里内部产品。

[3] UT:UserTrack 主要指无线端 APP 的各种用户行为操作日志,是所有基于用户行为分析的运营报表的基础。

[4] TT:TimeTunnel 是一个高效的、可靠的、可扩展的消息通信平台。


本文转载自:闲鱼技术(ID:XYtech_Alibaba)

原文链接:关于大规模实时数仓搭建,我有几条心得...

2021 年 7 月 30 日 08:00808

评论

发布
暂无评论
发现更多内容

大作业

Geek_2e7dd7

为什么区块链能成为全球贸易的助推器

CECBC区块链专委会

区块链 金融 国际贸易

测试

云龙

测试

直播风口,是什么在支撑教育、电商、泛娱乐等场景?

腾讯云音视频

腾讯云 音视频 云直播 点播

架构师课程大作业 知识图谱

杉松壁

Http请求中如何保持状态?

架构师修行之路

欧洲央行近期将决定是否建立官方数字货币

CECBC区块链专委会

数字货币 欧央行

高并发系列——CAS操作及CPU底层操作解析

诸葛小猿

CAS AtomicInteger compareAndSwap cmpxchg lock

Spring IoC 到底是什么?

小齐本齐

spring 程序员 ioc Spring Framework Spring Bean

随想之乐观估计

云杉

你需要开始做点什么,否则你会一直忙一直忙

老胡爱分享

学习 思维方式 行动派 随笔杂谈 拖延症

Spring事务是如何应用到你的业务场景中的?

AI乔治

Java spring 架构 微服务 springboot

Spring 5 中文解析测试篇-WebTestClient

青年IT男

单元测试 Spring5

中国云计算的云栖“坐标”

脑极体

SpringBoot RabbitMQ消息队列的重试、超时、延时、死信队列

Barry的异想世界

RabbitMQ springboot 消息队列 死信队列 延时队列

Flink SQL CDC 上线!我们总结了 13 条生产实践经验

Apache Flink

flink

前端必会的七种排序算法

执鸢者

算法 前端

解决分布式session问题

架构师修行之路

分布式 架构设计 session

理财专题一

TCA

C/C++基础之sizeof使用

C语言与CPP编程

c c++ 编程 编程语言

STL总结与常见面试题

C语言与CPP编程

c c++ 编程 编程语言 stl

甲方日常 14

句子

Java 工作 随笔杂谈 日常

SwiftGG 文档翻译笔记1-基础部分函数闭包

组合模式

基于 Flink 的典型 ETL 场景实现方案

Apache Flink

flink

RabbitMQ 重要概念介绍

hepingfly

Java RabbitMQ 消息队列 JMS

2020英特尔大师挑战赛携手华硕ROG激战成都

新闻科技资讯

你还在手撕微服务?快试试 go-zero 的微服务自动生成

万俊峰Kevin

go 微服务 microservice go-zero 微服务框架

非科班进大厂必备算法

我是程序员小贱

面试 算法

LeetCode题解:1. 两数之和,Map+队列+双指针,JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

MySQL 核心特性与优化

MySQL 核心特性与优化

关于大规模实时数仓搭建,我有几条心得...-InfoQ