kafka——设计与模型

kafka由LinkedIn公司研发开源,现已是apache基金会的顶级项目。

一、消息队列设计

1、消息队列的两个重要设计:

消息设计:消息设计通常采用结构化的方式进行设计,结构化信息格式例如XML,JSON

传输协议设计:狭义角度:AMQP、WebService +SOAP/MSMQ等,广义角度:RPC框架如PB、Dubbo。

2、消息队列模型

点对点模型:特点:

① 生产者将消息发送到指定队列,消费者从指定队列获取消息

② 每条消息有一个发送者生产出来,且只能被一个消费者获取(消费者获取消息后删除消息)。

③ 生产者消费者是严格的一对一模型

发布/订阅模型:发布/订阅模型还可细分为两类,

① 消费者是被动的接受消息,由消息队列推送给消费者。

② 消费者主动获取消息。消息由消费者主动获取,(kafka)

 特点:

① 多了一个topic概念,生产者将消息发送个消息队列中的topic中,所有订阅了该topic的消费者都可以接受到该topic下的所有消息(主动或被动)。

② 每条消息由一个生产者生产出来,可由多个消费者消费,实现消息复用。(消费者获取消息后不删除,kafka会持久化消息到配置文件中log路径......)

③ 由于消息不删除,所以需要记录消费者消费消息的位置offset,模型一由消息队列记录,模型二由消费者记录。

④ 生产消费者是一对多模型。

⑤ 只要控制offset位置,虽然不删除消息,但可以实现点对点模型。

二、Kafka设计

Kafka是一种高吞吐量的分布式发布/订阅消息系统。设计目标:

1、吞吐量/延时

kafka的吞吐量:单位时间内处理的消息请求数

kafka的延时:单次处理消息请求的总时长,发送到接受响应

① 批处理思想

② kafka消息写入速度非常快,kafka将消息写入到内存的页缓存中,然后由操作系统异步写回磁盘。实际情况kafka大量使用页缓存,利用缓存时间局部性原理,消费者读取消息时,消息很有可能依然保存在页缓存中,直接命中缓存,无需读取磁盘节省一次I/O操作时间。

③ kafka不必直接与底层文件系统打交道,繁琐的I/O操作都交由操作系统来处理

④ kafka写入操作采用追加写入(顺序写入)的方式,避免磁盘随机写操作。ROM顺序存储速度丝毫不逊色DRAM的随机存储

⑤ 使用sendfile为代表的零拷贝技术加强网络间的数据传输效率

2、消息持久化

kafka持久化:所有数据都会立即被写入文件系统的持久化日志中,之后kafka服务器才会响应客户端成功写入

kafka持久化可很方便的实现消息重演。

3、负载均衡和故障转移

kafka实现负载均衡实际上是通过分区(partition)leader选择来实现的。

kafka故障转移使用会话机制。以会话形式注册到ZooKeeper服务器上,由ZooKeeper管理服务器状态

4、伸缩性

由于kafka每台服务器状态统一交由ZooKeeper保管,所以扩展kafka集群,仅需要将新kafka服务器注册到ZooKeeper中就行了。

二、Kafka术语

Message:kafka中的消息使用紧凑二进制字节数组,保存消息,无多余比特位浪费。Java对象存储会强制8字节边界对齐,浪费很多空间。

topic和partition:主题与分区,kafka使用主题topic来分类消息,使用topic更小的分区概念partition作为消息的载体。

topics是逻辑概念,partition是物理概念(磁盘上找的到的)

replica:分区partition的副本,多个replica也是采用leader-follower模型建立关系。

offset:由于消息不删除,所以需要标识每条消息在分区(partition)的偏移量,

综上,消息在kafka中的位置可以用一个三元组<topic,partition,offset>表示。

leader和follower:leader-follower模型

ISR:全称in-sync replica:指的是与leader replica保持同步的replica集合。kafka的分区partition有众多replica,follower replica在不断同步leader replica状态,只有与leader replica状态一致的replica才能加入到ISR中。kafka保证ISR至少存在一个replica,哪些已提交的消息就不会丢失。

 多个对应关系结构图:(省略前面集群中ZooKeeper部分)

 ① topic层面:单机kafka可以创建多个topic,消费者以组为单位接受订阅topic,但topic中消息仅能被同一组内的一个消费者接受,

形象一点就是可以将group看作为一个消费者,topic消息仅推送一次。

例如消费者groupId=1,订阅topic1,2,3,消息仅能推送到group中的某一个消费者。

 ② partition层面:partition将topic再度细化。

一个topic中可有多个分区partition,生产者生产消息实际存在在topic中的partition中,消费者消费消息也是从topic中的partition中获取。

 ③ 集群模型(3-3)

kafka内部将kafka服务器称为broker,以下broker代表了一个kafka服务

broker.1=kafka9091
broker.2=kafka9092
broker.3=kafka9093

1) 创建topic的partition分区个数可大于broker数,replica副本个数不能大于broker数

2) 创建一个topic,拥有3个partition,每个partition有3个replica,然后查看topic信息

sh cluster.sh topic create topic-test 3 3
sh cluster.sh topic describe topic-test,topic-second,topic-third

 

也就是内存中会有9个副本replica,其中

partition0有三个副本replica,上面可以看出broker3上的replica是replica-leader,另外两个副本分别存储在broker1,2上;其他两个分区也是一样

模型图:partition-leader == replica-leader

①当partition-leader宕机了,kafka集群会从ISR中选取leader作为新的replica-leader也就是parition-leader。

以上面partition0为例,将leader所在服务broker3关掉,

下图:broker1中partition副本成为leader,ISR删除broker3

 将broker3启动,leader未发生变化,broker3上partition分区副本重新加入到ISR中。

集群模型图

 

参考《kafka实战》

原文地址:https://www.cnblogs.com/wqff-biubiu/p/12326704.html