Kafka入门

1.简介

官网简介

Kafka 是一个分布式流媒体平台。
Kafka有三大关键功能:

  1. 它允许我们发布和订阅记录流,这类似于消息队列或者消息传递系统。
  2. 它允许我们以容错机制存储记录流
  3. 它允许我们实时处理记录流

Kafka 擅长于做什么呢?

  1. 在系统或者应用间构建实时的数据流通道。
  2. 对于数据的传输或者转换构建实时的数据流处理程序

Kafka是如何工作的呢?
首先介绍几个概念:

  • kafka 是建立在一台或者多台服务器构成的集群。
  • kafka集群存储的记录流我们成为topics
  • 每一个记录流包含key,value和timestamp.

    Kafka有四个核心API :

  • Producer API 允许应用发布一条记录流到一个或者多个kafka topics.

  • Consumer API 允许应用程序订阅一个或者多个topics,并且处理发布给他们的记录流.
  • Streams API 允许应用程序作为一个流媒体处理程序,消费一个或者多个topics,生产一个或者多个topics,有效的传输输入流到输出流
  • Connector API 允许构建和允许可重用的生产者和消费者

在kafka中客户端和服务端通讯是通过简单,高效,语言无关的TCP协议.kafka提供了java客户端,不光java同时也提供了很多种语言的客户端

2.kafka整体结构

Kafka入门
一个典型的kafka集群中包含若干producer,若干broker,若干consumer,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在consumer group发生变化时进行rebalance。producer使用push模式将消息发布到broker,consumer使用pull模式从broker订阅并消费消息。  

Kafka专用术语:

Broker:消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。

Topic:一类消息,Kafka集群能够同时负责多个topic的分发。

Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。

Segment:partition物理上由多个segment组成。

offset:每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的***叫做offset,用于partition唯一标识一条消息。

Producer:负责发布消息到Kafka broker。

Consumer:消息消费者,向Kafka broker读取消息的客户端。

Consumer Group:每个Consumer属于一个特定的Consumer Group。

Topics and Logs

Kafka入门

Kafak顺序写入与数据读取

生产者(producer)是负责向Kafka提交数据的,Kafka会把收到的消息都写入到硬盘中,它绝对不会丢失数据。为了优化写入速度Kafak采用了两个技术,顺序写入和MMFile。

顺序写入

因为硬盘是机械结构,每次读写都会寻址,写入,其中寻址是一个“机械动作”,它是最耗时的。所以硬盘最“讨厌”随机I/O,最喜欢顺序I/O。为了提高读写硬盘的速度,Kafka就是使用顺序I/O。

每条消息都被append到该Partition中,属于顺序写磁盘,因此效率非常高。
Kafka入门

对于传统的message queue而言,一般会删除已经被消费的消息,而Kafka是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到了第几条数据。
Kafka入门

即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。所以Kafka的数据并不是实时的写入硬盘,它充分利用了现代操作系统分页存储来利用内存提高I/O效率。

在Linux Kernal 2.2之后出现了一种叫做“零拷贝(zero-copy)”系统调用机制,就是跳过“用户缓冲区”的拷贝,建立一个磁盘空间和内存空间的直接映射,数据不再复制到“用户态缓冲区”系统上下文切换减少2次,可以提升一倍性能。
Kafka入门

通过mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存)。使用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销(调用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中。)

消费者(读取数据)

试想一下,一个Web Server传送一个静态文件,如何优化?答案是zero copy。传统模式下我们从硬盘读取一个文件是这样的。

Kafka入门

先复制到内核空间(read是系统调用,放到了DMA,所以用内核空间),然后复制到用户空间(1、2);从用户空间重新复制到内核空间(你用的socket是系统调用,所以它也有自己的内核空间),最后发送给网卡(3、4)。

Kafka入门

Zero Copy中直接从内核空间(DMA的)到内核空间(Socket的),然后发送网卡。这个技术非常普遍,Nginx也是用的这种技术。
实际上,Kafka把所有的消息都存放在一个一个的文件中,当消费者需要数据的时候Kafka直接把“文件”发送给消费者。当不需要把整个文件发出去的时候.

Producers
生产者将数据发布到他们订阅的topics。

Consumers

Kafka入门

消费者将自己标记为一个consumer group,并将每个发布到主题的记录传递给每个订阅消费群中的一个消费者实例。消费者实例可以是独立的进程,也可以是独立的机器。
如果所有的消费者实例都具有相同的consumer group,那么记录将有效地在消费者实例上进行负载平衡。
如果所有的消费者实例都有不同的consumer group,那么每个记录将被广播到所有消费者进程。

Kafka入门