什么是Kafka——分布式消息系统

What’s is Kafka:

Apache Kafka是分布式发布-订阅消息系统。他最初由Linkedln公司开发,之后成为Apache项目的一部分。Kafka是一种快速,可拓展的,设计内在就是分布式的,分区的和可复制的提交日志服务

  • Apache Kafka与传统消息系统相比,有以下不同:
    • 它被设计为一个分布式系统,易于向外拓展;
    • 它同时为发布和订阅提供吞吐量;
    • 它支持多订阅者,当失败时能自动平衡消费者;
    • 它将消息持久化到磁盘,因此可用于批量消费,例如ETL以及实时应用程序。

Apache Kafka Architecture(架构):

这里写图片描述
kafka分布式消息系统,提供了生产者,缓冲区,消费者的模型
- producer:生产者,产生数据的地方(nginx)。往broker中的某个话题里面生产数据–>生产者向kafka发送数据流的时候需要执行话题
- consumer:消费者,可以订阅多个话题,使用消费数据的地方(flume)
- broker:消息中间件处理结点,中间的kafka集群,存储消息,由多个server组成。
- topic(话题):是特定类型的消息流。消息是字节的有效负载(Payload),话题是消息的分类名或种子(Feed)名。例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发。
这里写图片描述


Kafka设计思想:

kafka将所有消息组成多个topic的形式进行存储,每一个topic可以被分成多个partition,每一个partition由多个消息组成,每一个消息都被标识了一个offset,每个消息是按顺序存储在partition中(每条消息记录都包含一个键,一个值和一个时间戳)消息以一个个id的方式组合起来。consumer会选择一个topic,通过id指定从哪个位置开始消费消息(使用数据)消费完成之后会保留id(offset)下次可以直接从这个id继续进行消费,也可以从任意位置进行消费。消费者可以根据需求,指定offset进行消费
重要名词解释

  • Partition: topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。
  • offset:(偏移量)每个partition都由一系列有序的、不可变的消息组成,这些消息被连续的追加到partition中。partition中的每个消息都有一个连续的序列号叫做offset,用于partition唯一标识一条消息.

Kafka为什么那么快:

  • 生产者(写入数据):生产者(producer)是负责向Kafka(broker)提交数据的,Kafka会把收到的消息都写入到硬盘中(broker),它绝对不会丢失数据。为了优化写入速度Kafka采用了两个技术,顺序写入和MMFile。
    • 顺序写入:因为硬盘是机械结构,每次读写都会寻址(offset)->写入,其中寻址是一个“机械动作”,它是最耗时的。所以硬盘最“讨厌”随机I/O,最喜欢顺序I/O。为了提高读写硬盘的速度,Kafka就是使用顺序I/O。每一个Partition其实都是一个文件,收到消息后Kafka会把数据插入到文件末尾(消息存储在partition是顺序存储(offset))这种方法有一个缺陷——没有办法删除数据,所以Kafka是不会删除数据的(话题保留策略),它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到了第几条数据。
    • Memory Mapped Files(mmf):即便是顺序写入硬盘,硬盘的访问速度还是不可能追上内存。所以Kafka的数据并不是实时的写入硬盘,它充分利用了现代操作系统分页存储来利用内存提高I/O效率。mmf也被翻译成内存映射文件,在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。

Kafka特点:

  • 支持高Throughput(高吞吐量)的应用,源自多分区
  • 无需停机即可扩展机器。每一个topic中保留的消息非常庞大,通过partition将消息切分成多个子消息,并通过负载均衡策略将partition分配到不同的server中,这样当机器负载重的时候通过扩容集群将消息从新分配。
  • 持久化:通过将数据持久化到硬盘以及replication防止数据丢失
  • 支持online(实时消费)和offline(离线消费,比如按天消费)的场景
  • 依赖Zookeeer集群,状态信息都写在Zookeeer集群里