一、Kafka是什么
Kafka是一个开源的分布式消息队列,通过缓冲,来异构、解耦系统,与其他MQ相比,其优势在于高吞吐高性能。
上图所示为Kafka的基本架构,主要为:
Cluster:由多个服务器组成,每个服务器单独叫broker
Broker:Kafka集群中包含的服务器
Producer:消息生产者,发布消息到Kafka集群的终端或者服务
Consumer:消息消费者,负责消费数据
Topic:主题,一类消息的名称
二、分片与副本机制
分片机制:主要解决了单台服务器存储容量有限的问题。
当数据量非常大的时候,一个服务器存放不了,就将数据分成两个或者多个部分,存放在多台服务器上。每个服务器上的数据,叫做一个分片。
副本机制:解决了数据存储的高可用问题。
当数据只保存一份的时候,有丢失的风险。为了更好的容错和容灾,将数据拷贝几份,保存到不同的机器上。
三、消息不丢失机制
1、生产者端
生产者数据部不丢失,需要服务器端返回一个ack。
1) 消息确认分为三个状态
a) 0:生产者只负责发送数据
b) 1:某个partition的leader收到数据给出响应
c) -1:某个partition的所有副本都收到数据后给出响应
2) 在同步模式下
a) 生产者等待10S,如果broker没有给出ack响应,就认为失败。
b) 生产者重试3次,如果还没有响应,就报错。
3) 在异步模式下
a) 先将数据保存在生产者端的buffer中。Buffer大小是2万条。
b) 满足数据阈值或者数量阈值其中的一个条件就可以发送数据。
c) 发送一批数据的大小是500条。
如果broker迟迟不给ack,而buffer又满了。可以设置是否直接清空buffer中的数据。
2、Broker端
broker端的消息不丢失,其实就是用partition副本机制来保证。
Producer ack -1(all). 能够保证所有的副本都同步好了数据。其中一台机器挂了,并不影像数据的完整性。
3、消费者端
消费者,有偏移量记录消费到哪里。
只要记录offset值,消费者端不会存在消息不丢失的可能。只会重复消费。
当Kafka中的偏移量与zookeeper中的偏移量不一致就会重复消费
四、分发策略
分发就是消息发到哪里,哪个分片
-
如果是用户指定了partition,生产就不会调用DefaultPartitioner.partition()方法,数据分发策略的时候,可以指定数据发往哪个partition。当ProducerRecord 的构造参数中有partition的时候,就可以发送到对应partition上。
public ProducerRecord(String topic, Integer partition, K key, V value) { this(topic, partition, null, key, value, null); }
-
当用户指定key,使用hash算法,找出分片。
-
当用既没有指定partition也没有key。使用轮询的方式发送数据。
五、负载均衡
生产者生产消息太快,消费者消费不过来怎么办?
- 点对点消费
- 消费者组里,消费者<=分片数
六、文件存储机制
segment段中有两个核心的文件一个是log,一个是index。 当log文件等于1G时,新的会写入到下一个segment中。
超1G创建新的文件,过期会删掉(默认7天删除)。
磁盘的文件只能顺序往里面写,不能改。因为,硬盘的随机写和顺序写有非常大的差异。
为了保证高吞吐,只能让你在文件后面一直追加。
七、文件查询机制
读取offset=368776的message,需要通过下面2个步骤查找。
a、查找segment file
00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0
00000000000000368769.index的消息量起始偏移量为368770=368769+1
00000000000000737337.index的起始偏移量为737338=737337+1
其他后续文件依次类推。
以起始偏移量命名并排序这些文件,只要根据offset**二分查找**文件列表,就可以快速定位到具体文件。当offset=368776时定
位到00000000000000368769.index和对应log文件。
b、通过 segment file 查找message
当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地
址然后再通过00000000000000368769.log顺序查找直到offset=368776为止。