Kafka快速入门

28 阅读5分钟

kafka优势

  • 吞吐量高、性能好
  • 伸缩性好,支持在线水平扩展
  • 容错性(同一份消息存储三份并持久化到硬盘上)和可靠性(消息代理服务通常一组多备)
  • 与大数据生态紧密结合

Topic主题

kafka消息存储在Topic主题中,Topic类似数据库中的表,通常相同类型消息存储在同一Topic中,Topic是半结构化数据,也可以将不同类型消息存储在同一Topic中

Partition分区

Topic可以包含多个Partition分区,kafka是分布式消息系统,kafka将Topic拆分成多个Partition,不同的Partition可以存储在不同的服务器上,实现了kafka的扩展性;Partition是一个线性增长的不可变的提交日志,消息提交到Partition后便不可变更

offset偏移量

kafka为每条消息分配一个offset,offset记录每条消息的位置,kafka可以通过offset对消息进行提取,offset在每个分区中是唯一不可重复递增的,不同分区之间offset可以重复

Record消息记录

kafka中的Record消息以key-value键值对格式进行存储,如果不指定key,kafka以轮询的方式将消息写入不同的Partition中;如果指定了key,相同key的消息会被写入同一个分区中,这样就保证了具有相同key的消息根据顺序写入同一Partition中

kafka集群

kafka根据副本机制保证数据的可靠性,通过设置replication-factor参数调整kafka副本数量,设置为3即包含主分区在内一共三个副本;kafka选择一个副本作为leader(主分区),所有数据的写入与读取都是通过leader,其它两个副本称为follower,follower只负责从leader中复制数据,保持数据的一致,kafka会监控follower同步的状态,kafka会维护一个ISR的集合,ISR就是正在同步的副本集,如果某个副本落后的比较多,kafka会将其从ISR去除,直到恢复正常并重新加入

Broker消息代理

kafka集群由Broker消息代理组成,Broker负责消息的读写请求并且将数据写入到磁盘中,每个服务器上都启动一个Broker实例,一台服务器就是一个Broker;每个Broker都会存储多个不同Partition的副本。不同Partition的副本会尽量均衡地分布在所有Broker上,而同一个Partition的不同副本则会被分配到不同的Broker上

kafka环境安装

  • zookeeper配置文件: zookeeper.properties
  • kafka Broker配置文件: server.properties

server.properties必要配置项

  • broker.id: 消息代理ID
  • log.dirs: 日志目录
  • zookeeper.connect: zookeeper连接
  • listeners: 指定broker启动时的本机监听端口,给服务器使用
  • advertised.listeners: 对外发布的访问IP和端口,注册到zookeeper中,给客户端使用

kafka消息模型

分区

  • 分区是最小的并行单位
  • 一个消费者可以消费多个分区
  • 一个分区可以被多个消费者组里的消费者消费
  • 一个分区不能同时被同一个消费者组里的多个消费者消费

发布-订阅模式(单对多)

每个消费者都属于不同的消费者组

点对点模式(单对单)

所有消费者都属于同一个消费者组

分区与消费顺序

  • 同一个生产者发送到同一个分区的消息,先发送的offset比后发送的offset小
  • 同一个生产者发送到不同分区的消息,消息顺序无法保证
  • 消费者按照消息在分区里的存放顺序进行消费
  • kafka纸包装分区内消息的顺序,不能保证分区间的消息顺序

消息传递语义

消息传递语义需要生产者和消费者共同来保证 生产者发送给Broker消息后,Broker会返回一个消息,通知生产者收到消息

最多一次——消息可能会丢失,永远不重复发送

  • 生产者发送给Broker消息后,不会等待Broker的返回消息
  • 消费者先提交消费位置,后读取消息

最少一次——消息不会丢失,但是可能会重复

  • 生产者发送给Broker消息后,等待Broker的返回消息,如果没有收到返回消息,则重新发送
  • 消费者先读取消息,后提交消费位置

精确一次——保证消息被传递到服务端且在服务端不重复

生产者API

  • 异步发送: 使用send()函数,生产者创建缓冲区(不同分区在缓冲区中有不同的batch.size),消息首先发送到缓冲区,消息发送后立即返回并发送下一条(不等待消息成功发送到Broker中),后台IO线程负责将缓冲区内的消息发送到Broker
  • 同步发送: 获取send()函数返回的结果result,通过调用result.get()对发送消息进行阻塞,消息发送成功后再发送下一条消息
  • 批量发送: 设置batch.size参数(每批消息最大大小)、linge.ms(延迟时间),当消息满足二者任意一个则进行批量发送
  • acks参数: 消息发送到服务端后,会向生产者发送回执消息
    • acks=0: 生产者不会等待服务器端的任何回执消息,当消息被送入缓冲区则认为发送成功
    • acks=1: 表示已经被服务端的leader存入本地,但是不保证被follower成功同步
    • acks=1/all: 表示消息已经被服务端的follower同步成功
  • retries参数: 当消息发送失败重试次数
  • 最多一次: Acks=0或Acks=1
  • 至少一次: Acks=-1或all,并且retries>0

消费者API

kafka中有一个主题_consumer_offsets用来保存消费者消费到哪个主题、哪个分区哪个消费位置,利于快速回复

  • enable.auto.commit: 是否字段提交
  • auto.commit.interval.ms: 每隔多久自动提交
  • consumer.poll(): 拉取消息,异步,立即返回
  • consumer.commitSync(): 批量提交消息offset,同步,阻塞直到offset提交成功

事务消息

  • 事务成功提交后会标记为成功
  • lsolation_level: 隔离级别
    • read_uncommitted: 事务没有被标记成功也可以读取出来
    • read_committed: 事务只有被标记成功才可以被读取出来