Kafka详解

消息队列内部实现原理

在这里插入图片描述

为什么需要消息队列?

  1. 解耦:允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。利于扩展和维护
  2. 冗余:消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列采用的“插入-获取-删除”范式中,在把一个消息从队列中删除之前,需要你的处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。
  3. 扩展性:因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可。
  4. 灵活性和峰值处理能力:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
  5. 可恢复性:系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程的耦合度,所以使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
  6. 顺序保证:在大多数使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且能保证数据会按照特定的顺序来处理。(kafka保证一个Partition内的消息的有序性)
  7. 缓存:有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
  8. 异步通信:很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放入多少,然后再需要的时候再去处理它们。

Kafka架构图:

在这里插入图片描述
要点:

Kafka和SparkStreaming整合
使用spark-stream-kafka-0.8和spark-stream-kafka-0.10有区别
稳定 实验测试中
receiver DStream 支持 不支持
Direct DStream 支持 支持

receiver:使用连接器(receiver对象)接收数据,使用kafka的高级API,所有的接收器都会从kafka中接收数据。然后把数据存储到Spark executors中(work结点上),然后一个action算子触发job就开始处理数据。
在这里插入图片描述
Receiver通过高级API获取Kafka的数据,一端获取数据,另一端更新offset的值(去zookeeper里更新,自动更新,我们不需要管)。然后Driver启动一个job去处理数据。
最后还会把数据通过WAL机制将数据溢写到磁盘(数据有可能特别大,放不下就溢写,避免丢失数据)。

可靠和不可靠的receiver,可靠通过确认机制,发送确认机制。
确保数据0丢失,开启WAL机制。如果开启 会异步保存从kafka获取的所有数据,存储到HDFS上,然后到分布的文件系统,备份到文件系统。可以从文件系统中恢复数据。

直连模式:重点? 对接就用直连模式获取数据。。。。
首先没有receiver,然后直连是在spark1.3加入进来,接收数据
阶段性的查询kafka的topic对应的最近最新的offset值,然后根据这个offset定义最新的值,拿到一批数据,一批数据相当于某一个范围内的offset对应的消息。
使用的简单API,读从kafka拿到的一批数据,使用底层API,
对比:1.更简单的并行化的。不需要创建更多的输入的kafka流,然后把他们合并的一起,通过SparkStreaming创建许多的RDD分区,和消费的kafka分区一一对应。RDD的 分区数和Kafka的分区数一样。然后会直接同时通过分区读取数据,有一对一的映射,
每一个都对应一个。这是直连模式的核心,一对一的模式。分区对分区 并行度 解决数据

更高效。不需要把数据再备份一次。其实API更复杂 但是更灵活,自动将offset维护到zookeeper。可以实现数据的0丢失,但是会出现数据的重复。(数据已经消费了,但是offset没有更新)第二种方式使用底层的kafkaAPI 可以自己选择将offset写到哪 如mysql
通过事物机制,然后把处理的数据个offset的数据绑定到一起变成一个事物,要么处理成功,要么处理失败。数据同步消费
Exactly-once semantics 处理的数据的逻辑和维护API逻辑的不在一块,会导致数据重复消费。所有我们可以用事物,就不会出现重复消费

首先spark对接kafka拿到最新最近数据的offset值(范围),然后拿这个范围数据进行处理,读数据 分区对分区,图上方得到范围 下方得到读取数据,
看图在这里插入图片描述

Receiver把数据拉去过来缓存到自己的缓冲区中,然后再消费数据。
在这里插入图片描述
解决丢失 开始wal机制 以日志的方式追加到文件中,后期数据丢失就可以恢复
缺点:影响性能。操作起来比较简单,调用的高级api,只需要调用方法就实现了
也不需要手动维护offset值,它默认帮你维护到zookeeper中

dircter 一边拉去数据一边进行消费,调用的kafka的低级api,需要手动维护offset的值。
offset维护到zookeeper中 hbases中 rdies mysql中

只手动维护offset 能保证数据不丢失吗?
ack说的是生产者

保证消费数据的一致性?不丢失不重复—》
如 数据保存到redis中 offset维护到zk中
如果宕机 不是丢失就是重复消费

两种常用方式:
offset的保存过程和数据的保存过程放到一个事物当周
其中有一个失败就都失败啦,这就可以保存一致性

可以在存offset值和数据的时候,将他们绑定到一块
在这里插入图片描述
第三种解决方式 就是不解决。。
这些其实就是幂等机制。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值