美文网首页
kafka相关知识总结

kafka相关知识总结

作者: 程序媛啊 | 来源:发表于2017-07-30 20:34 被阅读0次

一、kafka基础知识

1、kafka是什么

类JMS消息队列,结合JMS中的两种模式,可以有多个消费者主动拉取数据,在JMS中只有点对点模式才有消费者主动拉取数据。
kafka是一个生产-消费模型。
Producer:生产者,只负责数据生产,生产者的代码可以集成到任务系统中。 
          数据的分发策略由producer决定,默认是defaultPartition  Utils.abs(key.hashCode) % numPartitions
Broker:当前服务器上的Kafka进程,俗称拉皮条。只管数据存储,不管是谁生产,不管是谁消费。
        在集群中每个broker都有一个唯一brokerid,不得重复。
Topic:目标发送的目的地,这是一个逻辑上的概念,落到磁盘上是一个partition的目录。partition的目录中有多个segment组合(index,log)
        一个Topic对应多个partition[0,1,2,3],一个partition对应多个segment组合。一个segment有默认的大小是1G。
        每个partition可以设置多个副本(replication-factor 1),会从所有的副本中选取一个leader出来。所有读写操作都是通过leader来进行的。
        特别强调,和mysql中主从有区别,mysql做主从是为了读写分离,在kafka中读写操作都是leader。
ConsumerGroup:数据消费者组,ConsumerGroup可以有多个,每个ConsumerGroup消费的数据都是一样的。
               可以把多个consumer线程划分为一个组,组里面所有成员共同消费一个topic的数据,组员之间不能重复消费。

2、kafka生产数据时的分组策略

默认是defaultPartition  Utils.abs(key.hashCode) % numPartitions
上文中的key是producer在发送数据时传入的,produer.send(KeyedMessage(topic,myPartitionKey,messageContent))

3、kafka如何保证数据的完全生产

ack机制:broker表示发来的数据已确认接收无误,表示数据已经保存到磁盘。
0:不等待broker返回确认消息
1:等待topic中某个partition leader保存成功的状态反馈
-1:等待topic中某个partition 所有副本都保存成功的状态反馈

4、broker如何保存数据

在理论环境下,broker按照顺序读写的机制,可以每秒保存600M的数据。主要通过pagecache机制,尽可能的利用当前物理机器上的空闲内存来做缓存。
当前topic所属的broker,必定有一个该topic的partition,partition是一个磁盘目录。partition的目录中有多个segment组合(index,log)

5、partition如何分布在不同的broker上

int i = 0
list{kafka01,kafka02,kafka03}

for(int i=0;i<5;i++){
    brIndex = i%broker;
    hostName = list.get(brIndex)
}

6、consumerGroup的组员和partition之间如何做负载均衡

最好是一一对应,一个partition对应一个consumer。
如果consumer的数量过多,必然有空闲的consumer。

算法:
    假如topic1,具有如下partitions: P0,P1,P2,P3
    加入group中,有如下consumer: C1,C2
    首先根据partition索引号对partitions排序: P0,P1,P2,P3
    根据consumer.id排序: C0,C1
    计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
    然后依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]

7、如何保证kafka消费者消费数据是全局有序的

伪命题
如果要全局有序的,必须保证生产有序,存储有序,消费有序。
由于生产可以做集群,存储可以分片,消费可以设置为一个consumerGroup,要保证全局有序,就需要保证每个环节都有序。
只有一个可能,就是一个生产者,一个partition,一个消费者。这种场景和大数据应用场景相悖。

二、kafka详细

1、Kafka整体结构图

Kafka名词解释和工作方式

Producer :消息生产者,就是向kafka broker发消息的客户端。
Consumer :消息消费者,向kafka broker取消息的客户端
Topic :咱们可以理解为一个队列。
Consumer Group (CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partion只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。
Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka

2、Consumer与topic关系

本质上kafka只支持Topic;

2.1 每个group中可以有多个consumer,每个consumer属于一个consumer group;
通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高"故障容错"性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。

2.2 对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;
那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个"订阅"者。

2.3 在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。

2.4 kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。

2.5 kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。

3、Kafka消息的分发

Producer客户端负责消息的分发

3.1 kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含"集群中存活的servers列表"/"partitions leader列表"等信息;

3.2 当producer获取到metadata信息之后, producer将会和Topic下所有partition leader保持socket连接;

3.3 消息由producer直接通过socket发送到broker,中间不会经过任何"路由层",事实上,消息被路由到哪个partition上由producer客户端决定;
比如可以采用"random""key-hash""轮询"等,如果一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。

3.4 在producer端的配置文件中,开发者可以指定partition路由的方式。

Producer消息发送的应答机制
设置发送数据是否需要服务端的反馈,有三个值0,1,-1
0: producer不会等待broker发送ack 
1: 当leader接收到消息之后发送ack 
-1: 当所有的follower都同步消息成功后发送ack
    request.required.acks=0

4、Consumer的负载均衡

当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提升topic的并发消费能力,步骤如下:
1、  假如topic1,具有如下partitions: P0,P1,P2,P3
2、  加入group中,有如下consumer: C1,C2
3、  首先根据partition索引号对partitions排序: P0,P1,P2,P3
4、  根据consumer.id排序: C0,C1
5、  计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
6、  然后依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]
Paste_Image.png

5、kafka文件存储机制

5.1、Kafka文件存储基本结构

5.1.1   在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。

5.1.2   每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。默认保留7天的数据。
Paste_Image.png
5.1.3   每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。(什么时候创建,什么时候删除)
Paste_Image.png
数据有序的讨论?
    一个partition的数据是否是有序的?   间隔性有序,不连续
    针对一个topic里面的数据,只能做到partition内部有序,不能做到全局有序。
    特别加入消费者的场景后,如何保证消费者消费的数据全局有序的?伪命题。

只有一种情况下才能保证全局有序?就是只有一个partition。

5.2、Kafka Partition Segment

5.2.1   Segment file组成:由2大部分组成,分别为index file和data file,此2个文件一一对应,成对出现,后缀".index"和“.log”分别表示为segment索引文件、数据文件。
Paste_Image.png
5.2.2   Segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。
5.2.3   索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。
Paste_Image.png
3,497:当前log文件中的第几条信息,存放在磁盘上的那个地方

segment data file由许多message组成, qq物理结构如下:
关键字           解释说明
8 byte offset       在parition(分区)内的每条消息都有一个有序的id号,这个id号被称为偏移(offset),它可以唯一确定每条消息在parition(分区)内的位置。即offset表示partiion的第多少message
4 byte message size message大小
4 byte CRC32        用crc32校验message
1 byte “magic"      表示本次发布Kafka服务程序协议版本号
1 byte “attributes" 表示为独立版本、或标识压缩类型、或编码类型。
4 byte key length   表示key的长度,当key为-1时,K byte key字段不填
K byte key          可选
value bytes payload 表示实际消息数据。

5.3、Kafka 查找message

读取offset=368776的message,需要通过下面2个步骤查找。
Paste_Image.png

5.3.1、查找segment file

00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0
00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1
00000000000000737337.index的起始偏移量为737338=737337 + 1
其他后续文件依次类推。
以起始偏移量命名并排序这些文件,只要根据offset **二分查找**文件列表,就可以快速定位到具体文件。当offset=368776时定位到00000000000000368769.index和对应log文件。

5.3.2、通过segment file查找message

当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址
然后再通过00000000000000368769.log顺序查找直到offset=368776为止。

6、Kafka自定义Partition

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
 
import java.util.Properties;
 
 
public class MyKafkaProducer {
    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put("metadata.broker.list","mini1:9092");
 
        // 默认的序列化为byte改为string
        properties.put("serializer.class","kafka.serializer.StringEncoder");
        /**
         * 自定义parition的基本步骤
         * 1、实现partition类
         * 2、加一个构造器,MyPartitioner(VerifiableProperties properties)
         * 3、将自定义的parititoner加入到properties中
         *    properties.put("partitioner.class","cn.itcast.MyPartitioner")
         * 4、producer.send方法中必须指定一个paritionKey
         */
        properties.put("partitioner.class","cn.itcast.MyPartitioner");
        Producer producer = new Producer(new ProducerConfig(properties));
        while (true){
            producer.send(new KeyedMessage("order4","zhang","我爱我的祖国"));
//            producer.send(new KeyedMessage("order","我爱我的祖国"));
        }
    }
}

import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties;
 
/**
 * http://www.cnblogs.com/wxd0108/p/6519973.html
 */
public class MyPartitioner implements Partitioner {
    public MyPartitioner(VerifiableProperties properties) {
    }
    public int partition(Object key, int numPartitions) {
        return 2;
    }
}

相关文章

  • kafka相关知识总结

    一、kafka基础知识 1、kafka是什么 2、kafka生产数据时的分组策略 3、kafka如何保证数据的完全...

  • 干货 | Kafka 内核知识梳理,附思维导图

    前面我们已经分享过几篇Kafka的文章,最近简单梳理了下Kafka内核相关的知识,涵盖了Kafka架构总结,副本机...

  • kafka学习系列

    Kafka学习总结(一)——Kafka简介 Kafka学习总结(二)——Kafka设计原理 Kafka学习总结(三...

  • Kafka & Zookeeper

    这篇文章主要用来介绍Kafka & Zookeeper相关基础知识。 1. Kafka是由Linkedin开发,是...

  • kafka知识总结

    本文将介绍最常用的分布式消息中间件kafka。由于笔者水平受限,因此介绍不一定全面,也不会太深入,仅供参考。 环境...

  • kafka 相关配置总结

    kafka 总结 心跳线程和poll线程分开,但是心跳线程是在poll线程中启动的 在满足max.partitio...

  • Kafka Connect 实战 ---- 入门

    前提 首先你需要了解MQ / Kafka相关的知识 本文目标 了解 Kafka Connect 基本概念与功能 什...

  • kafka扫盲——别等面试官一问三不知了

    由于工作中经常用到kafka,但是对kafka的一些内部机制不是很熟悉,所以最近在看kafka相关的知识,我们知道...

  • kafka从入门到实践

    题图:pixabay 上周在公上周在公司做了一次内部分享,关于kafka科普相关的。总结输出一下: kafka 是...

  • kafka知识整理总结

    1. Kafka是什么? kafka是一个分布式的,基于发布订阅的消息队列系统.虽然它也可以作为分布式缓存使用,但...

网友评论

      本文标题:kafka相关知识总结

      本文链接:https://www.haomeiwen.com/subject/ixuklxtx.html