作者介绍: 王天宜,TiDB 社区部门架构师。曾就职于 Fidelity Investment,Softbank Investment,拥有丰富的数据库高可用方案设计经验,对 TiDB、Oracle、PostgreSQL、MySQL 等数据库的高可用架构与数据库生态有深入研究。
数据仓库是公司数据发展到一定规模后必然需要提供的一种基础服务,也是“数据智能”建设的基础环节。早期数仓多为离线模式,主要处理的是 T+1 的数据,随着互联网时代的到来,实时数据处理的场景日益增多,离线数仓已无法满足业务发展的实时性需求。为更好的解决业务场景的实时化需求,实时数仓建设已成必然趋势,这也是 HTAP 数据库的重要能力之一。
实时数仓相较于离线数仓,主要处理的是 T+0 的数据,实时性更高,完美契合业务高效运转的需求。在架构上,实时数仓通常使用 Flink 来消费 Kafka 中的数据,将数据流实时的写入数据库中。这种方案虽然解决了数据处理的时效问题,但很多时候,由于 Kafka 没有落盘机制,可能在极端的情况造成消息队列中数据丢失。
针对上述问题,笔者调研了页面上的数据库与存储引擎,发现了能彻底解决 Kafka 落盘问题的,更高效准确的实时数仓新方案。
首先,**在数据库的选择上,考虑可扩展性更高的分布式数据库 TiDB,从数据库层面解决海量数据存储的问题,其次是分布式流存储引擎 Pravega,解决使用传统消息队列数据丢失问题和自动伸缩难题,提高了实时数仓系统的并行性,可用性与安全性。**以下将详细分析。
Pravega 是一款 DellEMC 开源的流存储项目,并已经进入 CNCF 的 sandbox 阶段。从功能上来看,除与 Apache Kafka、Apache Pulsar 相似,Pravega 提供了 stream、schema registry。除此之外,Pravega 最重要特点是: (1) 无需应用程序感知的自动伸缩能力 (auto-scaling) 和 (2) 是一个完整的存储接口,提供以 stream 为抽象的接口支持上层计算引擎统一的访问。
分布式消息传递一般都基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。提到消息队列,无论如何都无法绕过 Kafka。Kafka 是一个分布式、多分区、多副本、多订阅者,基于 Zookeeper 协调的分布式日志系统。Pravege 是在使用 Kafka 实践中总结出来的新的架构。
Pravega 重构了流式存储的架构。作为流式实时存储的解决方案,应用程序可以直接将数据持久化到 Pravega 中。也正是因为 Pravega 将数据落盘到 HDFS/S3 上,可以不再受限于数据的 retention,并且整个大数据流水线中数据只存储了一份。
作为一个粗浅的 Kafka 使用者,有三个问题使我感到困扰:
丢数据的问题,吃进的数据多,吐出的数据少,offset 提交了,会存在丢数据的风险。
acks = all,只有当所有消费者确认保存了消息时,才会返回 ack,不会丢数据。
acks = 1,当 leader 消费者保存消息就返回 ack,接收的 leader 如果确认后没有来得及备份就挂了,会丢数据。
acks = 0,不等待任何确认,接收方挂掉时会丢数据。
Kafka 数据受限于 retention,没有简单高效的 hdfs/S3 落盘方案。商业版本虽然提供了这个功能,但是数据一旦搬运后,你必须使用2套存储接口混合访问处于不同层级的数据。
引入 flume,可以走 kafka -> flume -> hdfs 的链路。
引入 kafka hadoop loader,可以走 kafka -> kafka hadoop loader -> hdfs 的链路。
引入 kafka-connect-hdfs,可以走 kafka -> kafka-connect-hdfs -> hdfs 的链路。
Consumer rebalance 过程危害甚多。
在 consumer reblance 的过程中可能会因为增加 cunsumer 导致暂停队列的消费。
在 consumer reblance 的过程中可能因为提交间隔长,引发重复消费的问题。
暂停消费和重复消费都有可能导致消息积压,reblance 结束后存在消费突刺的问题。
那么在 Pravega 造轮子的过程中,解决了那些问题呢?以下为 Pravega 与 Kafka 的对比:
Pravega 的特别之处在于,虽然它与不少开源产品一样,也使用 Bookkeeper 去处理并行实时数据低延迟写问题,但是 Bookkeeper 在 Pravega 中只作为数据聚合写(batch write)到 HDFS/S3 的第一阶段(唯一例外是在节点意外故障后做恢复的时候)。所有对 Pravega 读都直接作用到 HDFS/S3 上以利用它们的高吞吐能力。
所以 Pravega 并不把 BookKeeper 当做数据缓存层,而只是提供了一个基于 HDFS/S3 新的存储层用来同时满足“低延时尾读尾写”和“高吞吐追赶读”的抽象。因此,不像大部分使用“分层”设计的项目那样,当数据在 BookKeeper 和 HDFS/S3 之间移动时候性能将无法保证。
大部分的 DBA 或者运维人员最关心的有三件事:数据的正确性,系统的稳定性,以及系统的易用性。数据的正确性是 DBA 的立身之本,数据丢失,数据损坏,数据重复对于公司来说都是巨大的打击;稳定性与易用性解放了 DBA 的双手,让 DBA 从繁复的运维工作中解脱出来,有更多的时间关注与架构选型和系统适配的问题。
从这三点来看,Pravega 确实解决了绝大部分运维人员的痛点问题。Long-term retention 保证了数据的安全,Exactly-Once Semantics 保证了数据的准确性,Auto-scaling 使得维护本身变得轻松。这些特点令人更愿意对 Pravega 进行深一步的调研与适配。
之前,TiDB 5.0 发布后,其 MPP 架构主要是将业务负载切分成若干的任务下推到多个服务器和节点上。在每个结点的计算任务完成后,合并成最终结果交付给用户。在 TiDB 5.0 中,TiFlash 会全面补充 TiDB 的计算能力,TiDB 在 OLAP 场景下就会退化成一个 master 节点。基于 MPP 架构,用户会向 TiDB Server 发送查询 SQL,这个查询 SQL 会由共享的 TiDB 服务器来承担。这些 TiDB 服务器会进行 Join,然后交给优化器去决策。优化器会把使用行存、列存、某些索引、单机引擎、MPP 引擎,或者是使用不同组合产生不同的执行计划,都纳入到同一个代价模型中进行评估,最后选出一个最优的执行方案。
在一些订单交易系统,可能因为促销活动在短时间内迅速达到业务高峰。往往这种瞬时流量高峰需要我们能够快速的进行分析类的查询,从而在限定时间内给出反馈以影响决策。传统的实时数仓架构很难承载短时间内的流量高峰,随之的分析操作可能会需要大量的时间来完成。如果使用传统的计算引擎,可能无法做到秒级的聚合分析操作。有了 MPP 计算引擎,就可以**将能预测的流量高峰转换成扩容的物理成本,做到秒级的响应。**在 MPP 计算引擎的加持下,TiDB 能够更好的处理分析类型的海量数据查询。
实时数仓经历了三个重要的里程碑:
Storm 的出现打破了 MapReduce 的单一计算方式,让业务能够处理 T+0 的数据;
Lambda 到 Kappa 架构的进化,将离线数仓转化为实时数仓;
Flink 的出现给出了批流一体更好的实践方式。
实时数仓的架构一直是在不停变化的。很多时候,当我们刚刚选定一套架构模型的时候,数据仓库的技术栈仍在高速迭代。我们无法预测到 Lambda,Kappa之后会出现什么样的技术架构,但可以通过现在的架构窥探一二。一般来说,我们可以将实时数仓划分为四个部分:实时数据采集端,数据仓库存储层,实时计算层,实时应用层。多技术栈的融合可以帮我们构建一套无边界的大数据基础平台,帮助我们同时支撑分析挖掘,业务上线和批流处理。
随着数字化转型的推进,越来越多企业正面临前所未有的数据规模,随着商业竞争的日趋加剧,无论是外部的用户还是公司内部的决策已经无法依赖时效性不佳的离线数据分析,需要更实时的数据分析,甚至是对正在发生的交易数据进行分析,以支撑更加敏捷的商业决策。
举例来说:
风控场景的最佳效果是防患于未然,所以事前事中和事后三个方案中,以事前预警和和事中控制效果最好。这要求风控系统一定要有实时性。
电商大促期间希望能够平稳及时的监控到销售的情况而非历史数据。
传统上,以 Hadoop 还是分析型数据库为基础的数据分析 / 数据仓库方案都存在着无法良好支持实时分析的障碍;类似 HBase 等 NoSQL 方案虽然可以支持很好的扩展性和实时性,但无法提供所需的分析能力;而传统单机数据库则无法提供数据分析所需的扩展性。
在集成了 TiFlash 之后,TiDB 实现了 OLTP 与 OLAP 的结合,既可以应用于事务性数据库场景,可以应用于分析性数据库场景,也可以在 OLTP 业务中划分出独立的区域完成分析类查询。借助与 Flink,TiDB 可以很好的与 Pravega 适配,提供实时的、高吞吐的、稳定的数仓系统。满足用户在大数据场景中对各类数据的分析需求。
为了方便读者更好的理解,我们在 github tidb-pravega-quick-start 中提供了一个基于 docker-compose 的 Pravega -> Flink -> TiDB 的通路。在 docker-compose 启动后,可以通过 Flink SQL Client 来编写并提交 Flink 任务,并通过 HOST_IP:8081 来观察执行情况。
当前,TiDB + Pravega 构建实时数仓方案面向社区招募体验官!数仓新方案抢先体验,还可额外获取 TiDB 社区及 Pravega 社区精美周边。您在探索实践的过程中有任何问题,社区提供一定技术支持~ 感兴趣的小伙伴,赶快扫码报名吧!
数仓新方案,扫码抢先试用
TiDB 是一款 HTAP 为特点的数据库,定位于在线事务处理/在线分析处理 HTAP(Hybrid Transactional / Analytical Processing)的融合型数据库,具备一键水平伸缩,强一致性的多副本数据安全,分布式事务,实时 HTAP 等重要特性,同时兼容 MySQL 协议和生态,迁移便捷,运维成本低。
相较于其他开源数据库,TiDB 在实时数仓的构建中,既能够用来存储高并发的事务数据,又能应对复杂的分析类查询,对于用户来说无疑是非常友好的。从 4.0 开始,TiDB 引入了 TiFlash 列存引擎,可以将实时业务需求与分析类的需求在存储层中做物理隔离,此外 TiDB 还具备以下优势:
基于行存和列存的 HTAP 架构:
提供完整的索引以及针对明细数据精确定位的高并发访问,满足高 QPS 的点查。
高性能的 MPP 框架以及可更新的列存引擎,在数据进行更新之后,可以实时的同步修改到列存引擎,使得系统可以用分析型数据库的读取性能访问最新数据,满足用户的实时查询需求。
一套入口同时满足 AP 和 TP 需求,优化器会自动根据请求的类型决定是进行TP 类访问,索引选择,还是列存或则 MPP 计算模式,简化架构的复杂度。
弹性扩缩容:对线上环境的 TiDB、PD、TiKV 组件进行灵活便捷的扩缩容而不会对生产环境产生影响,操作透明。
SQL 标准与兼容 MySQL 协议:支持标准的 SQL 语法,包括聚合,JOIN,排序,窗口函数, DML、online DDL 等功能,用户可以通过标准的 SQL 对数据进行灵活的分析运算。
管理简单:使用 TiUP 工具可以快速的完成集群环境的搭建部署;正常运行时不需要依赖其他系统,运维上手简单;提供自带的监控系统,方便进行性能瓶颈分析和问题排查。
另外,在架构上,TiDB 在实时数仓场景中的应用也具备独特优势。
首先,内核设计,TiDB 分布式数据库将整体架构拆分成了多个模块,各模块之间互相通信,组成完整的 TiDB 系统。对应的架构图如下:
TiDB Server:SQL 层,对外暴露 MySQL 协议的连接 endpoint,负责接受客户端的连接,执行 SQL 解析和优化,最终生成分布式执行计划。
PD (Placement Driver) Server:整个 TiDB 集群的元信息管理模块,负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,提供 TiDB Dashboard 管控界面,并为分布式事务分配事务 ID。
存储节点
TiKV Server:负责存储数据,从外部看 TiKV 是一个分布式的提供事务的 Key-Value 存储引擎。存储数据的基本单位是 Region,每个 Region 负责存储一个 Key Range(从 StartKey 到 EndKey 的左闭右开区间)的数据,每个 TiKV 节点会负责多个 Region。
TiFlash:TiFlash 是一类特殊的存储节点。和普通 TiKV 节点不一样的是,在 TiFlash 内部,数据是以列式的形式进行存储,主要的功能是为分析型的场景加速。
其次,TiDB 5.0 通过 TiFlash 节点引入了 MPP 架构这使得大型表连接类查询可以由不同 TiFlash 节点分担共同完成。
当 MPP 模式开启后,TiDB 会通过代价决策是否应该交由 MPP 框架进行计算。MPP 模式下,表连接将通过对 JOIN Key 进行数据计算时重分布(Exchange 操作)的方式把计算压力分摊到各个 TiFlash 执行节点,从而达到加速计算的目的。加上之前 TiFlash 已经支持的聚合计算,MPP 模式下 TiDB 可以将一个查询的计算都下推到 TiFlash MPP 集群,从而借助分布式环境加速整个执行过程,大幅度提升分析查询速度。
Benchmark 测试显示,在 TPC-H 100 的规模下,TiFlash MPP 提供了显著超越 Greenplum,Apache Spark 等传统分析数据库或数据湖上分析引擎的速度。借助这套架构,可以直接针对最新的交易数据进行大规模分析查询,并且性能上能够超越传统离线分析方案。同时,测试结果显示 TiDB 5.0 在同等资源下,MPP 引擎的总体性能是 Greenplum 6.15.0 与 Apache Spark 3.1.1 两到三倍之间,部分查询能达 8 倍性能差异。在数据分析性能上拥有显著优势。