Kakfa在大数据消息引擎领域,绝对是没有争议的国民老公。mysql
这是kafka系列的第一篇文章。预计共出20篇系列文章,所有原创,从0到1,跟你一块儿死磕kafka。sql
本文盘点了 Kafka 的各类术语而且进行解读,术语可能比较枯燥,但真的是精髓中的精髓!数据库
了解Kafka以前咱们必须先掌握它的相关概念和术语,这对于后面深刻学习 Kafka 各类功能将大有裨益。因此,枯燥你也得给我看完!编程
大概是有这么些东西要掌握,很少很少,预计20分钟能够吃透:数组
主题层有三个儿子,分别叫作:Topic、Partition、Replica。既然我说是三个儿子,那你懂了,是不可分割的总体。缓存
Kafka 是分布式的消息引擎系统,它的主要功能是提供一套完备的消息(Message)发布与订阅解决方案。服务器
在 Kafka 中,发布订阅的对象是主题(Topic),你能够为每一个业务、每一个应用甚至是每类数据都建立专属的主题。网络
一个Topic是对一组消息的概括。也能够理解成传统数据库里的表,或者文件系统里的一个目录。架构
一个Topic一般都是由多个partition组成的,建立topic时候能够指定partition数量。负载均衡
📷 分区优点
为何须要将Topic分区呢?若是你了解其余分布式系统,你可能据说过度片、分区域等说法,好比 MongoDB 和 Elasticsearch 中的 Sharding、HBase 中的 Region,其实它们都是相同的原理。
试想,若是一个Topic积累了太多的数据以致于单台 Broker 机器都没法容纳了,此时应该怎么办呢?
一个很天然的想法就是,可否把数据分割成多份保存在不一样的机器上?这不就是分区的做用吗?其实就是解决伸缩性的问题,每一个partition均可以放在独立的服务器上。
固然优点不只于此,也能够提升吞吐量。kafka只容许单个partition的数据被一个consumer线程消费。所以,在consumer端,consumer并行度彻底依赖于被消费的分区数量。综上所述,一般状况下,在一个Kafka集群中,partition的数量越多,意味着能够到达的吞吐量越大。
📷 partition结构
每一个partition对应于一个文件夹,该文件夹下存储该partition的数据和索引文件。
如图所示,能够看到两个文件夹,都对应着一个叫作asd的topic,在该台服务器上有两个分区,0和2,那么1呢?在其余服务器上啦!毕竟是分布式分布的!
咱们进去asd-0目录中看看是什么?有后缀为.index和.log的文件,他们就是该partition的数据和索引文件:
如今先无论它们是何方神圣,由于我会在【分区机制原理】这篇文章中详细描述。
📷 partition顺序性
如今,我须要你睁大眼睛看看关于分区很是重要的一点:
【每一个partition内部保证消息的顺序。可是分区之间是不保证顺序的】
这一点很重要,例如kafka中的消息是某个业务库的数据,mysql binlog是有前后顺序的,10:01分我没有付款,因此pay_date为null,而10:02分我付款了,pay_date被更新了。
但到了kafka那,因为是分布式的,多分区的,可就不必定能保证顺序了,也许10:02分那条先来,这样可就会引起严重生产问题了。所以,通常咱们须要按表+主键来分区。保证同一主键的数据发送到同一个分区中。
若是你想要 kafka 中的全部数据都按照时间的前后顺序进行存储,那么能够设置分区数为 1。
每一个partition能够配置若干个副本。Kafka 定义了两类副本:领导者副本(Leader Replica)和追随者副本(Follower Replica)。只能有 1 个领导者副本和 N-1 个追随者副本。
为啥要用副本?也很好理解,反问下本身为何重要的文件须要备份多份呢?备份机制(Replication)是实现高可用的一个手段。
须要注意的是:仅Leader Replica对外提供服务,与客户端程序进行交互,生产者老是向领导者副本写消息,而消费者老是从领导者副本读消息。而Follower Replica不能与外界进行交互,它只作一件事:向领导者副本发送请求,请求领导者把最新生产的消息发给它,保持与领导者的同步。
若是对于刚刚所说的主题、分区、副本还有疑惑,那么结合下面这张图再思考一下,我相信你就能够玩转它了:
下图所示,TopicA,具备三个partition,每一个partion都有1 个leader副本和 1 个follower者副本。为了保证高可用性,一台机器宕机不会有影响,所以leader副本和follower副本必然分布在不一样的机器上。
Kafka的官方定义是message system,由此咱们能够知道Kafka 中最基本的数据单元无疑是消息message,它可理解成数据库里的一条行或者一条记录。消息是由字符数组组成。关于消息你必须知道这几件事:
📷 消息key
发送消息的时候指定 key,这个 key 也是个字符数组。key 用来肯定消息写入分区时,进入哪个分区。你能够用有明确业务含义的字段做为key,好比用户号,这样就能够保证同一个用户号进入同一个分区。
📷 批量写入
为了提升效率, Kafka 以批量batch的方式写入。
一个 batch 就是一组消息的集合, 这一组的数据都会进入同一个 topic 和 partition(这个是根据 producer 的配置来定的) 。
每个消息都进行一次网络传输会很消耗性能,所以把消息收集到一块儿再同时处理就高效的多。
固然,这样会引入更高的延迟以及吞吐量:batch 越大,同一时间处理的消息就越多。batch 一般都会进行压缩,这样在传输以及存储的时候效率都更高一些。
📷 位移 生产者向分区写入消息,每条消息在分区中的位置信息由一个叫位移(Offset)的数据来表征。分区位移老是从 0 开始,假设一个生产者向一个空分区写入了 10 条消息,那么这 10 条消息的位移依次是 0、一、二、…、9。
Kafka 的服务器端由被称为 Broker 的服务进程构成,即一个 Kafka 集群由多个 Broker 组成,Kafka支持水平扩展,broker数量越多,集群吞吐量越高。在集群中每一个broker都有一个惟一brokerid,不得重复。Broker 负责接收和处理客户端发送过来的请求,以及对消息进行持久化。
通常会将不一样的 Broker 分散运行在不一样的机器上,这样若是集群中某一台机器宕机,kafka能够自动选举出其余机器上的 Broker 继续对外提供服务。这其实就是 Kafka 提供高可用的手段之一。
📷 controller
Kafka集群中会有一个或者多个broker,其中有且仅有一个broker会被选举为控制器(Kafka Controller),它负责管理整个集群中全部分区和副本的状态。
当某个分区的leader副本出现故障时,由控制器负责为该分区选举新的leader副本。当检测到某个分区的ISR集合发生变化时,由控制器负责通知全部broker更新其元数据信息。当为某个topic增长分区数量时,一样仍是由控制器负责分区的从新分配。
这几句话可能会让你以为困惑不要方 只是突出下控制器的职能不少,而这些功能的具体细节会在后面的文章中作具体的介绍。
Kafka中的控制器选举的工做依赖于Zookeeper,成功竞选为控制器的broker会在Zookeeper中建立/controller这个临时(EPHEMERAL)节点,此临时节点的内容参考以下:
其中version在目前版本中固定为1,brokerid表示称为控制器的broker的id编号,timestamp表示竞选称为控制器时的时间戳。
Kafka有两种客户端。生产者和消费者。咱们把生产者和消费者统称为客户端(Clients)。
向主题Topic发布消息Message的客户端应用程序称为生产者(Producer),生产者程序一般持续不断地向一个或多个主题发送消息。
而订阅这些主题消息的客户端应用程序就被称为消费者(Consumer)。和生产者相似,消费者也可以同时订阅多个主题的消息。
Producer 用来建立Message。在发布订阅系统中,他们也被叫作 Publisher 发布者或 writer 写做者。
一般状况下,会发布到特定的Topic,并负责决定发布到哪一个分区(一般简单的由负载均衡机制随机选择,或者经过key,或者经过特定的分区函数选择分区。) Producer分为Sync Producer 和 Aync Producer。
Sync Producer同步的生产者,即必定要某条消息成功才会发送下一条。因此它是低吞吐率、通常不会出现数据丢失。
Aync Producer异步的生产者,有个队列的概念,是直接发送到队列里面,批量发送。高吞吐率、可能有数据丢失的。
📷 消费者
Consumer 读取消息。在发布订阅系统中,也叫作 subscriber 订阅者或者 reader 阅读者。消费者订阅一个或者多个主题,而后按照顺序读取主题中的数据。
📷 消费位移
消费者须要记录消费进度,即消费到了哪一个分区的哪一个位置上,这是消费者位移(Consumer Offset)。注意,这和上面所说的消息在分区上的位移彻底不是一个概念。上面的“位移”表征的是分区内的消息位置,它是不变的,即一旦消息被成功写入到一个分区上,它的位移值就是固定的了。
而消费者位移则不一样,它多是随时变化的,毕竟它是消费者消费进度的指示器嘛。经过存储最后消费的 Offset,消费者应用在重启或者中止以后,还能够继续从以前的位置读取。保存的机制能够是 zookeeper,或者 kafka 本身。
📷 消费者组
ConsumerGroup:消费者组,指的是多个消费者实例组成一个组来消费一组主题,分区只能被消费者组中的其中一个消费者去消费,组员之间不能重复消费。
为何要引入消费者组呢?主要是为了提高消费者端的吞吐量。多个消费者实例同时消费,加速整个消费端的吞吐量(TPS)。
固然它的做用不只仅是瓜分订阅主题的数据,加速消费。它们还能彼此协助。假设组内某个实例挂掉了,Kafka 可以自动检测到,而后把这个 Failed 实例以前负责的分区转移给其余活着的消费者,这个过程称之为重平衡(Rebalance)。
你务必先把这个词记住,它是kafka大名鼎鼎的重平衡机制,生产出现的异常问题不少都是因为它致使的。后续我会在【kafka大名鼎鼎又臭名昭著的重平衡】文章中详细分析。
zookeeper目前在kafka中扮演着举重轻重的角色和做用~是kafka不可缺乏的一个组件。
目前,Apache Kafka 使用 Apache ZooKeeper 来存储它的元数据,好比brokers信息、分区的位置和主题的配置等数据就是存储在 ZooKeeper 集群中。
注意个人用词,我只说是目前。why?在 2019 年社区提出了一个计划,以打破这种依赖关系,并将元数据管理引入 Kafka 自己。由于拥有两个系统会致使大量的重复。
在以前的设计中,咱们至少须要运行三个额外的 Java 进程,有时甚至更多。事实上,咱们常常看到具备与 Kafka 节点同样多的 ZooKeeper 节点的 Kafka 集群!此外,ZooKeeper 中的数据还须要缓存在 Kafka 控制器上,这致使了双重缓存。
更糟糕的是,在外部存储元数据限制了 Kafka 的可伸缩性。当 Kafka 集群启动时,或者一个新的控制器被选中时,控制器必须从 ZooKeeper 加载集群的完整状态。随着元数据数量的增长,加载过程须要的时间也会增长,这限制了 Kafka 能够存储的分区数量。
最后,将元数据存储在外部会增长控制器的内存状态与外部状态不一样步的可能性。
所以,将来,Kafka 的元数据将存储在 Kafka 自己中,而不是存储在 ZooKeeper 之类的外部系统中。能够持续关注kafka社区动态哦!
一个典型的kafka集群包含若干个producer(向主题发布新消息),若干consumer(从主题订阅新消息,用Consumer Offset表征消费者消费进度),cousumergroup(多个消费者实例共同组成的一个组,共同消费多个分区),若干broker(服务器端进程)。还有zookeeper。
kafka发布订阅的对象叫主题,每一个Topic下能够有多个Partition,Partition中每条消息的位置信息又叫作消息位移(Offset),Partition有副本机制,使得同一条消息可以被拷贝到多个地方以提供数据冗余,副本分为领导者副本和追随者副本。
能够用下面这张图来形象表达kafka的组成:
另外,再po一张思惟导图助你回顾本文所述的术语。
重要!!关注【胖滚猪学编程】公众号发送"kafka"。获取本文全部架构图以及Kafka全系列思惟导图!
本文来源于公众号:【胖滚猪学编程】。一枚集颜值与才华于一身,不算聪明却足够努力的女程序媛。用漫画形式让编程so easy and interesting!求关注!