Kafka深度剖析

Kafka简介

Kafka概述:

Kafka由 linked-in 开源 。
kafka-高产出的分布式消息系统(A high-throughput distributed messaging system)。
Kafka是一个高吞吐、分布式、基于发布订阅的消息系统,利用Kafka技术可以在廉价的PC Server上搭建起大规模消息系统。

Kafka的特性:

高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作;
可扩展性:kafka集群支持热扩展;
持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失;
容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败);
高并发:支持数千个客户端同时读写;
支持实时在线处理和离线处理:可以使用Storm这种实时流处理系统对消息进行实时进行处理,同时还可以使用Hadoop这种批处理系统进行离线处理;

Kafka应用场景:

Kafka应用场景
Kafka和其他组件比较,具有消息持久化、高吞吐、分布式、多客户端支持、实时等特性,适用于离线和在线的消息消费,如常规的消息收集、网站活性跟踪、聚合统计系统运营数据(监控数据)、日志收集等大量数据的互联网服务的数据收集场景。

日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如Hadoop、Hbase、Solr等;
消息系统:解耦和生产者和消费者、缓存消息等;
用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到Hadoop、数据仓库中做离线分析和挖掘;
运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告;
流式处理:比如spark streaming和storm;
事件源

kafka在FusionInsight中的位置:
kafka在FusionInsight中的位置

Kafka架构与功能

Kafka架构:

Kafka架构图
基础架构

基本概念:

Broker:Kafka集群包含一个或多个服务实例,这些服务实例被称为Broker。是Kafka当中具体处理数据的单元。Kafka支持Broker的水平扩展。一般Broker数据越多,集群的吞吐力就越强。
Topic:每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。
Partition:Kafka将Topic分成一个或多个Partition,每个Partition在物理上对应一个文件夹,该文件下存储这个Partition的所有消息。
Producer:负责发布消息到Kafka Broker。
Consumer:消息消费者,从Kafka Broker读取消息的客户端。
Consumer Group:每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name)。
ZooKeeper:kafka与Zookeeper级联,通过Zookeeper管理级联配置,选举Leader。

Kafka Topics

Kafka Topics
每条发布到Kafka的消息都有个类别,这个类别被称为Topic,也可以理解为一个存储消息的队列。例如:天气作为一个Topic,每天的温度消息就可以存储在“天气”这个队列里。数据总数先进先出。后来的数据追加到后面。

Kafka Partition:

Kafka Partition
每个Topic都有一个或者多个Partitions构成。每个Partition都是有序且不可变的消息队列。引入Partition机制,保证了Kafka的高吞吐能力。

在每个Partition当中,都会存储一个Log文件,Log文件中记录了所有的消息文件。一个Topic的多个Partition,它分布在不同的Kafka节点上,这样多个客户端包括Producer和Consumer就可以并发的访问不同节点,对同一个Topic进行消息的读取。

Partition
Topic的Partition数量可以在创建时配置。
Partition数据决定了每个Consumer group中并发消费者的最大数据。
Consumer group A有两个消费者来读取4个Partition中数据;Consumer group B有四个消费者来读取4个partition中数据。

Kafka Partition offset:

Kafka Partition offset
任何发布到此Partition的消息都会被直接追加到log文件的尾部。
每条消息在文件中的位置称为offset(偏移量),offset是一个long型数字,它唯一标记一条消息。消费者通过(offset、partition、topic)跟踪记录。
Kafka不支持消息的随机读取。

Kafak Partition Replicas(副本):

副本机制
副本以分区为单位。每个分区都有各自的主副本。
可以通过配置文件,配置副本的个数。
一个Kafka集群中,各个节点可能互为Leader和Follower。
主副本叫做Leader,从副本叫做Follower,处于同步状态的副本叫做In-Sync Replicas(ISR)。
如果Leader失效,那么将会有其他的Follower来接管成为新的Leader。如果由于Follower自身的原因,比如网络原因导致同步落后太多,那么当Leader失效后,就不会将这个Follower选为leader。
由于Leader的Server承载了全部的请求压力,因此从集群的整体考虑,Kafka会将Leader均衡的分散在每个实例上,来保持整体稳定。
Follower通过拉取的方式从Leader中同步数据。消费者和生产这都是从Leader中读取数据,不与Follower交互

主副本和从副本的数据同步

主副本和从副本的数据同步
Follower主动从Partition的Leader上批量拉取数据,这就极大的提高了Kafka的吞吐量。Follower复制数据的线程叫做ReplicaFetcher Thread,而Kafka的Producer和Consumer只与Leader进行交互,不会与Follower进行交互。

ReplicaFetcher Thread
Kafka中每个Broker启动的时候,都会创建一个副本管理服务ReplicaManager,该服务负责维护ReplicaFether Thread与其他Broker链路连接关系。该服务中存在的Follower Partition对应的Leader Partition会分布在不同的Broker上,这些Broker创建相同数量的ReplicaFether Thread,同步对应Partition数据。Kafka中Partition间复制数据,是由Follower主动从Leader拉消息的。Follower每次读取消息都会更新HW状态,用于记录当前最新消息的标识。每当Follower的Partition发生变化而影响Leader所在的Broker时,ReplicaManager就会新建或者销毁相对应的ReplicaFether Thread。

Kafka Logs:

为了使得Kafka的吞吐率可以线性提高,物理上把Topic分成一个或多个Partition,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息

partition segment
Kafka把Topic中一个Partition大文件分成多个小文件段通过多个小文件段,就容易定期清除或删除已经消费完的文件,减少磁盘占用。
同一个Topic下有不同的分区,每个分区会划分为多个文件,只有一个当前文件在写,其他文件是只读的。当写满一个文件(即达到某个设定的值)Kafka会新建一个空文件继续来写。而老文件切换为只读。

文件的命名以起始的偏移量来进行命名。 .index 和 .log 就分别表示为Segment的index file和data file。Segment命名规则:以该segment最小offset来命名(000.index存储offset为0~368795的消息,下一个index名字则为368796.index),这个数据是64位的long型数据,如果没有数据就用0进行填充。
kafka就是利用分段+索引的方式来解决查找效率的问题。

通常把日志文件默认为1G,当达到1G就会创建新的Log文件和index文件。如果设置的参数过小,会产生大量的log文件和index文件,系统在启动的时候就需要加载大量的index到内存,占用大量的句柄。如果设置的太大,分段文件又比较少,不利于快速的查找。

索引文件
通过索引信息可以快速定位message。
通过将index元数据全部映射到memory,可以避免segment file的index数据IO磁盘操作。
通过索引文件稀疏存储,可以大幅降低index文件元数据占用空间大小。
稀疏存储:将原来完整的数据,只间隔的选择多条数据进行存储。

Message结构

上面说到log文件就实际是存储message的地方,我们在producer往kafka写入的也是一条一条的message,那存储在log中的message是什么样子的呢?消息主要包含消息体、消息大小、offset、压缩类型……等等!我们重点需要知道的是下面三个:
1、 offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
2、 消息大小:消息大小占用4byte,用于描述消息的大小。
3、 消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。

Kafka Log Cleanup:

无论消息是否被消费,kafka都会保存所有的消息

日志的清理方式有两种:delete和compact。
删除策略:
1、 基于时间,默认配置是168小时(7天)。
2、 基于分区内总日志大小,默认配置是1073741824。
删除
需要注意的是,kafka读取特定消息的时间复杂度是O(1),所以这里删除过期的文件并不会提高kafka的性能!
日志清理方式–compact

Kafka数据可靠性:

Kafka所有消息都会被持久化到磁盘中,同时Kafka通过对Topic Partition设置Replication来保障数据可靠。

消息传输过程中保障通常有以下三种:

最多一次(At Most Once): 消息可能丢失;消息不会重复发送和处理。
最少一次(At Lease Once):消息不会丢失;消息可能会重复发送和处理。
仅有一次(Exactly Once): 消息不会丢失;消息仅被处理一次。

Kafka消息传输保障机制,通过配置不同的消息发送模式来保障消息传输,进而满足不同的可靠性要求应用场景。
可靠

Kafka关键流程

发送数据

发送数据
Producer在写入数据的时候永远的找leader,不会直接将数据写入follower
producer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区(Partition)内的数据是有序的

通过ACK应答机制,保证消息不丢失;在生产者向队列写入数据的时候可以设置参数来确定是否确认kafka接收到数据,这个参数可设置的值为0、1、all
0:producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但效率最高。
1:producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
all:producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保leader发送成功和所有的副本都完成备份。安全性最高,但是效率最低。

kafka会自动创建topic,分区和副本的数量根据默认配置都是1。

消费数据

消息存储在log文件后,消费者就可以进行消费了。 Kafka采用的是点对点的模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader去拉取。

多个消费者可以组成一个消费者组(consumer group),每个消费者组都有一个组id!同一个消费组者的消费者可以消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据!!!
同一个消费组者的消费者可以消费同一topic下不同分区的数据
消费者组内的消费者小于partition数量的情况,所以会出现某个消费者消费多个partition数据的情况,消费的速度也就不及只处理一个partition的消费者的处理速度!
如果是消费者组的消费者多于partition的数量,那会不会出现多个消费者消费同一个partition的数据呢?上面已经提到过不会出现这种情况!多出来的消费者不消费任何partition的数据。所以在实际的应用中,建议消费者组的consumer的数量与partition的数量一致!

segment+offset 查找消息

查找消息的时候是怎么利用segment+offset配合查找的呢?
假如现在需要查找一个offset为368801的message是什么样的过程呢?
查找过程
1、 先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。
2、 打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系,所以直接找相对offset为5的索引找不到,这里同样利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。
3、 根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。

segment+有序offset+稀疏索引+二分查找+顺序查找等多种手段来高效的查找数据!

Zookeeper在Kafka的作用:

无论是kafka集群,还是producer和consumer都依赖于zookeeper来保证系统可用性集群保存一些meta信息。
Kafka使用zookeeper作为其分布式协调框架,很好的将消息生产、消息存储、消息消费的过程结合在一起。
同时借助zookeeper,kafka能够生产者、消费者和broker在内的所以组件在无状态的情况下,建立起生产者和消费者的订阅关系,并实现生产者与消费者的负载均衡。

Kafka in ZooKeeper:

在这里插入图片描述

Kafka Cluster Mirroring

Kafka CLuster Mirroring
Kafka Cluster Mirroring是Kafka跨集群数据同步方案,通过Kafka内置的MirrorMaker工具来实现。通过Mirror Maker工具中的consumer从源集群消费数据,然后再通过内置的Producer,将数据重新发布到目标集群。

参考:再过半小时,你就能明白kafka的工作原理了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值