Kafka原理总结

研究了rocket-mq之后,一直想知道为什么kafka会这么火, 终于有时间学习了一下这块的内容, 简单总结以备以后查阅。

部署架构

其实这个架构和rocket-mq比较像,差异是rocket-mq使用了nameserver,而kafka使用zookeeper来做配置协调中心。

组成原理

主要涉及kafka从broker启动、生产者发送消息、broker分发消息到消费者消费消息的流程。

服务注册

  • 所有的broker启动后都注册到zookeeper,写到/brokers/ids目录下;
  • Broker组件订阅这个路径,当有borker加入、删除就能够立即知道其broker的信息了;
  • 健康检查机制,Broker长时间丢失连接会被自动回收;
  • 基于此,producer在配置的时候,并不需要填写所有broker的地址,只需要填写几个broker的地址就可以通过他们去发现自己需要写topic的broker了。

Controller的作用

  • Broker起来后选举出一个controller,controller是使用锁的方式来实现的。即在zookeeper的/controller目录,谁先写入数据,谁就是controller;
  • 新的controller会获得一个递增的epoch,如果其他broker收到老controller发出来的消息,消息体重会带着旧的epoch,就直接忽略消息;
  • 其他broker会一直watch /controller的变化;并等待当前controller挂了之后抢占controller的地位。
  • controller的职责是管控broker与topic中partition主备映射关系;
  • 当broker挂掉、新加broker时,controller通过watch可以感知到变化;它会通过分析挂掉的broker中的partition的副本来重新选举出partition的leader,并将变化下发到相关的broker;

生产者

  • Producer先序列化数据,按照topic分类(下面还有key/value),然后按照负载均衡算法push消息到topic的不同partition;
  • Producer发送消息的模式有三种: oneway(结果未知), sync(阻塞), async(有回调函数);
  • Producer可以设置Acks方式,可以设置为: 1. 发送后立即返回; 2. 等待主partition保存后返回; 3.等待副本patirion复制完成后返回;

Topic与Partition

  • Topic可以有多个partition,可以基于各种算法来将消息分类到不同partition,拥有同样key的消息会放到同一个partition;
  • partition是物理实现,可以指定partition的副本数;
  • Topic下的partition数量可以递增,但是不能递减;

Parition主备复制

  • kafka的高可用是通过topic的partition主备来实现的;
  • partition的副本负责从leader拷贝数据,数据中包含了offset等信息;
  • partition的副本会发送回复信息给leader,leader基于此来判断副本是否保持同步;
  • 只有同步的分区副本才能在leader挂后被选为新的leader;
  • 消费者只能看到已经被复制到ISR的消息,分区副本从leader复制消息之前,理论上leader是不允许该消息被consumer消费的,因为这样的消息不安全。

消费者组再均衡

  • Topic如果增加partition,或者consumer有变动,均需要重新分配分区(再均衡);
  • Consumer的变动是通过定期向broker协调者发送心跳报文来实现的,心跳报文中包含了群属关系以及分区所有权关系;
  • 在再均衡期间,消费者无法读取消息;
  • Consumer读取消息,并将offset发送到一个__consumer_offset的特殊topic中,该消息包含了每个分区的偏移量;
  • 一旦再均衡后,新的consumer可以继续按照之前的offset工作;

消息存储

  • Broker的消息保存策略为:
    1. 保存指定时间;
    2. 保存达到某一Size;

消费者

  • Kafka支持Consumer group,它可以保障每一个group中只有一个consumer消费某条消息;
  • 如果要广播消息,需要创建多个consumer group;
  • Consumer的数量不要超过分区数量,否者某些consumer会闲置。
0%