kafka消息队列的简单理解
kafka在大数据、分布式架构中都很流行。kafka可以进行流式计算,也可以做为日志系统,还可以用于消息队列。
本篇主要是kafka消息队列相关的知识。
零、kafka作为消息队列的优点:
高吞吐、低延迟
:kakfa 最大的特点就是收发消息非常快,kafka 每秒可以处理几十万条消息,它的最低延迟只有几毫秒。高伸缩性
: 每个主题(topic) 包含多个分区(partition),主题中的分区可以分布在不同的主机(broker)中。持久性、可靠性
: Kafka 能够允许数据的持久化存储,消息被持久化到磁盘,而且是顺序写,顺序写的效率比随机写的高很多,并支持数据备份防止数据丢失。Kafka 底层的数据存储是基于 Zookeeper 存储的,Zookeeper 我们知道它的数据能够持久存储。容错性
: 允许集群中的节点失败,某个节点宕机,Kafka 集群能够正常工作高并发
: 支持数千个客户端同时读写
一、pull模式
消息队列有push模式和pull模式。push模式是消息队列推送给消息消费者,pull模式是消息消费者从消息队列中拉取。
kafka使用了pull模式:消费者采用轮询的方式定期去 Kafka Broker 中进行数据的检索,如果有数据就用来消费,如果没有就再继续轮询等待。
二、发布 - 订阅消息系统
kafka是一个分布式的发布 - 订阅(pub-sub)消息系统。
在发布 - 订阅系统中,消息被保留在主题中。 消费者可以订阅一个或多个主题并使用该主题中的所有消息。
消息生产者称为发布者,消息使用者称为订阅者。
比如,购物网站,有一个订单系统,还有一个物流系统,消息队列可以作为两个系统的消息中间件,订单系统可以将订单数据发送给kafka消息队列,然后物流系统再从消息队列中订阅得到订单数据。
三、角色和组件
消息:
Kafka 中的数据单元被称为消息,也被称为记录,可以把它看作数据库表中某一行的记录。
批次:
为了提高效率, 消息会分批次写入 Kafka,批次就代指的是一组消息。
Topics(主题)
消息的种类称为 主题(Topic),可以说一个主题代表了一类消息。相当于是对消息进行分类。
Partition(分区)
主题(Topic)可以被分为若干个分区(partition),同一个主题中的分区可以不在一个机器上,有可能会部署在多个机器上,
同一个主题的不同分区包含的消息是不同的。
由此来实现 kafka 的伸缩性,单一主题中的分区有序,但是无法保证主题中所有的分区有序。
Producer (消息生产者)
向主题发布消息的客户端应用程序称为生产者
(Producer),生产者用于持续不断的向某个主题发送消息。
Consumer (消息消费者)
订阅主题消息的客户端程序称为消费者
(Consumer),消费者用于处理生产者产生的消息。
Consumer Group (消费者组)
每个消费者属于一个特定的消费者群组(可为每个消费者指定group name,若不指定group name则属于默认的group)。
每个消费者群组都有一个唯一的GroupId。
offset(偏移量)
每个分区消息具有称为 offset
的唯一序列标识。类似数据库自增int Id,随着数据的不断写入 kafka 分区内的偏移量会不断增加,一条消息由一个唯一的偏移量来标识。
偏移量的作用是,让消费者知道自己消费到了哪个位置,下次可以接着从这里消费
Replicas of partition(分区备份)
副本只是一个分区的备份
。 副本从不读取或写入数据。 它们用于防止数据丢失。
Brokers(kafka服务器)
一个独立的 Kafka 服务器就被称为 broker
,broker 接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。
一个broker可以容纳多个topic。每个broker都有各自的broker.id。
Kafka Cluster(Kafka集群)
Kafka有多个代理被称为Kafka集群。 可以扩展Kafka集群,无需停机。 这些集群用于管理消息数据的持久性和复制。
Leader(领导者)
Leader是负责给定分区的所有读取和写入的节点。 每个分区都有一个服务器充当Leader
Follower(追随者)
跟随Leader指令的节点被称为Follower。 如果Leader失效,一个Follower将自动成为新的领导者。 跟随者作为正常消费者,拉取消息并更新其自己的数据存储。
Rebalance (重平衡)
新加入群组的消费者实例分摊了最初消费者的部分消息,这种把分区的所有权通过一个消费者转到其他消费者的行为称为重平衡。
消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。
Rebalance 是 Kafka 消费者端实现高可用的重要手段。
消费者通过向Kafka Broker发送心跳来维护自己是消费者组的一员并确认其拥有的分区。对于不同的消费群体来说,其组织协调者可以是不同的。只要消费者定期发送心跳,就会认为消费者是存活的并处理其分区中的消息。当消费者检索记录或者提交它所消费的记录时就会发送心跳。
如果过了一段时间 Kafka 停止发送心跳了,会话(Session)就会过期,组织协调者就会认为这个 Consumer 已经死亡,就会触发一次重平衡。如果消费者宕机并且停止发送消息,组织协调者会等待几秒钟,确认它死亡了才会触发重平衡。在这段时间里,死亡的消费者将不处理任何消息。在清理消费者时,消费者将通知协调者它要离开群组,组织协调者会触发一次重平衡,尽量降低处理停顿。
四、Kafka架构
五、kafka主题、分区和消费者的关系
如下图所示:P表示Partition(分区)。Cluster是集群。C是消费者。
1.kafka每个分区,只能被消费者群组中的一个消费者消费。
假设同一群组内的多个消费者负责同一个分区,那么会有什么问题呢?
倘若,同一群组内的两个消费者负责同一个分区,那么就意味着两个消费者同时读取分区的消息,由于消费者自己可以控制读取消息的offset,就有可能C1才读到2,而C1读到1,C1还没处理完,C2已经读到3了,则会造成很多浪费,因为这会造成消息处理的重复,且不能保证消息的顺序。
2.可以往消费者群组中增加消费者,提高消息处理效率,但是不要让消费者的数量超过主题分区的数量。
如果消费者消费的速度已经跟不上生产者生产的速度,那么可以在消费者群组内增加更多的消费者,让它们分担负载,这个就是伸缩性的表现。
可以在主题(Topic)中创建大量的分区,在负载增长时可以加入更多的消费者。不过要注意,不要让消费者的数量超过主题分区的数量,多余的消费者只会被闲置。
3.不同的消费者群组可以从同一主题获取所有的消息,消费者群组G1和消费者群组G2之间互不影响。
多个应用程序可以从同一主题获取到所有的消息。
只要保证每个订阅的应用程序都有自己的不同的消费者群组,每个订阅的应用程序都可以从同一主题获取所有的消息,而不只是其中的一部分。
六、kafka的性能好在什么地方?
1. 顺序写
操作系统每次从磁盘读写数据的时候,需要先寻址,也就是先要找到数据在磁盘上的物理位置,然后再进行数据读写,如果是机械硬盘,寻址就需要较长的时间。 kafka的设计中,数据其实是存储在磁盘上面,一般来说,会把数据存储在内存上面性能才会好。但是kafka用的是顺序写,追加数据是追加到末尾,磁盘顺序写的性能极高,在磁盘个数一定,转数达到一定的情况下,基本和内存速度一致
随机写的话是在文件的某个位置修改数据,性能会较低。
2. 零拷贝
先来看看非零拷贝的情况:
参考资料:
《Kafka权威经典指南》