如何保障流式处理的数据一致性
背景
相对于传统的Hadoop这样的batch分析平台,流式分析的优点就是实时性, 即可以在秒级别延迟上得到分析结果 。
当然缺点是, 很难保证强一致性,即Exactly-Once语义 (在海量数据的前提下,为了保障吞吐量,无法使用类似事务的强一致性的方案)。
一般流式分析平台都会promise较弱的一致性,即Least-Once语义,保证数据不丢但允许数据重复。
但这只是在正常的情况下,当流式分析的任一环节发生故障,整个流被堵塞时,会导致层层队列被打满,最终仍然是会丢数据的。
所以对于流式分析平台,如果要保证一致性,必须借助外部的Replay的能力。
Lamda架构
Storm的作者Nathan在How to beat the CAP theorem文中提出著名的Lamda架构来解决实时系统的一致性问题。
原理其实很简单,既然流式分析没法保证一致性,那么我们就用Hadoop存全量数据,通过batch数据分析来保证强一致性。
流式分析只用来计算实时热数据,而冷数据由离线计算来做,用户查询的时候,只需要把两份数据做下merge。
从严格意义上讲,这个不能算beat CAP,因为只是结合Batch分析的强一致性和流式分析的高可用性而形成的架构。
但确实给流式分析如何保证一致性,提出了一个非常有建设性的方案。
Lamda架构的缺陷也很明显,太复杂,太重,需要搭建实时和离线两套系统,对运维而言成本过高。
更麻烦的是,分析逻辑需要实现两次,虽然现在有类似Summingbird这样的方案,但还是比较理想化,面对海量数据的现实,还是很骨感的。
Linkedin的架构
针对这个问题,Linkedin的架构师Jay Kreps在Questioning the Lambda Architecture文中,提出一种单纯基于Kakfa和流式分析的架构,
原理也不复杂,就是充分利用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全量数据。
步骤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
相关文章
- 大数据在互联网时代的意义!
- 二次供水远程监测
- 【ES三周年】集群半数以上master节点掉线解决方法
- 一文带你看透天气预报
- 生信课程note-1
- 数据分享|Python决策树、随机森林、朴素贝叶斯、KNN(K-最近邻居)分类分析银行拉新活动挖掘潜在贷款客户|附代码数据
- 电脑数据丢失如何找回?有哪些免费的数据恢复软件
- 【ES三周年】初识ES的特点以及应用场景
- 量子可视化编程软件介绍
- 学习分享(第 1 期)之 Redis:巧用 Hash 类型节省内存
- 大数据NiFi(十四):数据来源和变量及表达式
- 大数据必知必会:Hadoop(2)伪分布式安装
- 为什么说六西格玛不仅仅是数据运算?
- 面向面试编程连载(一)
- 【ES三周年】结合ilm的方式实现滚动索引
- 工程监测仪器振弦模拟信号采集仪VTN的用户接口
- 深圳锐宝智联纳入ODM Uplift计划,共推行业智能化升级
- 深度解析:元宇宙养殖农业DAPP系统开发逻辑详细方案
- 使用 NineData 快速构建企业容灾备份
- TiCDC 源码阅读(四)TiCDC Scheduler 工作原理解析