什么是kafka?
kafka是分布式发布-订阅消息系统,是一种分布式的消息队列工具
kafka是一个分布式的,可分区的,可复制的消息系统
kafka对消息保存的时候根据topic进行分类,发送消息者称为Producer,消息接受者称为consumer,此外kafka集群由多个kafka实例组成,每个实例称为broker
依赖zookeeper来保证系统的可用性,保存元数据信息
Kafka的设计
1,吞吐量
数据磁盘持久化:消息不在内存中cache,直接写入到磁盘,充分利用磁盘的顺序读写性能
zero-copy:减少IO操作步骤
数据批量发送
数据压缩
Topic划分为多个partition,提高parallelism
2,负载均衡
producer根据用户指定的算法,将消息发送到指定的partition
存在多个partiiton,每个partition有自己的replica,每个replica分布在不同的Broker节点上
多个partition需要选取出lead partition,lead partition负责读写,并由zookeeper负责fail over
通过zookeeper管理broker与consumer的动态加入与离开
3,拉取系统
kafka broker会持久化数据,broker没有内存压力,因此,consumer非常适合采取pull的方式消费数据
consumer根据消费能力自主控制消息拉取速度
consumer根据自身情况自主选择消费模式,例如批量,重复消费,从尾端开始消费等
4,可扩展性
当需要增加broker结点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化,并及时作出调整。
kafka特点
1,高吞吐率
Kafka 每秒可以生产约 25万消息(50 MB),每秒处理 55 万消息(110 MB)
2,持久化数据存储
可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,例如 ETL,以及实时应用程序。通过将数据持久化到硬盘以及 replication 防止数据丢失。
3,分布式系统易于扩展
所有的 producer、broker 和 consumer都会有多个,均为分布式的。无需停机即可扩展机器
4,客户端状态维护
消息被处理的状态是在 consumer 端维护,而不是由 server 端维护。减轻服务器端的压力,为客户端会话管理提供了更好的灵活性。
ETL
Extract-Transform-load 数据抽取,转换和装载,能够完成数据从数据源到目标仓库转换的过程,从而有效的构建起数据仓库
数据抽取
从各种互联网资源、业务系统、各种数据库及数据格式、各种应用中抽取数据。可以看出数据源是异构的,各种关系型和非关系型数据库、半格式化文本文件、CSV文件、XML文件等。这些数据被抽取出来后,暂存于内存中,等待后续处理
数据转换
需要对加载的数据做转换、清洗等处理
数据装载
将转换之后的数据装载到目的库中
概念
1,topic主题
一个topic是对一组消息的归纳
在一个Kafka集群中,可以创建多个topic主题,以topic主题为单位管理消息,kafka中多个topic主题之间是互相隔离互不影响,从而可以在一个Kafka集群中通过创建多个topic主题实现不同的使用者独立使用不同topic主题而互不影响。
2,partition分区
topic可以划分出多个分区,利用分区机制保证每个分区的数据量不会太大, 可以在单个服务器上保存
分区是kafka实现负载均衡和失败恢复分布式数据存储的基本单元
每个分区可以单独发布和消费,为并发操作topic提供了可能
3,offset序号
每个分区都由一系列有序的,不可变的消息组成,这些消息被连续追加到分区中
分区中的每个消息都由一个连续的序列号叫做offset,用来在分区中唯一的标识这个消息
在一个可配置的时间段内,Kafka集群保留所有发布的消息,不管这些消息有没有被消费。
可以设置消息的保存策略,制定保存期限,在期限到来之前,数据会一直存在,无论是否被消费国,当保存期限结束,消息会被连续的擦除,释放空间
一系列的机制保证了kafka当中数据的连续读写磁盘,保证了性能,从而使得kafka的性能与数据量无关,只和磁盘的性能是常量级的
4,Replication复本
每个分区拥有若干复本,这些复本存放在不同的服务器中
若干个副本中,有一个称为leader负责读写操作,而其他的作为Leader,负责同步leader中的数据,对外只提供读的能力
kafka不是以broker为单位划分leader,follwer,而是以副本为单位划分;这样,集群中的每一个broker是持有一部分分区的leader和另一部分分区的follwer,从而将写的压力分摊到不同的broken中取,利用分布式分摊写的压力,提升性能
5,Producer生产者
生产者将消息发布到制定的主题中,默认使用简单的负载均衡机制选择分区,如果需要可以通过特定的分区函数选择分区,制定发布到哪个分区
6,Consumer消费者
Consumer负责消费主题中的数据,消费时由Consumer自己来维护会话产生的数据,实际上每个consumer唯一需要维护的数据是消息在日志中的位置,也就是offset,一般情况下随着Consumer不断的读取消息,这offset的值不断增加,从而实现连续读取数据
7,Broker
集群汇中的一台或多台服务器统称为broker
消费者消费数据的模式
发布订阅模式:多个Consumer可以同时从服务端读取数据,Consumer之间互不影响,每个Consumer都可以读取到全量的数据。达成了多个Consumer之间共享数据的效果。
队列模式:多个Consumer可以同时从服务端读取消息,每个消息只被其中一个Consumer读到。达成多个Consumer之间竞争数据的效果。
8,消费者组的概念
在Kafka中可以将多个消费者组成一个消费者组。
在消费者组内,多个消费者而形成竞争状态,互相抢夺数据。同一份消息只能被一个消费者组内的消费者消费一次。
在消费者组之间,多个消费者形成共享状态,共享数据。同一份消息会同时被多个消费者组各自消费到
Kafka在大数据环境下的优势
分布式存储数据,易于扩展
利用磁盘存储数据,按照主题,分区来分布式的存放数据,持久化存储,提供海量数据的存储能力,数据不会意外的丢失,提供了更好的可靠性,连续读写保证了性能,性能和磁盘的性能有关,和数据量的大小无关
发送数据流程
生产者根据制定的partition方法(round-robin,hash),将消息发布到制定topic的partition中
kafka集群接收到Producer发过来的消息后,将其持久化到硬盘,并保留消息指定时长(可配置),而不关注消息是否被消费
Consumer从kafka中pull数据,并控制获取消息的offset
kafka是pull模式,flume是push模式
Kafka的存储策略
kafka通过topic来分主题存放数据,主题内又有分区,分区还可以有多个副本 。
从物理结构来看,分区本身是kafka存储目录下的一个文件夹,文件夹名称是主题名加分区编号,编号从0开始
分区的内部还有segment的概念,其实就是在分区对应的文件夹下产生的文件,
一个分区会被划分为大小相等的若干个segment,一方面保证了分区的数据被划分到多个文件中(保证了文件的体积不会太大),另一方面可以基于这些segment文件进行历史数据的删除,提高效率
一个segment由一个.log和一个.index文件组成,其中.log文件为数据文件用来存储数据分段数据,.index为索引文件保存对应的.log文件的索引信息
这两个文件的命名规则:partition全局的第一个segment从0开始,后续的每个segment文件名为上一个segment文件的最后一条消息的offset值
通过查找.index文件可以获知每个存储在当前segment中的offset在.log文件中的开始位置
每条日志有固定格式:包括offset编号,日志长度,key的长度,通过这个固定格式的数据可以确定出当前offset的结束位置,从而对数据进行读取
Kafka的可靠性保障AR ISR OSR
1,AR
kafka分区中,维护了一个AR列表,其中包括了所有的分区的副本编号,AR分为ISR和OSR
2,ISR
同步列表,只有当所有的ISR内的副本都同步了leader中的数据,数据才能被提交,才能被消费者访问
3,OSR
非同步列表,OSR内的副本是否同步了leader的数据,不影响数据的提交,OSR内的follower只是尽力的去同步leader,数据版本可能落后。
最开始所有的副本都在ISR中,在kafka工作的过程中,如果某个副本同步速度慢于replica.lag.time.max.ms指定的阈值,则被踢出ISR 存入OSR,如果后续速度恢复可以回到ISR中
这种方案是介于leader独裁和所有民主方式之间,更加的灵活,相对于zookeeper的过半同意过半存活机制,提供了更好的可用性。牺牲了一部分的可靠性,换来的可用性对于kafka这样的消息队列来说很有意义
LEO HW
1,LEO-LogEndOffset
分区的最新的数据的offset,只要有数据写入分区,LEO就指向最新的数据,无论这个数据是否在ISR中同步完成
2,HW-HignWatermark
消费者能够看到的最大的offset,这个offset或者小于这个的offset的数据可以被消费者访问;而大于这个offset的数据,要么不存,要么没有同步完成,外界无法访问
分区同步数据的截断机制
如果leader宕机,选举出新的leader,所有的副本都会讲数据截断到leader之前的hw位,保证所有的副本不会持有未同步完成的数据,这个机制称之为截断机制;此时即使旧的leader恢复,称为follwer,也要先截断数据到宕机之前的hw为,再和新的leader同步数据,保证数据的可靠
截断机制保证了,在leader切换的过程中,数据基于HW保持同步。
Kafka和RabbitMQ的区别
1,架构方面不同
RabbitMQ遵循AMQP协议,RabbitMQ的broker由Exchange,Binding,queue组成,其中exchange和binding组成了消息的路由键;客户端Producer通过连接channel和server进行通信,Consumer从queue获取消息进行消费(长连接,queue有消息会推送到consumer端,consumer循环从输入流读取数据)。rabbitMQ以broker为中心;有消息的确认机制。
kafka遵从一般的MQ结构,producer,broker,consumer,以consumer为中心,消息的消费信息保存的客户端consumer上,consumer根据消费的点,从broker上批量pull数据;无消息确认机制。
2,应用场景
RabbitMQ,循AMQP协议,用于实时的对可靠性要求比较高的消息传递上。
kafka主要用于处理活跃的流式数据,大数据量的数据处理上
3,吞吐量
kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度,消息处理的效率很高
rabbitMQ在吞吐量方面稍逊于kafka,他们的出发点不一样,rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘。
Kafka生产者生产数据的可靠性
生产者向leader发送数据时,可以选择需要的可靠性级别
通过request.required.acks参数设置(0:至多一次,1:至少一次,-1:刚好一次)
0(至多一次):
生产者不停向leader发送数据,而不需要leader反馈成功消息,这种模式效率最高,可靠性最低,可能在发送过程中丢失数据。可能在leader宕机时丢失数据(可能因为网络的不稳定丢失数据。Leader宕机后,宕机期间没有接受到数据,就丢失了)
1(默认,至少一次):
producer在ISR中的leader已成功收到数据并得到确认后才会发送下一条数据,如果等待响应超时,生产者自动重发数据。(不会因为网络不稳定而丢失,但可能在leader宕机而新数据未同步完成时,因新的leader选举后截断未同步数据而造成丢失数据。如果网络不稳定,在重发的过程中,可能会导致多数据)
-1(恰好一次)
producer需要等待ISR中的leader和所有follower都确认接收到数据后才算一次发送完成,才会发送下一条数据,如果等待响应超时,生产者自动重发,数据可靠性最高(效率很低)。
但是这样也不能保证数据完全不丢失,例如当ISR中只有leader时,此时,leader宕机,如果不允许OSR中的follower成为新的leader可以保障写入数据的一致性,但除非原来的leader恢复,否则集群一直无法恢复。或者可以允许OSR列表中的follower成为新的leader,但此时存在写数据不一致的风险。
kafka还提供了min.insync.replicas参数,这个参数要求ISR列表中至少要有指定数量个副本leader才可以接受数据
即使配置request.required.acks=-1,min.insync.replicas=2,也只能保证第二个层面的可靠性,即不丢数据,但仍可能多数据。如果想要实现恰好一次的语义,则需要在这个基础上进一步的加上去重机制
Kafka提供了GUID机制,能够在客户端根据算法为每条日志增加一个全局唯一标识,重发时会保持GUID一致,从而实现了标识每条数据。
分布式系统中的不可能三角-CPA定理
Consistency一致性:分布式环境下,任意时间点中,数据是否一致
Availability可用性:任意节点,是否具有完整的功能
Partition Toleerance分区容忍性:是否可以采用分布式模式,容忍多台机器一起工作
在分布式系统开发中,以上三个特性,最多可以满足两个,同时满足以上三个特性的分布式系统是不可能的。
网友评论