一、消息设计
消息设计过程是一个消息占用内存变小的过程。
kafka的实现方式本质上使用JavaNIO的ByteBuffer来保存消息 ,同时依赖文件系统提供的页缓存机制,而非依靠Java的堆缓存。
ByteBuffer是紧凑的二进制字节结构,不会有JVM内存中对象8字节边界对齐产生padding问题。
消息格式版本V0、V1、V2版本。
V0版本:
CRC32+magic+attribute+keylen+key+valuelen+value
4B+1B+1B+4B+可变+4B+可变
其中keylen=-1,则没有字段key,valuelen=-1,则没有字段value;所以一条kafkaV0版本的消息长度大于等于14B。
V1版本:
V0版本消息格式没有时间信息,kafka删除过期日志只能依靠日志段文件的“最近修改时间”,这个是可以被修改的,V1相比于V0主要加入了时间字段。
CRC32+magic+attribute+timestamp+keylen+key+valuelen+value
4B+1B+1B+8B+4B+可变+4B+可变
一条kafkaV1版本消息长度大于等于22B。
V2版本:与V0,V1版本进行了很多优化,改动很大
提升空间利用率
①V2改用可变长度存储kenlan,valuelen,具体利用zig-zag编码方式0-->0,-1-->1,1-->2,-2-->3实现,将-1存储为1,-1补码为32个1,zig-zag编码前必须4B存储,zig-zag后1B即可存储。节约很大的空间
②V2版本将CRC值从消息层面移入到batch层面,
③V2版本改用可变长度存储timestamp(原来是8B长度),具体存储的是消息时间戳与batch中时间戳的差值
④V2版本将attribute值从消息层面移入到batch层面,
新增部分字段
①新增消息总长度
②新增位移增量,相对于起始位置。
二、集群管理
Kafka是分布式的消息系统,分布式实现主要是依赖ZooKeeper实现的,每当一个broker启动时,就会将自己注册到ZooKeeper下的一个节点。
zkCli.sh -server mcip:port //可查询ZooKeeper中节点
/admin:保存管理脚本的输出结果,如删除topic
/brokers:保存Kafka集群中所有信息,包括/brokers/ids保存broker信息的节点,brokers/topics保存主题节点
/cluster : 保存Kafka集群的简要消息,集群Id还有版本号
/config : 保存kafka集群下各种资源定制化配置信息
/controller:保存Kafka controller组件的注册信息,controller负责集群的领导者选举。
/controller_epoch:你保存controller组件的版本号
三、replica与ISR机制
broker中topic-partition-offset表示一条信息的位置,每个partition都有n(设置)个replica,n个replica采用leader-follower模型
①replica-leader=partition-leader
②kafka维护了一个ISR副本集合,ISR中的所有副本都与leader副本保持同步状态,leader副本也包含在内,
③ISR中有N个副本,可以忍受N-1个副本崩溃而不丢失已提交的消息
④leader选举在ISR中产生。
四、日志存储
kafka日志存储的是消息的持久化信息,
五、controller设计
在一个kafka集群中,某个broker会被选举为controller,controller是用来管理和协调Kafka集群的,管理集群中所有分区的状态并执行相应的管理操作。
①更新集群元数据信息
②创建topic
③删除topic
④分区rebalance
⑤prefferd leader选举
⑥topic分区扩展
⑦broker加入集群
⑧broker崩溃
⑨受控关闭
⑩controller leader选举
六、集群管理