如何保障流式处理的数据一致性

简介:

背景

相对于传统的Hadoop这样的batch分析平台,流式分析的优点就是实时性, 即可以在秒级别延迟上得到分析结果 。 
当然缺点是, 很难保证强一致性,即Exactly-Once语义 (在海量数据的前提下,为了保障吞吐量,无法使用类似事务的强一致性的方案)。 
一般流式分析平台都会promise较弱的一致性,即Least-Once语义,保证数据不丢但允许数据重复。

但这只是在正常的情况下,当流式分析的任一环节发生故障,整个流被堵塞时,会导致层层队列被打满,最终仍然是会丢数据的。

所以对于流式分析平台,如果要保证一致性,必须借助外部的Replay的能力。

Lamda架构

Storm的作者Nathan在How to beat the CAP theorem文中提出著名的Lamda架构来解决实时系统的一致性问题。

原理其实很简单,既然流式分析没法保证一致性,那么我们就用Hadoop存全量数据,通过batch数据分析来保证强一致性。 
流式分析只用来计算实时热数据,而冷数据由离线计算来做,用户查询的时候,只需要把两份数据做下merge。

image

从严格意义上讲,这个不能算beat CAP,因为只是结合Batch分析的强一致性和流式分析的高可用性而形成的架构。 
但确实给流式分析如何保证一致性,提出了一个非常有建设性的方案。

Lamda架构的缺陷也很明显,太复杂,太重,需要搭建实时和离线两套系统,对运维而言成本过高。 
更麻烦的是,分析逻辑需要实现两次,虽然现在有类似Summingbird这样的方案,但还是比较理想化,面对海量数据的现实,还是很骨感的。

Linkedin的架构

针对这个问题,Linkedin的架构师Jay Kreps在Questioning the Lambda Architecture文中,提出一种单纯基于Kakfa和流式分析的架构,

image

原理也不复杂,就是充分利用Kafka的replay能力,只要磁盘足够,用kafka可以保存足够久的数据 。 
并且由于kafka的数据存在磁盘上,是可以被重复读取的,这也是Kafka在流式场景下更优于其他队列中间件的原因。

1. 用流式job_n去实时计算热数据,结果存入table_n,可以用于用户实时查询 。 
2. 在需要的时候(发生故障数据部分丢失或处理逻辑发生变化)开启流式job_n+1来处理全量数据,存入table_n+1,当数据catch up的时候,把用户流量切到table_n+1 。 
3. 删除job_n和table_n。

这个架构比较轻,并且确实可以在很大程度上解决流式分析平台的一致性问题,也可以用做参考。

 

Tradeoff方案

但是对于我们的场景,这个方法太理想化:

原因是数据量太大,存储7天的日志需要近2PB的磁盘空间(kafka需要做replica)。

如果要在可接受时间范围内replay完这些数据,所需要的分析资源也是很难满足。

并且线上业务做数据源的切换也不是那么简单的事。

所以我们的思路是,补全丢失的数据,而非replay全量数据。

image

步骤1. 重置线上job至kafka latest offset,读最新的数据。 
用线上Job去补旧数据,会很影响用户的体验,因为实时流量本身就很大,catchup的速度会比较慢,会导致用户长时间看不到最新日志。

步骤2. 找出需要补全数据。 
这步方法有很多,我们的方法是, 
用monitorBolt提供实时业务监控,我们可以知道服务什么时候异常,什么时候恢复(秒级别)。

步骤3. 启动Catchup Job,从earliest offset开始读。 
通过配置在处理bolt里设置时间过滤条件,只处理规定时间范围内的数据,其余的数据全部丢弃。

步骤4. 数据恢复后,停止Catchup Job。

这个方案可以解决数据不丢的需求,当然这个方案也并不完美,问题如下,

1. 无法保证Exactly-Once,只能保证Least-Once 
因为发生异常的10小时中,还是有比较少量的日志数据是被成功写入的, replay时,这部分数据会重复。

2. 读取了部分不需要被replay的数据 
为了简单处理,我们的catchup Job是从earliest offset开始读的,并在业务bolt里面进行过滤。 
更好的方式,是定期在kafkaspout中对已处理的offset做checkpoint(比如分钟级别), 
然后恢复的时候,可以从某个checkpoint开始读,这样更精确些,但方案上会复杂很多。

我们最终通过这种方案找回了丢失的用户Sql日志,可以作为一种思路给大家借鉴。

总结

CAP理论对于流式处理仍然奏效,并没有被beat。 
对于流式处理这样强调高数据可用性的场景,要保证数据的强一致性是需要依赖于外部系统的Replay能力的,并且对于海量数据是要付出很大的资源代价的(存储和处理)。

实战中,我们通过一定tradeoff,可以做到在有限资源的情况下,保证流式处理中发生故障时,仍然可以保证Least-Once的一致性。


本文章摘自博客园,原文发布日期:2015-07-30

目录
相关文章
|
2月前
|
算法 关系型数据库 MySQL
TiDB保证数据一致性的策略与优势
【2月更文挑战第28天】TiDB作为一款分布式数据库,通过其独特的策略和优势,确保在分布式环境下数据的一致性。本章将详细探讨TiDB保证数据一致性的核心策略,包括其采用的分布式一致性协议、数据复制机制以及容错处理等方面,并阐述这些策略所带来的优势。通过理解TiDB的数据一致性保证机制,读者将能更深入地认识其作为分布式数据库的价值。
|
2月前
|
算法 大数据 数据库
数据库事务:保障数据一致性的基石
数据库事务:保障数据一致性的基石
|
消息中间件 存储 SQL
跨系统数据一致性方案的思考(上)
本文主要意在总结沉淀现有问题解决经验过程,整理解决跨系统数据不一致问题的经验方法。 跨系统数据一致性,比较优秀的解决方案就是微服务化,不同应用系统采用统一数据源方式,这样可以有效避免数据一致性问题。 但是我们很多系统由于历史原因或者业务缘由,导致非服务化情况下,又要采取数据一致性方案。
跨系统数据一致性方案的思考(上)
|
4月前
|
消息中间件 存储 Java
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的低延迟可用性机制方案实现
在充满挑战的2023年度,我们不可避免地面对了一系列棘手的问题,例如响应速度缓慢、系统陷入雪崩状态、用户遭受不佳的体验以及交易量的下滑。这些问题的出现,严重影响了我们的业务运行和用户满意度,为了应对这些问题,我们所在团队进行了大量的研究和实践,提出了低延迟高可用的解决方案,并在分布式存储领域广泛应用。
50 2
【亿级数据专题】「分布式消息引擎」 盘点本年度我们探索服务的低延迟可用性机制方案实现
|
26天前
|
监控 中间件 UED
中间件数据传输数据一致性
中间件在跨系统数据传输中确保一致性至关重要,采用事务处理、数据校验和验证、分布式一致性协议(如Raft、Paxos)、数据复制与同步、错误处理及重试机制、监控日志记录和选择合适的一致性级别(如强一致或最终一致)等策略,能有效提高传输的可靠性和数据一致性。
16 2
|
2月前
|
存储 监控 容灾
TiDB存储层深入:分布式存储架构与数据一致性保障
【2月更文挑战第26天】本文将深入探讨TiDB的存储层,详细解析其分布式存储架构、数据复制机制以及数据一致性保障措施。通过了解存储层的核心组件和工作原理,我们可以更好地理解TiDB如何确保数据的可靠性、高可用性和可扩展性。本文将从存储层的架构、数据分布、容错机制等方面展开介绍,帮助读者全面掌握TiDB存储层的关键技术和优势。
|
5月前
|
安全
Hologres中,为了保障数据的安全性和稳定性
Hologres中,为了保障数据的安全性和稳定性
29 2
|
9月前
|
存储 关系型数据库 MySQL
如何实现基于Flink的高吞吐、精确一致性数据入湖
APS(ADB Pipeline Service)简介:ADB湖仓版在深化自身湖仓能力建设的同时,还推出了APS(ADB Pipeline Service)数据通道组件,为客户提供实时数据流服务实现数据低成本、低延迟入湖入仓。本文以数据源SLS如何通过APS实现高速精确一致性入湖为例,介绍相关的挑战和解决方法。
|
11月前
|
存储 缓存 文件存储
如何保证分布式文件系统的数据一致性
分布式文件系统需要向上层应用提供透明的客户端缓存,从而缓解网络延时现象,更好地支持客户端性能水平扩展,同时也降低对文件服务器的访问压力。当考虑客户端缓存的时候,由于在客户端上引入了多个本地数据副本(Replica),就相应地需要提供客户端对数据访问的全局数据一致性。
31167 66
如何保证分布式文件系统的数据一致性
|
11月前
|
分布式计算 Java
数据可靠性与一致性:分布式事务处理的挑战与解决方案
在分布式系统中,确保数据的可靠性和一致性是一项重要且具有挑战性的任务。随着分布式计算的普及,开发人员面临着处理跨多个节点和服务的分布式事务的问题。本文将介绍分布式事务处理中的挑战,并探讨一些常见的解决方案。
211 0