零基础之go语言16 | 青训营笔记

91 阅读7分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 16 天 本次笔记将记录Kafka

什么是Kafka

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源 项目。

Kafka特性

  • 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒
  • 可扩展性:kafka集群支持热扩展
  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
  • 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
  • 高并发:支持数千个客户端同时读写

Kafka的应用

  • 日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。
  • 消息系统:解耦和生产者和消费者、缓存消息等。
  • 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
  • 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
  • 流式处理:比如spark streaming和storm
  • 事件源

Kafka架构原理

image.png

注:每个broker可以看成一个服务器,每个服务器存储这一些topic,这些topic可以是follower或者leader,leader是主存储,follower是用来备份的,加入leader1是某个主存储,follower1是leader1的备份,那么follower1一定不能与leader1在同一个broker内。也就是说leader与它的follower们必须都是在不同broker里!

名词解释

  • Producer:Producer即生产者,消息的产生者,是消息的入口。
  • Broker:Broker是kafka实例,每个服务器上有一个或多个kafka的实例。每个kafka集群内的broker都有一个不重复的编号,如图中的broker-0、broker-1等……
  • Topic:消息的主题,消息的分类,kafka的数据就保存在topic。在每个broker上都可以创建多个topic。每个topic要么是leader,要么是follower。
  • Partition:Topic的分区,每个topic可以有多个分区,分区的作用是做负载,提高kafka的吞吐量。同一个topic在不同的分区的数据是不重复的,partition的表现形式就是每一个文件夹
  • Replication:每一个分区都有多个副本。当主分区(Leader)故障的时候会选择一个Follower上位,成为Leader。在kafka中默认副本的最大数量是10个,且副本的数量不能大于Broker的数量,follower和leader是在不同的机器,同一机器对同一个分区也只可能存放一个副本。
  • Message:每一条发送的消息主体。
  • Consumer:消费者,即消息的消费方,是消息的出口。
  • Consumer Group:将多个消费组组成一个消费者组,在kafka的设计中同一个分区的数据只能被消费者组中的某一个消费者消费。同一个消费者组的消费者可以消费同一个topic的不同分区的数据,这也是为了提高kafka的吞吐量!
  • Zookeeper:kafka集群依赖zookeeper来保存集群的的元信息,来保证系统的可用性。

工作流程

image.png

图片来自CSDN,blog.csdn.net/wanghailan1…

1、producer会在broker(kafuka实例)里面寻找leader(某个topic),再讲消息保存到kafka

2、然后对应follower(副本)主动拉取leader所写的消息进行备份

3、备份完成后,follower发送成功信息ACK给leader

4、leader收到所有follower发送的ACK后,再发送成功信息ACK给producer

5、producer收到ACK后继续寻找leader发送消息

注:roducer采用push模式将数据发布到broker,每条消息追加到分区中,顺序写入磁盘,所以保证同一分区内的数据是有序的。

kafka保存消息到本地

partition(文件夹)

每个topic可以分为一个或多个partition,Partition在服务器上的表现形式就是文件夹,每个partition的文件夹下面会有多组segment文件,每组segment文件又包含.index文件、.log文件、.timeindex文件(早期版本中没有)三个文件, log文件就实际是存储message的地方,而index和timeindex文件为索引文件,用于检索消息。

image.png 文件的命名是以该segment最小offset来命名的,如000.index存储offset为0~368795的消息,kafka就是利用分段+索引的方式来解决查找效率的问题(二分法)。

Message结构

message就是要保存的消息数据,message的主要结构如下:

  • offset:offset是一个占8byte的有序id号,它可以唯一确定每条消息在parition内的位置!
  • 消息大小:消息大小占用4byte,用于描述消息的大小。
  • 消息体:消息体存放的是实际的消息数据(被压缩过),占用的空间根据具体的消息而不一样。

consumer获取消息

Kafka采用的是发布订阅模式,消费者主动的去kafka集群拉取消息,与producer相同的是,消费者在拉取消息的时候也是找leader去拉取。

发布订阅模式 image.png 发布订阅模式是一个基于消息送的消息传送模型,改模型可以有多种不同的订阅者。生产者将消息放入消息队列后,队列会将消息推送给订阅过该类消息的消费者(类似微信公众号)。由于是消费者被动接收推送,所以无需感知消息队列是否有待消费的消息。

多个消费者可组成一个消费者组(consumer group),每个消费者组都有一个组id。同一组的消费者可消费同一topic下不同分区的数据,但是不会组内多个消费者消费同一分区的数据

也就是说,一组consumer可以消费同一个topic,但不能消费同一个topic下面的同一个partition image.png 如上图,consumer小于partition的数量时,某个consumer会读取多个partition,从而降低性能,所以建议消费者组的consumer的数量与partition的数量一致

consumer如何查找数据

image.png

  • 先找到offset的368801message所在的segment文件(利用二分法查找),这里找到的就是在第二个segment文件。

  • 打开找到的segment中的.index文件(也就是368796.index文件,该文件起始偏移量为368796+1,我们要查找的offset为368801的message在该index内的偏移量为368796+5=368801,所以这里要查找的相对offset为5)。由于该文件采用的是稀疏索引的方式存储着相对offset及对应message物理偏移量的关系,所以直接找相对offset为5的索引找不到,这里同样利用二分法查找相对offset小于或者等于指定的相对offset的索引条目中最大的那个相对offset,所以找到的是相对offset为4的这个索引。

  • 根据找到的相对offset为4的索引确定message存储的物理偏移位置为256。打开数据文件,从位置为256的那个地方开始顺序扫描直到找到offset为368801的那条Message。

      参考文章:https://blog.csdn.net/wanghailan1818/article/details/125166287