Apache Kafka

1. 简介

Kafka 是linkedin 公司用于日志处理的分布式消息队列,同时支持离线和在线日志处理。kafka 对消息保存时根据Topic进行归类,发送消息者成为Producer,消息接受者成为Consumer,此外kafka 集群有多个kafka 实例组成,每个实例(server)称为broker。无论是kafka集群,还是producer和consumer 都依赖于zookeeper 来保证系统可用性,为集群保存一些meta 信息。
Kafka 是一种分布式的、分区的、多副本的基于发布/订阅的消息系统。它是通过 zookeeper 进行协调,常见可以用于 web/nginx 日志、访问日志、消息服务等。主要应用场景为:日志收集系统和消息系统。

Kafka 的主要设计目标如下:

  1. 以时间复杂度为 O(1) 的方式提供持久化能力,即使对 TB 级别以上的数据也能保证常数时间的访问性能。
  2. 高吞吐率,即使在十分廉价的机器上也能实现单机支持每秒 100K 条消息的传输。
  3. 支持 Kafka Server (即 Kafka 集群的服务器)间的消息分区,及分布式消费,同时保证每个 partition 内的消息顺序传输。
  4. 同时支持离线数据处理和实时数据处理

2. Kafka 架构

一个 Kafka 集群由若干producer、若干consumer、若干broker,以及一个zookeeper集群所组成。
Kafka通过zookeeper管理集群配置,选举leader,以及在consumer group发生变化时进行rebalance。producer使用push模式将消息发布到broker,consumer使用pull模式从broker订阅并消费消息。

Kafka名词解释:

  • broker:Kafka是由多个服务器组成的机器,每个服务器称作代理(broker)消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群,相当于物理层面上的一台服务器。

  • topic:Kafka维护消息类别的东西是主题(topic)。存放同一类消息的位置,是一个概念层面上的名词,Kafka集群可以负责多个topic的分发。(物理上不同topic的消息分开存储,逻辑上一个topic的消息虽然保存于一个或多个broker上但用户只需指定消息的topic即可生产或消费数据而不必关心数据存于何处)

  • partition:topic在物理层面上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列,创建topic时可以指定partition数量,每个partition对应于一个文件夹,该文件夹下存储该partition的数据和索引文件。一般来说partition的数量大于等于broker的数量。

  • producer:负责发布消息到Kafka broker(生产者)

  • consumer:消费消息,每个consumer属于一个特定的consumer group(可为每个consumer指定group name,若不指定group name则为默认的group)。使用consumer high level API时,同一topic的一条消息只能被一个consumer group的一个consumer消费,但多个consumer group可同时消费这条消息。

  • consumer group:每个consumer属于一个特定的consumer group,consumer group是实际记录的概念。

3. 主题(Topics),日志(Logs)

一个Topic 可以认为是一类消息,每个topic 将被分成多个partition(区),每个partition 在存储层面是append log 文件。任何发布到此partition 的消息都会被直接追加到log 文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset 为一个long型数字,它是唯一标记一条消息。kafka 并没有提供其他额外的索引机制来存储offset,因为在kafka 中几乎不允许对消息进行“随机读写”。
每个分区就是一个提交日志:每个分区上保存着不断被追加的消息,这些消息是有序的且顺序不可改变;分区上的每个消息都被分配了一个序列号offset,offset唯一标识了分区上的消息。

在kafka 中,即使消息被消费,消息仍然不会被立即删除。日志文件将会根据broker 中的配置要求,保留一定的时间之后删除;比如log 文件保留2 天,那么两天后,文件会被清除,无论其中的消息是否被消费。kafka 通过这种简单的手段,来释放磁盘空间,以及减少消息消费之后对文件内容改动的磁盘IO 开支。

对于consumer 而言,它需要保存消费消息的offset,对于offset的保存和使用, 由consumer 来控制; 当consumer 正常消费消息时,offset 将会"线性"的向前驱动,即消息将依次顺序被消费。事实上consumer 可以使用任意顺序消费消息,它只需要将offset 重置为任意值。(offset 将会保存在zookeeper 中,参见下文)

kafka集群几乎不需要维护任何consumer和producer 状态信息,这些信息由zookeeper 保存;因此producer和consumer 的客户端实现非常轻量级,它们可以随意离开,而不会对集群造成额外的影响。partitions的设计目的有多个。最根本原因是kafka基于文件存储。通过分区,可以将日志内容分散到多个server 上,来避免文件尺寸达到单机磁盘的上限,每个partiton都会被当前server(kafka实例)保存;可以将一个topic 切分多任意多个partitions来保存消息。此外越多的partitions 意味着可以容纳更多的consumer,有效提升并发消费的能力。(具体原理参见下文)。这些特性表明,Kafka的消费者是非常廉价的,一个消费者的创建、销毁不会对集群或其他消费者产生多大的影响。

对日志进行分区有几个目的:

  • 1.扩容,一个主题可以有多个分区,这使得可以保存比一个机器保存的多的多的数据。
  • 2.并行

4.分布式(Distribution)

一个Topic 的多个partitions,被分布在kafka 集群中的多个server 上;每个server(kafka 实例)负责partitions中消息的读写操作;此外kafka 还可以配置partitions 需要备份的个数(replicas),每个partition 将会被备份到多台机器上,以提高可用性。

基于replicated(冗余) 方案,那么就意味着需要对多个备份进行调度;每个partition 都有一个机器为"leader";零个或多个机器作为follower。leader 负责所有的读写操作,follower执行leader的指令。如果leader 失效,那么将会有其他follower 来接管(成为新的leader);follower只是单调的和leader 跟进,同步消息即可。由此可见作为leader 的server 承载了全部的请求压力,因此从集群的整体考虑,有多少个partitions就意味着有多少个"leader",kafka会将"leader"均衡的分散在每个实例上,来确保整体的性能稳定。

1.发送到partitions 中的消息将会按照它接收的顺序追加到日志中。
2.对于消费者而言,它们消费消息的顺序和日志中消息顺序一致。
3.如果Topic 的"replicationfactor"(备份因子)为N,那么允许N-1 个kafka实例失效。

5.生产者(Producers)

Producer 将消息发布到指定的Topic中,同时Producer 也能决定将此消息归属于哪个partition;这可以通过简单的循环的方式来实现,或者使用一些分区方法(比如根据消息的key来分区)

6.消费者(Consumers)

传统的消息传递有两种方式: 队列方式(queuing)、发布-订阅(publish-subscribe)方式.

  • 队列方式:一组消费者从机器上读消息,每个消息只传递给这组消费者中的一个。

  • 分布-订阅方式:消息被广播到所有的消费者。Kafka提供了一个消费组(consumer group)的说法来概括这两种方式。

消费者都属于一个消费组;反过来说,每个消费组中可以有多个消费者。发送到Topic的消息,只会被订阅此Topic的每个消费组中的一个消费组消费。如果所有的消费者都具有相同的消费组,这种情况和queue模式很像;消息将会在consumers之间负载均衡。如果所有的consumer 都具有不同的group,那这就是"发布-订阅",消息将会广播给所有的消费者。

在kafka 中,一个partition 中的消息只会被group 中的一个consumer 消费;每个group 中consumer 消息消费互相独立;我们可以认为一个group 是一个"订阅"者,一个Topic 中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer 可以消费多个partitions 中的消息。kafka只能保证一个partition中的消息被某个consumer 消费时,消息是顺序的。事实上,从Topic 角度来说,消息仍不是有序的。kafka 的设计原理决定,对于一个topic,同一个group 中不能有多于partitions 个数的consumer 同时消费,否则将意味着某些consumer 将无法得到消息。

1.Kafka将主题下的分区分配给消费组里的消费者,每个分区被一个消费者消费

2.消费者的数量不能超过分区数

3.Kafka只能保证分区内的消息是有序的

4.如果你想要消息是全局有序的,你可以设置主题只有一个分区,同时这意味着只能有一个消费者

7. Kafka数据传输的事务特点

    1. at most once
      这种模式下consumer fetch消息,先进行commit,再进行处理。如果再处理消息的过程中出现异常,下次重新开始工作就无法读到之前已经确认而未处理的消息。
    1. at least once
      消息至少发送一次,如果消息未能接受成功,可能会重发,直到接收成功。消费者fetch消息,然后处理消息,然后保存offset。如果消息处理成功之后,但是在保存offset阶段zookeeper异常导致保存操作未能执行成功,这就导致接下来再次fetch时可能获得上次已经处理过的消息,这就是”at least once”,原因offset没有及时的提交给zookeeper,zookeeper恢复正常还是之前offset状态。
    1. exactly once
      消息只会发送一次,Kafka中并没有严格的去实现,我们认为这种策略在Kafka中是没有必要的。
      通常情况下,Kafka默认保证at least once。
    1. Push & Pull
      作为一个消息系统,Kafka遵循了传统的方式,选择由producer向broker push消息,并由consumer从broker中pull消息。
      push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。push模式的目标就是以尽可能快的速度传递消息,但是这样很容易造成consumer来不及处理消息,典型的表现是拒绝服务以及网络拥塞。而pull模式可以根据consumer的消费能力以适当的速率消费消息。
    1. Topic & Partition
      Topic在逻辑上可以认为是一个存在的queue,每条消息都必须指定它的topic,可以简单的理解为必须指明把这条消息放进哪个queue里。为了使Kafka的吞吐率可以水平扩展,物理上把topic分成一个或多个partition,每个partition在物理上对应一个文件夹,该文件夹下存储这个partition的所有消息和索引文件。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容