Java Web分布式篇之Kafka

Java Web系列文章汇总贴: Java Web知识总结汇总


JMS(Java Message Service)的两种模式

  • 点对点(队列模式):多个消费者读取消息队列,每条消息只发送给一个消费者
  • 发布订阅:多个消费者订阅主题,主题的每条记录会发布给所有的消费者

更多:
消息队列的两种模式


Kafka简介

是什么

0.10版本之前,Kafka仅仅作为一个消息系统,主要用来解决应用解耦、异步消息、流量削峰等问题。0.10版本之后,Kafka提供了连接器与流处理的能力,它从分布式的消息系统逐步成为一个流式的数据平台。
作为一个流式数据平台,Kafka具备下面三个特点:

  • 类似消息系统,提供事件流的发布和订阅
  • 存储事件流数据的节点具有故障容错的特点
  • 能够对实时的事件流进行流式地处理和分析

基本原理

Kafka如何实现上面的三个特点?

  • 1、消息系统,Kafka使用消费组统一了队列&发布订阅两种消息模型,既可以线性扩展消息的处理能力,也允许消息被多个消费组订阅。
  • 2、存储系统,数据写入到Kafka集群的服务节点时,还会复制多份来保证故障时仍然肯用。
  • 3、流处理系统,Kafka提供了完整的流处理API(聚合,连接,转换)等。
  • 4、将以上三个系统组合在一起,既能处理最新的试试数据,也能处理过去的历史数据,流处理平台的核心组件包括:
    A)生产者,发布事件流到Kafka的一个或多个主题
    B)消费者,订阅Kafka的一个或多个主题,并处理事件流
    C)连接器,将Kafka主题和已有数据源连接,支持数据导入和导出
    D)流处理,将主题消费输入流,经过处理,产生输出流到输出主题

Kafka基本概念

  • 主题
  • 消息
  • 分区和副本
  • ISR(In-sync Replica)
  • Leader副本和Follower副本
  • 偏移量
  • 生产者
  • 消费者和消费组

更多:
Kafka简介-《Kafka入门与实践》阅读


Kafka工作流程

 Kafka工作流程图

更多:
Kafka工作流程分析


Kafka模型

分区模型

分区概述

Kafka为每个主题(topic)维护了分布式的分区(partition)日志文件。每个分区都是一个有序的、不可变的记录序列。新的消息不断追加到提交日志中。分区中的每条消息都会按照时间顺序分配到一个单调递增的顺序编号,叫做偏移量(offset),这个偏移量能够唯一定位当前分区中的每一条消息。
Kafka以分区作为最小的粒度,将每个分区分配给消费组中不同且唯一的消费者(一份分区的消息只能被同一个消费组的一个消费者消费,但不同的消费组的不同消费者可以同时消费一个分区的消息)。每个主题有不同的分区,不同的消费者处理不同的分区,一个分区在一个消费组中只有一个消费者的线程在读取,既保证了消费的有序性,也做到了消费者的负载均衡。

分区的意义

  • 方便在集群中扩展,每个Partition可以通过调整以适应它所在的机器,而一个topic又可以有多个Partition组成,因此整个集群就可以适应任意大小的数据了
  • 可以提高并发,因为可以以Partition为单位读写了

分区的原则

  • 指定了patition,则直接使用;
  • 未指定patition但指定key,通过对key的value进行hash出一个patition
  • patition和key都未指定,使用轮询选出一个patition。

消费模型

推还是拉?

消费模式分为推(push)模式和拉(pull)模式。推模式是指由Broker主动推送消息至消费端,实时性较好,不过需要一定的流制机制来确保服务端推送过来的消息不会压垮消费端。而拉模式是指消费端主动向Broker端请求拉取(一般是定时或者定量)消息,实时性较推模式差,但是可以根据自身的处理能力而控制拉取的消息量。

推:

优点:有消息才推送,节省资源,实时性好
缺点:无法得知消费者消费速率,可能压垮消费端;应对多个消费者乏力(消费速率不同);消费代理推送消息,无法保证消费者真正收到消息,并且被消费者消费。

拉:

优点:(Kafka的拉取模型)消费者自己记录消费状态,每个消费者独立顺序读取每个分区的消息,可以按照任意的顺序消费消息,自己控制偏移量,也可以处理已经消费过的消息(Kafka不会根据消息消费状态清理处理,可配置消息过期时间来清理)。
缺点:实时性差,需要不断轮询(可采用阻塞/长轮询解决)

分布式模型

每个分区都会以副本的方式复制到多个消息代理节点上。其中一个节点作为主副本(Leader),负责所有的客户端读写操作,其他节点作为备份副本(Follower),仅仅从主副本同步数据。主副本故障时,备份副本中的一个副本会被选择为新的主副本。
生产者客户端发布消息到服务端的指定主题,会指定消息所属的分区。生产者发布消息时根据消息是否有键,采用不同的分区策略。消息没有键时,通过轮询方式进行客户端负载均衡;消息有键时根据分区语义确保相同键消息总是发送到同一分区。客户端还可以在主题创建后修改主题的分区数量(注:但是分区数量只能变大不能减小 原因参考为什么Kafka中的分区数只能增加不能减少?)。
消费者通过订阅主题来消费消息,并且每个消费者都会设置一个消费组。分区中的一条消息都只会发送给消费组中的一个消费者。分区是消费者线程模型的最小并行单位。增加服务器节点会提升集群的性能,增加消费者数量会提升处理性能。Kafka保证一个分区内消息的完全有序,多个分区不保证,可通过设置一个分区来保证整个topic的有序消费

Kafka生产者

生产者写入消息流程

  • 1)producer先从zookeeper的 “/brokers/…/state”节点找到该partition的leader
  • 2)producer将消息发送给该leader
  • 3)leader将消息写入本地log
  • 4)followers从leader pull消息,写入本地log后向leader发送ACK
  • 5)leader收到所有ISR中的replication的ACK后,增加HW(high watermark,最后commit 的offset)并向producer发送ACK

消息发送流程

消息发送流程

  • 1、ProducerInterceptor对消息进行拦截
  • 2、Serializer对消息的key和value进行序列化
  • 3、Partitioner为消息选择合适的Partition
  • 4、RecordAccumulator收集消息,实现批量发送
  • 5、sender从RecordAccumulator获取消息
  • 6、构造一个ClientRequest,这里是KafkaClient
  • 7、将ClientRequest交给NetworkClient,准备发送
  • 8、NetworkClient将请求放入KafkaChannel的缓存
  • 9、执行网络IO,发送请求
  • 10、收到相应,调用ClientRequest的回调函数
  • 11、调用RecordBatch的回调函数,最终调用每个消息上注册的回调函数

消息追加流程


更多:
Kafka源码剖析 —— 生产者消息追加中的优秀设计与大体流程
kafka 生产者源码分析(一)- 生产者发送消息过程
Kafka发送消息流程

Kafka消费者

消费者模型

消费消息,Kafka提供两种API。

高级API

优点

  • 高级API 写起来简单
  • 不需要自行去管理offset,系统通过zookeeper自行管理。
  • 不需要管理分区,副本等情况,.系统自动管理。
  • 消费者断线会自动根据上一次记录在zookeeper中的offset去接着获取数据(默认设置1分钟更新一下zookeeper中存的offset)
  • 可以使用group来区分对同一个topic 的不同程序访问分离开来(不同的group记录不同的offset,这样不同程序读取同一个topic才不会因为offset互相影响)

缺点

  • 不能自行控制offset(对于某些特殊需求来说)
  • 不能细化控制如分区、副本、zk等

低级API

优点

  • 能够让开发者自己控制offset,想从哪里读取就从哪里读取。
  • 自行控制连接分区,对分区自定义进行负载均衡
  • 对zookeeper的依赖性降低(如:offset不一定非要靠zk存储,自行存储offset即可,比如存在文件或者内存中)

缺点

  • 太过复杂,需要自行控制offset,连接哪个分区,找到分区leader 等。

Kafka设计与实现

文件系统的持久化与数据传输效率

Raid-5顺序存储读取 & 零拷贝技术(sendFile())解决消费者快速消费数据

A、Kafka将数据写到磁盘,充分利用磁盘的顺序读。
B、应用程序----->(文件系统的持久化日志)磁盘缓存------->定期自动刷新到物理磁盘
同时,Kafka在数据写入及数据同步采用了零拷贝(zero-copy)技术(浅析Linux中的零拷贝技术),采用sendFile()函数调用,sendFile()函数是在两个文件描述符之间直接传递数据,完全在内核中操作,从而避免了内核缓冲区与用户缓冲区之间数据的拷贝,操作效率极高。Kafka还支持数据压缩及批量发送,同时Kafka将每个主题划分为多个分区,这一系列的优化及实现方法使得Kafka具有很高的吞吐量。经大多数公司对Kafka应用的验证,Kafka支持每秒数百万级别的消息

生产者发送消息

分区、分批发送,提升效率:将多条消息按照分区进行分组,并采用批量的方式一次发送一个消息集,并且对消息集进行压缩,就可以减少网络传输的带宽,进一步提高数据的传输效率。

生产者&&消费者

(1)、拉取模型保证可重复消费,消费有序
(2)、一个消费组中只有一个消费同一分区数据,状态维护简单,有序消费得到保证

副本机制和容错处理

  • (1)、备份副本的日志文件和主副本的日志总是相同的,都有相同的偏移量和相同顺序的消息
  • (2)、分区的主副本应该均匀的分布到各个服务器,主副本也会跟踪正在同步中的备副本(ISR),如果不存在,则移除。
    节点存活的定义
    1、节点必须与ZK保持回话
    2、如果这个节点是某个分区的备份副本,必须对分区主副本的写操作进行复制,并且复制的进度不能落后太多。
  • (3)、复制到所有ISR完成后,提交的消息才会被消费

ZooKeeper的使用

Kafka重要元数据(分区,偏移量等)采用ZooKeeper存储,保证高可用
利用ZooKeeper进行Leader选举等

更多:
Kafka工作流程分析


MQ对比

Kafka

Kafka是LinkedIn开源的分布式发布-订阅消息系统,目前归属于Apache顶级项目。Kafka主要特点是基于Pull的模式来处理消息消费,追求高吞吐量,一开始的目的就是用于日志收集和传输。0.8版本开始支持复制,不支持事务,对消息的重复、丢失、错误没有严格要求,适合产生大量数据的互联网服务的数据收集业务。

RabbitMQ

RabbitMQ是使用Erlang语言开发的开源消息队列系统,基于AMQP协议来实现。AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。AMQP协议更多用在企业系统内,对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量的要求还在其次。

RocketMQ

RocketMQ是阿里开源的消息中间件,它是纯Java开发,具有高吞吐量、高可用性、适合大规模分布式系统应用的特点。RocketMQ思路起源于Kafka,但并不是Kafka的一个Copy,它对消息的可靠传输及事务性做了优化,目前在阿里集团被广泛应用于交易、充值、流计算、消息推送、日志流式处理、binglog分发等场景。

Kafka与RabbitMQ

Rabbitmq比kafka可靠,kafka更适合IO高吞吐的处理,比如ELK日志收集
Kafka和RabbitMq一样是通用意图消息代理,他们都是以分布式部署为目的。但是他们对消息语义模型的定义的假设是非常不同的。

  • a) 以下场景你比较适合使用Kafka。你有大量的事件(10万以上/秒)、你需要以分区的,顺序的,至少传递成功一次到混杂了在线和打包消费的消费者、你希望能重读消息、你能接受目前是有限的节点级别高可用或则说你并不介意通过论坛/IRC工具得到还在幼儿阶段的软件的支持。
  • b) 以下场景你比较适合使用RabbitMQ。你有较少的事件(2万以上/秒)并且需要通过复杂的路由逻辑去找到消费者、你希望消息传递是可靠的、你并不关心消息传递的顺序、你需要现在就支持集群-节点级别的高可用或则说你需要7*24小时的付费支持(当然也可以通过论坛/IRC工具)。

参考:
Kafka、RabbitMQ、RocketMQ等消息中间件的介绍和对比
消息中间件选型分析——从Kafka与RabbitMQ的对比来看全局
我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比
分布式开放消息系统(RocketMQ)的原理与实践


Kafka知识点

Kafka史上最详细原理总结
Kafka全解析

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值