当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢失机制。为了体验这个关键的特性,你需要满足以下几个先决条件:

  1、输入的数据来自可靠的数据源和可靠的接收器;
  2、应用程序的metadata被application的driver持久化了(checkpointed );
  3、启用了WAL特性(Write ahead log)。

  下面我将简单地介绍这些先决条件。

可靠的数据源和可靠的接收器

对于一些输入数据源(比如Kafka),Spark Streaming可以对已经接收的数据进行确认。输入的数据首先被接收器(receivers )所接收,然后存储到Spark中(默认情况下,数据保存到2个执行器中以便进行容错)。数据一旦存储到Spark中,接收器可以对它进行确认(比如,如果消费Kafka里面的数据时可以更新Zookeeper里面的偏移量)。这种机制保证了在接收器突然挂掉的情况下也不会丢失数据:因为数据虽然被接收,但是没有被持久化的情况下是不会发送确认消息的。所以在接收器恢复的时候,数据可以被原端重新发送。

元数据持久化(Metadata checkpointing)

可靠的数据源和接收器可以让我们从接收器挂掉的情况下恢复(或者是接收器运行的Exectuor和服务器挂掉都可以)。但是更棘手的问题是,如果Driver挂掉如何恢复?对此开发者们引入了很多技术来让Driver从失败中恢复。其中一个就是对应用程序的元数据进行Checkpint。利用这个特性,Driver可以将应用程序的重要元数据持久化到可靠的存储中,比如HDFS、S3;然后Driver可以利用这些持久化的数据进行恢复。元数据包括:
  1、配置;
  2、代码;
  3、那些在队列中还没有处理的batch(仅仅保存元数据,而不是这些batch中的数据)
由于有了元数据的Checkpint,所以Driver可以利用他们重构应用程序,而且可以计算出Driver挂掉的时候应用程序执行到什么位置。

可能存在数据丢失的场景

令人惊讶的是,即使是可靠的数据源、可靠的接收器和对元数据进行Checkpint,仍然不足以阻止潜在的数据丢失。我们可以想象出以下的糟糕场景:

  1、两个Exectuor已经从接收器中接收到输入数据,并将它缓存到Exectuor的内存中;
  2、接收器通知输入源数据已经接收;
  3、Exectuor根据应用程序的代码开始处理已经缓存的数据;
  4、这时候Driver突然挂掉了;
  5、从设计的角度看,一旦Driver挂掉之后,它维护的Exectuor也将全部被kill;
  6、既然所有的Exectuor被kill了,所以缓存到它们内存中的数据也将被丢失。结果,这些已经通知数据源但是还没有处理的缓存数据就丢失了;
  7、缓存的时候不可能恢复,因为它们是缓存在Exectuor的内存中,所以数据被丢失了。

这对于很多关键型的应用程序来说非常的糟糕。

WAL(Write ahead log)

为了解决上面提到的糟糕场景,Spark Streaming 1.2开始引入了WAL机制。

  启用了WAL机制,所以已经接收的数据被接收器写入到容错存储中,比如HDFS或者S3。由于采用了WAl机制,Driver可以从失败的点重新读取数据,即使Exectuor中内存的数据已经丢失了。在这个简单的方法下,Spark Streaming提供了一种即使是Driver挂掉也可以避免数据丢失的机制。

At-least-once语义

虽然WAL可以确保数据不丢失,它并不能对所有的数据源保证exactly-once语义。想象一下可能发生在Spark Streaming整合Kafka的糟糕场景。

  1、接收器接收到输入数据,并把它存储到WAL中;
  2、接收器在更新Zookeeper中Kafka的偏移量之前突然挂掉了;

        3、Spark Streaming假设输入数据已成功收到(因为它已经写入到WAL中),然而Kafka认为数据被没有被消费,因为相应的偏移量并没有在Zookeeper中更新;
  4、过了一会,接收器从失败中恢复;
  5、那些被保存到WAL中但未被处理的数据被重新读取;
  6、一旦从WAL中读取所有的数据之后,接收器开始从Kafka中消费数据。因为接收器是采用Kafka的High-Level Consumer API实现的,它开始从Zookeeper当前记录的偏移量开始读取数据,但是因为接收器挂掉的时候偏移量并没有更新到Zookeeper中,所有有一些数据被处理了2次。

WAL的缺点

除了上面描述的场景,WAL还有其他两个不可忽略的缺点:

  1、WAL减少了接收器的吞吐量,因为接受到的数据必须保存到可靠的分布式文件系统中。
  2、对于一些输入源来说,它会重复相同的数据。比如当从Kafka中读取数据,你需要在Kafka的brokers中保存一份数据,而且你还得在Spark Streaming中保存一份。

Kafka direct API

为了解决由WAL引入的性能损失,并且保证 exactly-once 语义,Spark Streaming 1.3中引入了名为Kafka direct API。
  这个想法对于这个特性是非常明智的。Spark driver只需要简单地计算下一个batch需要处理Kafka中偏移量的范围,然后命令Spark Exectuor直接从Kafka相应Topic的分区中消费数据。换句话说,这种方法把Kafka当作成一个文件系统,然后像读文件一样来消费Topic中的数据。
在这个简单但强大的设计中:
  1、不再需要Kafka接收器,Exectuor直接采用Simple Consumer API从Kafka中消费数据。
  2、不再需要WAL机制,我们仍然可以从失败恢复之后从Kafka中重新消费数据;
  3、exactly-once语义得以保存,我们不再从WAL中读取重复的数据。

Spark Streaming和Kafka整合保证数据零丢失的更多相关文章

  1. Spark Streaming消费Kafka Direct方式数据零丢失实现

    使用场景 Spark Streaming实时消费kafka数据的时候,程序停止或者Kafka节点挂掉会导致数据丢失,Spark Streaming也没有设置CheckPoint(据说比较鸡肋,虽然可以 ...

  2. Spark Streaming使用Kafka保证数据零丢失

    来自: https://community.qingcloud.com/topic/344/spark-streaming使用kafka保证数据零丢失 spark streaming从1.2开始提供了 ...

  3. 【转】Spark Streaming和Kafka整合开发指南

    基于Receivers的方法 这个方法使用了Receivers来接收数据.Receivers的实现使用到Kafka高层次的消费者API.对于所有的Receivers,接收到的数据将会保存在Spark ...

  4. Spark Streaming和Kafka整合开发指南(一)

    Apache Kafka是一个分布式的消息发布-订阅系统.可以说,任何实时大数据处理工具缺少与Kafka整合都是不完整的.本文将介绍如何使用Spark Streaming从Kafka中接收数据,这里将 ...

  5. Spark Streaming和Kafka整合开发指南(二)

    在本博客的<Spark Streaming和Kafka整合开发指南(一)>文章中介绍了如何使用基于Receiver的方法使用Spark Streaming从Kafka中接收数据.本文将介绍 ...

  6. Kafka如何保证数据不丢失

    Kafka如何保证数据不丢失 1.生产者数据的不丢失 kafka的ack机制:在kafka发送数据的时候,每次发送消息都会有一个确认反馈机制,确保消息正常的能够被收到,其中状态有0,1,-1. 如果是 ...

  7. [转帖]kafka 如何保证数据不丢失

    kafka 如何保证数据不丢失 https://www.cnblogs.com/MrRightZhao/p/11498952.html   一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数 ...

  8. kafka 如何保证数据不丢失

    一般我们在用到这种消息中件的时候,肯定会考虑要怎样才能保证数据不丢失,在面试中也会问到相关的问题.但凡遇到这种问题,是指3个方面的数据不丢失,即:producer consumer 端数据不丢失  b ...

  9. Spark Streaming和Kafka整合是如何保证数据零丢失

    转载:https://www.iteblog.com/archives/1591.html 当我们正确地部署好Spark Streaming,我们就可以使用Spark Streaming提供的零数据丢 ...

随机推荐

  1. 好好耕耘 redis和memcached的区别

    观点一: 1.Redis和Memcache都是将数据存放在内存中,都是内存数据库.不过memcache还可用于缓存其他东西,例如图片.视频等等: 2.Redis不仅仅支持简单的k/v类型的数据,同时还 ...

  2. 应用TortoiseGit为github账号添加SSH keys,解决pull总是提示输入密码的问题

    每次同步或者上传代码到githun上的代码库时,需要每次都输入用户名和密码,这时我们设置一下SSH key就可以省去这些麻烦了.若果使用TortoiseGit作为github本地管理工具,Tortoi ...

  3. C#基础知识总结(二)

    摘要 第二篇主要讲:变量.连接符占位符等.转义字符.数据的计算.数据的转换.try-catch的简单熟悉.复合运算符和自加自减 一.变量 1.数据存储在内存中:内存叫做RAM,内存被分隔为一小格一小格 ...

  4. JQuery官方学习资料(译):遍历

        一旦你通过JQuery创建了选择器,你就可以对此进行更为深入的遍历.遍历可以分为三个基本组成部分,父节点.子节点和兄弟节点.JQuery为这些部分提供了许多丰富易用的方法. <div c ...

  5. 5. CopyOnWriteArrayList 的适用场景

    package com.gf.demo04; import java.util.ArrayList; import java.util.Collections; import java.util.It ...

  6. vue(四)-vuex与组件联合使用

    官方定义: Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.我的理解就是,vuex就是前端的数据库. 1.首先核心是store,是个仓库,包含着state,因此第一步需要新建一个sto ...

  7. Python国内豆瓣源

    Python国内豆瓣源 https://pypi.doubanio.com/simple/

  8. 浅谈css中的盒模型(框模型)

    css中的盒模型是css的基础,盒模型的理解可以帮助我们进行对样式进行修改.废话不多说,进入正题: 在w3c中,CSS 框模型 (Box Model) 规定了元素框处理元素内容.内边框.边框 和 外边 ...

  9. 我写的Angular相关的文章

    此文正在更新中... Angular6的变化 Angular7的变化 No value accessor for form control with path的解决方案

  10. 使用Visual Studio Team Services敏捷规划和项目组合管理(五)——组合管理

    使用Visual Studio Team Services敏捷规划和项目组合管理(五)--组合管理 组合待办事项为产品所有者提供关于几个敏捷特性团队工作的洞察.产品所有者可以将高优先级的目标定义为Ep ...