腾讯看点基于 Flink 的实时数仓及多维实时数据分析实践

当业务发展到必定规模,实时数据仓库是一个必要的基础服务。从数据驱动方面考虑,多维实时数据分析系统的重要性也不言而喻。可是当数据量巨大的状况下,拿腾讯看点来讲,一天上报的数据量达到万亿级的规模,要实现极低延迟的实时计算和亚秒级的多维实时查询是有技术挑战的。前端

本文将介绍信息流场景下,腾讯看点的实时数据仓库和多维实时数据分析系统的技术架构。sql

一、可解决的痛点

能够先看一下,多维实时数据分析系统能够解决哪些痛点。好比:数据库

  • 推荐同窗 10 分钟前上了一个推荐策略,想知道在不一样人群的推荐效果怎么样?
  • 运营同窗想知道,在广东省的用户中,最火的广东地域内容是哪些,方便作地域 Push。
  • 审核同窗想知道,过去 5 分钟,游戏类被举报最多的内容和帐号是哪些?
  • 老板可能想了解,过去 10 分钟有多少用户在看点消费了内容,对消费人群有一个宏观了解。

二、调研

在进行开发以前,咱们作了这些调研。 浏览器

1. 离线数据分析平台可否知足这些需求,结论是不能知足。离线数据分析平台不行的缘由以下。缓存

  • C 侧数据上报过来,须要通过 Spark 的多层离线计算,最终结果出库到 MySQL 或者 ES 提供给离线分析平台查询。这个过程的延时最少 3-6 个小时,目前比较常见的都是提供隔天的查询,因此不少实时性要求高的业务场景都是不能知足的。
  • 另外一个问题是,腾讯看点的数据量太大,带来的不稳定性也比较大,常常会有预料不到的延迟。因此,离线分析平台是没法知足不少需求的。

2. 实时数据分析平台的话,事业群内部提供了准实时数据查询的功能,底层技术用的是 Kudu+Impala,Impala 虽然是 MPP 架构的大数据计算引擎,而且访问以列式存储数据的 Kudu。可是对于实时数据分析场景来讲,查询响应的速度和数据的延迟都仍是比较高,查询一次实时 DAU,返回结果耗时至少几分钟,没法提供良好的交互式用户体验。因此(Kudu+Impala)这种通用大数据处理框架的速度优点更多的是相比(Spark+Hdfs)这种离线分析框架来讲的,对于咱们这个实时性要求更高的场景,是没法知足的。服务器

三、项目背景

通过刚才的介绍,再来看下咱们这个项目的背景。做者发文的内容被内容中心引入,通过内容审核链路,启用或者下架。启用的内容给到推荐系统和运营系统,而后推荐系统和运营系统将内容进行 C 侧分发。内容分发给 C 侧用户以后,用户会产生各类行为,曝光、点击、举报等,经过埋点上报实时接入到消息队列中。接下来咱们作了两部分工做,就是图中有颜色的这两部分。架构

  • 第一部分构建了一个腾讯看点的实时数据仓库。
  • 第二部分就是基于 OLAP 存储引擎,开发了多维实时数据分析系统。

咱们为何要构建实时数仓,由于原始的上报数据量很是大,一天上报峰值就有上万亿条。并且上报格式混乱。缺少内容维度信息、用户画像信息,下游没办法直接使用。而咱们提供的实时数仓,是根据腾讯看点信息流的业务场景,进行了内容维度的关联,用户画像的关联,各类粒度的聚合,下游能够很是方便的使用实时数据。并发

四、方案选型

那就看下咱们多维实时数据分析系统的方案选型,选型咱们对比了行业内的领先方案,选择了最符合咱们业务场景的方案。框架

  • 第一块是实时数仓的选型,咱们选择的是业界比较成熟的 Lambda 架构,他的优势是灵活性高、容错性高、成熟度高和迁移成本低;缺点是实时、离线数据用两套代码,可能会存在一个口径修改了,另外一个没改的问题,咱们天天都有作数据对帐的工做,若是有异常会进行告警。
  • 第二块是实时计算引擎选型,由于 Flink 设计之初就是为了流处理,SparkStreaming 严格来讲仍是微批处理,Strom 用的已经很少了。再看 Flink 具备 Exactly-once 的准确性、轻量级 Checkpoint 容错机制、低延时高吞吐和易用性高的特色,咱们选择了 Flink 做为实时计算引擎。
  • 第三块是实时存储引擎,咱们的要求就是须要有维度索引、支持高并发、预聚合、高性能实时多维 OLAP 查询。能够看到,Hbase、Tdsql 和 ES 都不能知足要求,Druid 有一个缺陷,它是按照时序划分 Segment,没法将同一个内容,存放在同一个 Segment上,计算全局 TopN 只能是近似值,因此咱们选择了最近两年大火的 MPP 数据库引擎 ClickHouse。

五、设计目标与设计难点

咱们多维实时数据分析系统分为三大模块分布式

  1. 实时计算引擎
  2. 实时存储引擎
  3. App层

难点主要在前两个模块:实时计算引擎和实时存储引擎。

  1. 千万级/s 的海量数据如何实时接入,而且进行极低延迟维表关联。
  2. 实时存储引擎如何支持高并发写入、高可用分布式和高性能索引查询,是比较难的。

这几个模块的具体实现,看一下咱们系统的架构设计。

六、架构设计

前端采用的是开源组件 Ant Design,利用了 Nginx 服务器,部署静态页面,并反向代理了浏览器的请求到后台服务器上。

后台服务是基于腾讯自研的 RPC 后台服务框架写的,而且会进行一些二级缓存。

实时数仓部分,分为了接入层、实时计算层和实时数仓存储层。

  • 接入层主要是从千万级/s 的原始消息队列中,拆分出不一样行为数据的微队列,拿看点的视频来讲,拆分事后,数据就只有百万级/s 了;
  • 实时计算层主要负责,多行行为流水数据进行行转列,实时关联用户画像数据和内容维度数据;
  • 实时数仓存储层主要是设计出符合看点业务的,下游好用的实时消息队列。咱们暂时提供了两个消息队列,做为实时数仓的两层。一层 DWM 层是内容 ID-用户ID 粒度聚合的,就是一条数据包含内容 ID-用户ID 还有 B 侧内容数据、C 侧用户数据和用户画像数据;另外一层是 DWS 层,是内容ID粒度聚合的,一条数据包含内容 ID,B 侧数据和 C 侧数据。能够看到内容 ID-用户ID 粒度的消息队列流量进一步减少到十万级/s,内容 ID 粒度的更是万级/s,而且格式更加清晰,维度信息更加丰富。

实时存储部分分为实时写入层、OLAP 存储层和后台接口层。

  • 实时写入层主要是负责 Hash 路由将数据写入;
  • OLAP 存储层利用 MPP 存储引擎,设计符合业务的索引和物化视图,高效存储海量数据;
  • 后台接口层提供高效的多维实时查询接口。

七、实时计算

这个系统最复杂的两块,实时计算和实时存储。

先介绍实时计算部分:分为实时关联和实时数仓。

7.1 实时高性能维表关联

实时维表关联这一块难度在于。百万级/s的实时数据流,若是直接去关联 HBase,1 分钟的数据,关联完 HBase 耗时是小时级的,会致使数据延迟严重。

咱们提出了几个解决方案:

  • 第一个是,在 Flink 实时计算环节,先按照 1 分钟进行了窗口聚合,将窗口内多行行为数据转一行多列的数据格式,通过这一步操做,本来小时级的关联耗时降低到了十几分钟,可是仍是不够的。
  • 第二个是,在访问 HBase 内容以前设置一层 Redis 缓存,由于 1000 条数据访问 HBase 是秒级的,而访问 Redis 是毫秒级的,访问 Redis 的速度基本是访问 HBase 的 1000 倍。为了防止过时的数据浪费缓存,缓存过时时间设置成 24 小时,同时经过监听写 HBase Proxy 来保证缓存的一致性。这样将访问时间从十几分钟变成了秒级。
  • 第三个是,上报过程当中会上报很多很是规内容 ID,这些内容 ID 在内容 HBase中是不存储的,会形成缓存穿透的问题。因此在实时计算的时候,咱们直接过滤掉这些内容 ID,防止缓存穿透,又减小一些时间。
  • 第四个是,由于设置了定时缓存,会引入一个缓存雪崩的问题。为了防止雪崩,咱们在实时计算中,进行了削峰填谷的操做,错开设置缓存的时间。

能够看到,优化先后,数据量从百亿级减小到了十亿级,耗时从小时级减小到了数十秒,减小 99%。

7.2 下游提供服务

实时数仓的难度在于:它处于比较新的领域,而且各个公司各个业务差距比较大,怎么能设计出方便,好用,符合看点业务场景的实时数仓是有难度的。

先看一下实时数仓作了什么,实时数仓对外就是几个消息队列,不一样的消息队列里面存放的就是不一样聚合粒度的实时数据,包括内容 ID、用户ID、C 侧行为数据、B 侧内容维度数据和用户画像数据等。

咱们是怎么搭建实时数仓的,就是上面介绍的实时计算引擎的输出,放到消息队列中保存,能够提供给下游多用户复用。

咱们能够看下,在咱们建设实时数据仓库先后,开发一个实时应用的区别。没有数仓的时候,咱们须要消费千万级/s 的原始队列,进行复杂的数据清洗,而后再进行用户画像关联、内容维度关联,才能拿到符合要求格式的实时数据,开发和扩展的成本都会比较高,若是想开发一个新的应用,又要走一遍这个流程。有了数仓以后,若是想开发内容 ID 粒度的实时应用,就直接申请 TPS 万级/s 的 DWS 层的消息队列。开发成本变低不少,资源消耗小不少,可扩展性也强不少。

看个实际例子,开发咱们系统的实时数据大屏,本来须要进行如上全部操做,才能拿到数据。如今只须要消费 DWS 层消息队列,写一条 Flink SQL 便可,仅消耗 2 个 CPU 核心,1G 内存。

能够看到,以 50 个消费者为例,创建实时数仓先后,下游开发一个实时应用,能够减小 98%的资源消耗。包括计算资源,存储资源,人力成本和开发人员学习接入成本等等。而且消费者越多,节省越多。就拿 Redis 存储这一部分来讲,一个月就能省下上百万人民币。

八、实时存储

介绍完实时计算,再来介绍实时存储。

这块分为三个部分来介绍

  • 第一是 分布式-高可用
  • 第二是 海量数据-写入
  • 第三是 高性能-查询

8.1 分布式-高可用

咱们这里听取的是 Clickhouse 官方的建议,借助 ZK 实现高可用的方案。数据写入一个分片,仅写入一个副本,而后再写 ZK,经过 ZK 告诉同一个分片的其余副本,其余副本再过来拉取数据,保证数据一致性。

这里没有选用消息队列进行数据同步,是由于 ZK 更加轻量级。并且写的时候,任意写一个副本,其它副本都可以经过 ZK 得到一致的数据。并且就算其它节点第一次来获取数据失败了,后面只要发现它跟 ZK 上记录的数据不一致,就会再次尝试获取数据,保证一致性。

8.2 海量数据-写入

数据写入遇到的第一个问题是,海量数据直接写入 Clickhouse 的话,会致使 ZK 的 QPS 过高,解决方案是改用 Batch 方式写入。Batch 设置多大呢,Batch 过小的话缓解不了 ZK 的压力,Batch 也不能太大,否则上游内存压力太大,经过实验,最终咱们选用了大小几十万的 Batch。

第二个问题是,随着数据量的增加,单 QQ 看点的视频内容天天可能写入百亿级的数据,默认方案是写一张分布式表,这就会形成单台机器出现磁盘的瓶颈,尤为是 Clickhouse 底层运用的是 Mergetree,原理相似于 HBase、RocketsDB 的底层 LSM-Tree。在合并的过程当中会存在写放大的问题,加剧磁盘压力。峰值每分钟几千万条数据,写完耗时几十秒,若是正在作 Merge,就会阻塞写入请求,查询也会很是慢。咱们作的两个优化方案:一是对磁盘作 Raid,提高磁盘的 IO;二是在写入以前进行分表,直接分开写入到不一样的分片上,磁盘压力直接变为 1/N。

第三个问题是,虽然咱们写入按照分片进行了划分,可是这里引入了一个分布式系统常见的问题,就是局部的 Top 并不是全局 Top 的问题。好比同一个内容 ID 的数据落在了不一样的分片上,计算全局 Top100 阅读的内容 ID,有一个内容 ID 在分片 1 上是 Top100,可是在其它分片上不是 Top100,致使汇总的时候,会丢失一部分数据,影响最终结果。咱们作的优化是在写入以前加上一层路由,将同一个内容 ID 的记录,所有路由到同一个分片上,解决了该问题。

介绍完写入,下一步介绍 Clickhouse 的高性能存储和查询。

8.3 高性能-存储-查询

Clickhouse 高性能查询的一个关键点是稀疏索引。稀疏索引这个设计就颇有讲究,设计得好能够加速查询,设计很差反而会影响查询效率。我根据咱们的业务场景,由于咱们的查询大部分都是时间和内容 ID 相关的,好比说,某个内容,过去 N 分钟在各我的群表现如何?我按照日期,分钟粒度时间和内容 ID 创建了稀疏索引。针对某个内容的查询,创建稀疏索引以后,能够减小 99%的文件扫描。

还有一个问题就是,咱们如今数据量太大,维度太多。拿 QQ 看点的视频内容来讲,一天流水有上百亿条,有些维度有几百个类别。若是一次性把全部维度进行预聚合,数据量会指数膨胀,查询反而变慢,而且会占用大量内存空间。咱们的优化,针对不一样的维度,创建对应的预聚合物化视图,用空间换时间,这样能够缩短查询的时间。

分布式表查询还会有一个问题,查询单个内容 ID 的信息,分布式表会将查询下发到全部的分片上,而后再返回查询结果进行汇总。实际上,由于作过路由,一个内容 ID 只存在于一个分片上,剩下的分片都在空跑。针对这类查询,咱们的优化是后台按照一样的规则先进行路由,直接查询目标分片,这样减小了 N-1/N 的负载,能够大量缩短查询时间。并且因为咱们是提供的 OLAP 查询,数据知足最终一致性便可,经过主从副本读写分离,能够进一步提高性能。

咱们在后台还作了一个 1 分钟的数据缓存,针对相同条件查询,后台就直接返回了。

8.4 扩容

这里再介绍一下咱们的扩容的方案,调研了业内的一些常见方案。

好比 HBase,原始数据都存放在 HDFS 上,扩容只是 Region Server 扩容,不涉及原始数据的迁移。可是 Clickhouse 的每一个分片数据都是在本地,是一个比较底层存储引擎,不能像 HBase 那样方便扩容。

Redis 是哈希槽这种相似一致性哈希的方式,是比较经典分布式缓存的方案。Redis slot 在 Rehash 的过程当中虽然存在短暂的 ask 读不可用,可是整体来讲迁移是比较方便的,从原 h[0]迁移到 h[1],最后再删除 h[0]。可是 Clickhouse 大部分都是 OLAP 批量查询,不是点查,并且因为列式存储,不支持删除的特性,一致性哈希的方案不是很适合。

目前扩容的方案是,另外消费一份数据,写入新 Clickhouse 集群,两个集群一块儿跑一段时间,由于实时数据就保存 3 天,等 3 天以后,后台服务直接访问新集群。

九、成果

腾讯看点实时数据仓库:DWM 层和 DWS 层,数据延迟 1 分钟。

远见多维实时数据分析系统:亚秒级响应多维条件查询请求,在未命中缓存状况下,过去 30 分钟的查询,99%的请求耗时在 1 秒内;过去 24 小时的查询,90%的请求耗时在 5 秒内,99%的请求耗时在 10 秒内。

相关文章
相关标签/搜索