前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kafka的生成者、消费者、broker的基本概念

Kafka的生成者、消费者、broker的基本概念

作者头像
chenchenchen
发布2019-09-03 11:56:17
5.5K0
发布2019-09-03 11:56:17
举报
文章被收录于专栏:chenchenchen

kafka是一款基于发布与订阅的消息系统。它一般被称为“分布式提交日志”或者“分布式流平台”。文件系统或者数据库提交日志用来提供所有事物的持久化记录,通过重建这些日志可以重建系统的状态。同样地,kafka的数据是按照一定顺序持久化保存的,可以按需读取。

  • 1、kafka拓扑结构
  • 2、Kafka的特点
  1. 同时为分布和订阅提供高吞吐量。据了解,Kafka每秒可以生产约25万条消息(50MB),每秒处理55万条消息(110MB)这里说条数,可能不上特别准确,因为消息的大小可能不一致;
  2. 可进行持久化操作,将消息持久化到到磁盘,以日志的形式存储,因此可用于批量消费,例如ETL,以及实时应用程序。 通过将数据持久化到硬盘以及replication防止数据丢失。
  3. 分布式系统,易于向外拓展。所有的Producer、broker和consumer都会有多个,均为分布式。无需停机即可拓展机器。
  4. 消息被处理的状态是在consumer端维护,而不是由server端维护,当失败时能自动平衡。
  5. 支持Online和offline的场景。
  • 3、Kafka的核心概念

名词

解释

Producer

消息的生成者

Consumer

消息的消费者

ConsumerGroup

消费者组,可以并行消费Topic中的partition的消息

Broker

缓存代理,Kafka集群中的一台或多台服务器统称broker.

Topic

Kafka处理资源的消息源(feeds of messages)的不同分类

Partition

Topic物理上的分组,一个topic可以分为多个partion,每个partion是一个有序的队列。partion中每条消息都会被分 配一个 有序的Id(offset)

Message

消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息

Producers

消息和数据生成者,向Kafka的一个topic发布消息的 过程叫做producers

Consumers

消息和数据的消费者,订阅topic并处理其发布的消费过程叫做consumers

  • 3.1 Producers的概念
  1. 消息和数据生成者,向Kafka的一个topic发布消息的过程叫做producers
  2. Producer将消息发布到指定的Topic中,同时Producer也能决定将此消息归属于哪个partition;比如基于round-robin方式 或者通过其他的一些算法等;
  3. 异步发送批量发送可以很有效的提高发送效率。kafka producer的异步发送模式允许进行批量发送,先将消息缓存到内存中,然后一次请求批量发送出去。
  • 3.2 broker的概念:
  1. Broker没有副本机制,一旦broker宕机,该broker的消息将都不可用。
  2. Broker不保存订阅者的状态,由订阅者自己保存。
  3. 无状态导致消息的删除成为难题(可能删除的消息正在被订阅),Kafka采用基于时间的SLA(服务保证),消息保存一定时间(通常7天)后会删除。
  4. 消费订阅者可以rewind back到任意位置重新进行消费,当订阅者故障时,可以选择最小的offset(id)进行重新读取消费消息
  • 3.3 Message组成
  1. Message消息:是通信的基本单位,每个producer可以向一个topic发布消息。
  2. Kafka中的Message是以topic为基本单位组织的,不同的topic之间是相互独立的,每个topic又可以分成不同的partition每个partition储存一部分
  3. partion中的每条Message包含以下三个属性:

offset

long

MessageSize

int32

data

messages的具体内容

  • 3.4 Consumers的概念

消息和数据消费者,订阅topic并处理其发布的消息的过程叫做consumers. 在kafka中,我们可以认为一个group是一个“订阅者”,一个topic中的每个partions只会被一个“订阅者”中的一个consumer 消费,不过一个consumer可以消费多个partitions中的消息 注: Kafka的设计原理决定,对于一个topic,同一个group不能多于partition个数的consumer同时消费,否则将意味着某些 consumer无法得到消息

关键术语

主题,分区和偏移

主题是特定的数据流。它与NoSQL数据库中的表非常相似。与NoSQL数据库中的表一样,该主题被拆分为分区,使主题能够分布在各个节点上。与表中的主键一样,主题具有每个分区的偏移量。您可以使用其主题,分区和偏移量唯一标识消息。

分区

分区使主题可以在群集中分布。分区是水平可伸缩性的并行度单位。一个主题可以跨节点进行多个分区扩展。

消息根据分区键分配给分区; 如果没有分区键,则随机分配该分区。使用正确的密钥来避免热点非常重要。

分区中的每个消息都被分配一个称为偏移量的增量ID。每个分区的偏移量是唯一的,消息只在分区内排序。写入分区的消息是不可变的。

Kafka架构图

ZooKeeper

ZooKeeper是一种用于管理分布式系统的集中式服务。它为其管理的分布式系统提供分层键值存储,配置,同步和名称注册服务。ZooKeeper充当集合层(将事物联系在一起)并确保Kafka集群的高可用性。Kafka节点也称为代理。重要的是要理解Kafka在没有ZooKeeper的情况下无法工作。

从ZooKeeper节点列表中,其中一个节点被选为领导者,其余节点跟随领导者。在ZooKeeper节点发生故障的情况下,其中一个关注者被选为领导者。强烈建议使用多个节点以实现高可用性,不建议使用超过7个节点。

ZooKeeper存储元数据和Kafka集群的当前状态。例如,主题名称,分区数量,复制,请愿的领导者详细信息以及消费者组详细信息等详细信息存储在ZooKeeper中。您可以将ZooKeeper视为项目经理,他负责管理项目中的资源并记住项目的状态。

关键事项:

管理经纪人名单。

当经纪人破产时选举经纪人领导。

发送有关新代理、新主题、已删除主题、丢失代理等的通知。

从Kafka0.10开始,消费者偏移不存储在ZooKeeper中,只有集群的元数据存储在ZooKeepr中。

ZooKeepr中的领导者处理所有写入和跟随者ZooKeepr只处理读取。

Broker

一个broker是由ZooKeeper管理的单个Kafka节点。一组brokers组成了Kafka集群。在Kaka中创建的主题基于分区,复制和其他因素分布在broker中。当broker节点基于ZooKeeper中存储的状态失败时,它会自动重新平衡群集,如果领导分区丢失,则其中一个跟随者请求被选为领导者。

您可以将broker视为负责分配任务的团队负责人。如果团队负责人不可用,那么经理负

责将任务分配给其他团队成员。

复制

复制正在另一个代理中提供分区的副本。复制使Kafka具有容错能力。当主题的分区在

多个代理中可用时,代理中的一个分区被选为领导者,而分区的其余复制是跟随者。

复制使Kafka即使在代理关闭时也具有容错能力。例如,主题B分区0存储在代理0和代理1中。生产者和消费者都只由领导者提供服务。在代理失败的情况下,来自另一个代理的分区被选为领导者,并且它开始为生产者和消费者群体提供服务。与领导同步的副本分区标记为ISR(同步副本)。

IT团队和Kafka集群类比

下图描绘了IT团队和Kafka集群的类比。

摘要

以下是Kafka核心组件的摘要。

ZooKeeper管理Kafka经纪人及其元数据。

代理是可水平扩展的Kafka节点,包含主题和复制。

主题是具有一个或多个分区的消息流。

分区包含每个分区具有唯一偏移量的消息。

复制使Kafka能够使用跟随分区进行容错。

4. Kafka为什么速度那么快?

Kafka的消息是保存或缓存在磁盘上的,一般认为在磁盘上读写数据是会降低性能的,因为寻址会比较消耗时间,但是实际上,Kafka的特性之一就是高吞吐率。

即使是普通的服务器,Kafka也可以轻松支持每秒百万级的写入请求,超过了大部分的消息中间件,这种特性也使得Kafka在日志处理等海量数据场景广泛应用。

针对Kafka的基准测试可以参考,Apache Kafka基准测试:每秒写入2百万(在三台廉价机器上)

下面从数据写入和读取两方面分析,为什么Kafka速度这么快。

一、写入数据

Kafka会把收到的消息都写入到硬盘中,它绝对不会丢失数据。为了优化写入速度Kafka采用了两个技术, 顺序写入和MMFile

1、顺序写入

磁盘读写的快慢取决于你怎么使用它,也就是顺序读写或者随机读写。在顺序读写的情况下,磁盘的顺序读写速度和内存持平。

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

而且Linux对于磁盘的读写优化也比较多,包括read-ahead和write-behind,磁盘缓存等。如果在内存做这些操作的时候,一个是JAVA对象的内存开销很大,另一个是随着堆内存数据的增多,JAVA的GC时间会变得很长,使用磁盘操作有以下几个好处:

1、顺序写入磁盘顺序读写速度超过内存随机读写

2、顺序写入JVM的GC效率低,内存占用大。使用磁盘可以避免这一问题

3、顺序写入系统冷启动后,磁盘缓存依然可用

下图就展示了Kafka是如何写入数据的, 每一个Partition其实都是一个文件 ,收到消息后Kafka会把数据插入到文件末尾(虚框部分):

这种方法有一个缺陷——没有办法删除数据 ,所以Kafka是不会删除数据的,它会把所有的数据都保留下来,每个消费者(Consumer)对每个Topic都有一个offset用来表示读取到了第几条数据 。

两个消费者:

1、顺序写入Consumer1有两个offset分别对应Partition0、Partition1(假设每一个Topic一个Partition);

2、顺序写入Consumer2有一个offset对应Partition2。

这个offset是由客户端SDK负责保存的,Kafka的Broker完全无视这个东西的存在;一般情况下SDK会把它保存到Zookeeper里面,所以需要给Consumer提供zookeeper的地址。

如果不删除硬盘肯定会被撑满,所以Kakfa提供了两种策略来删除数据:

1、顺序写入一是基于时间。

2、顺序写入二是基于partition文件大小。

具体配置可以参看它的配置文档

2、Memory Mapped Files

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

Memory Mapped Files(后面简称mmap)也被翻译成 内存映射文件 ,在64位操作系统中一般可以表示20G的数据文件,它的工作原理是直接利用操作系统的Page来实现文件到物理内存的直接映射。

完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。

通过mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存),也不必关心内存的大小有虚拟内存为我们兜底。

使用这种方式可以获取很大的I/O提升,省去了用户空间到内核空间复制的开销(调用文件的read会把数据先放到内核空间的内存中,然后再复制到用户空间的内存中。)

但也有一个很明显的缺陷——不可靠,写到mmap中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用flush的时候才把数据真正的写到硬盘。

Kafka提供了一个参数——producer.type来控制是不是主动flush,如果Kafka写入到mmap之后就立即flush然后再返回Producer叫 同步 (sync);写入mmap之后立即返回Producer不调用flush叫异步 (async)。

二、读取数据

Kafka在读取磁盘时做了哪些优化?

1、基于sendfile实现Zero Copy

传统模式下,当需要对一个文件进行传输的时候,其具体流程细节如下:

1、基于sendfile实现Zero Copy调用read函数,文件数据被copy到内核缓冲区

2、read函数返回,文件数据从内核缓冲区copy到用户缓冲区

3、write函数调用,将文件数据从用户缓冲区copy到内核与socket相关的缓冲区。

4、数据从socket缓冲区copy到相关协议引擎。

以上细节是传统read/write方式进行网络文件传输的方式,我们可以看到,在这个过程当中,文件数据实际上是经过了四次copy操作:

硬盘—>内核buf—>用户buf—>socket相关缓冲区—>协议引擎

而sendfile系统调用则提供了一种减少以上多次copy,提升文件传输性能的方法。

在内核版本2.1中,引入了sendfile系统调用,以简化网络上和两个本地文件之间的数据传输。sendfile的引入不仅减少了数据复制,还减少了上下文切换。

sendfile(socket, file, len);

运行流程如下:

1、sendfile系统调用,文件数据被copy至内核缓冲区

2、再从内核缓冲区copy至内核中socket相关的缓冲区

3、最后再socket相关的缓冲区copy到协议引擎

相较传统read/write方式,2.1版本内核引进的sendfile已经减少了内核缓冲区到user缓冲区,再由user缓冲区到socket相关缓冲区的文件copy,而在内核版本2.4之后,文件描述符结果被改变,sendfile实现了更简单的方式,再次减少了一次copy操作。

在Apache、Nginx、lighttpd等web服务器当中,都有一项sendfile相关的配置,使用sendfile可以大幅提升文件传输性能。

Kafka把所有的消息都存放在一个一个的文件中,当消费者需要数据的时候Kafka直接把文件发送给消费者,配合mmap作为文件读写方式,直接把它传给sendfile。

2、批量压缩

在很多情况下,系统的瓶颈不是CPU或磁盘,而是网络IO,对于需要在广域网上的数据中心之间发送消息的数据流水线尤其如此。进行数据压缩会消耗少量的CPU资源,不过对于kafka而言,网络IO更应该需要考虑。

1、如果每个消息都压缩,但是压缩率相对很低,所以Kafka使用了批量压缩,即将多个消息一起压缩而不是单个消息压缩

2、Kafka允许使用递归的消息集合,批量的消息可以通过压缩的形式传输并且在日志中也可以保持压缩格式,直到被消费者解压缩

3、Kafka支持多种压缩协议,包括Gzip和Snappy压缩协议

三、总结

Kafka速度的秘诀在于,它把所有的消息都变成一个批量的文件,并且进行合理的批量压缩,减少网络IO损耗,通过mmap提高I/O速度,写入数据的时候由于单个Partion是末尾添加所以速度最优;读取数据的时候配合sendfile直接暴力输出。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019年05月15日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4. Kafka为什么速度那么快?
    • 一、写入数据
      • 二、读取数据
        • 三、总结
        相关产品与服务
        对象存储
        对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档