kafka简单回顾

先说说遇到的坑 回顾下kafka

topic:生产组:P0\P1----P14
一个消费组:c0 c1 c2
依据Consumer的负载均衡分配
消费顺序“c0:p0-p4 c1:p5-p9 c2:p10-p14
问题:忽然发现读offset 堆积太多 增长消费者也没用
缘由: C2节点物理故障,会把数据分给C0和C1,而后C2恢复(生产上会用相似superviser重新启动挂掉的进程),再从新分配数据,这样来来回回浪费了不少时间 每次挪回都从新洗牌,新版本已经修复此问题,因此不该该随便恢复进程
解决:应该预分配节点,比正常的多一些,这样挂点一两个也没有太大影响服务器

消息系统概念

消息系统负责将数据从一个应用程序传输到另外一个应用程序
点对点消息系统和发布 - 订阅消息系统架构

kafka概念

Kafka专为分布式高吞吐量系统而设计。 与其余消息传递系统相比,Kafka具备更好的吞吐量,内置分区,复制和固有的容错能力,这使得它很是适合大规模消息处理应用程序。并发

架构

image

Topics(主题)

数据存储在主题中。Topic至关于Queue。
主题被拆分红分区。 每一个这样的分区包含不可变有序序列的消息。分区被实现为具备相等大小的一组分段文件。任何发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset为一个long型数字,它是惟一标记一条消息。它惟一的标记一条消息。kafka并无提供其余额外的索引机制来存储offset,由于在kafka中几乎不容许对消息进行“随机读写”。负载均衡

Partition(分区)

image

  • 一个Topic能够分红多个Partition,这是为了平行化处理。
  • 每一个Partition内部消息有序,其中每一个消息都有一个offset序号。
  • 一个Partition只对应一个Broker,一个Broker能够管理多个Partition。

Partition offset(分区偏移)

每一个分区消息具备称为 offset 的惟一序列标识。dom

Replicas of partition(分区备份)

副本只是一个分区的备份。 副本从不读取或写入数据。 它们用于防止数据丢失。异步

Brokers(经纪人)

代理是负责维护发布数据的简单系统。 每一个代理能够每一个主题具备零个或多个分区。
每个kafka实例(或者说每台kafka服务器节点)就是一个broker,一个broker能够有多个topicsocket

Kafka Cluster(Kafka集群)

Kafka有多个代理被称为Kafka集群。 能够扩展Kafka集群,无需停机。 这些集群用于管理消息数据的持久性和复制。分布式

Producers(生产者)

每当生产者将消息发布给代理时,代理只需将消息附加到最后一个段文件。实际上,该消息将被附加到分区。 生产者还能够向他们选择的分区发送消息。ui

Consumers(消费者)

Consumers从broker处读取数据。 消费者订阅一个或多个主题,并经过从代理中提取数据来使用已发布的消息。设计

Consumer本身维护消费到哪一个offet
offet的存放位子依据消费类型的不一样,若是JAVA API 消费则是存放在zookeeper,若是是kafka默认自带的消费则是存放在kafka自带的topic【__consumer_offsets】

每一个Consumer都有对应的group
group是==queue消费模型==:==各个Consumer消费不一样的partition,所以一个消息在group内只消费一次==
group是==publish-subscribe消费模型==:各个group各自独立消费,互不影响,所以一个消息被每一个group消费一次。
这是kafka用来实现一个topic消息的广播(发给全部的consumer)和单播(发给任意一个consumer)的手段。

image

Kafka数据处理步骤

  • 一、Producer产生消息,发送到Broker中
  • 二、Leader状态的Broker接收消息,写入到相应topic中
  • 三、Leader状态的Broker接收完毕之后,传给Follow状态的Broker做为副本备份
  • 四、Consumer消费Broker中的消息

Consumer与topic关系

kafka只支持Topic

每一个group中能够有多个consumer,每一个consumer属于一个consumer group; 一般状况下,一个group中会包含多个consumer,这样不只能够==提升topic中消息的并发消费能力,并且还能提升"故障容错"性==,若是group中的某个consumer失效那么其消费的partitions将会有其余consumer自动接管。
总结:
==一个group中的consumer只会消费一个topic的一条消息,每一个consumer消费不一样的partition。==

在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
一个Topic中的每一个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer能够同时消费多个partitions中的消息。

kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,不然将意味着某些consumer将没法获得消息。==可是在设计的时候我的以为能够多些consumer 已解决前面遇到的坑。==

Kafka消息的分发

Producer客户端负责消息的分发

kafka集群中的任何一个broker均可以向producer提供metadata信息,这些metadata中包含"集群中存活的servers列表"、"partitions leader列表"等信息;

当producer获取到metadata信息以后, producer将会和Topic下全部partition leader保持socket链接;

消息由producer直接经过socket发送到broker,中间不会通过任何"路由层"。事实上,消息被路由到哪一个partition上由producer客户端决定,好比能够采用"random""key-hash""轮询"等。

若是一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。

在producer端的配置文件中,开发者能够指定partition路由的方式。

Producer消息发送的应答机制

设置发送数据是否须要服务端的反馈,有三个值0,1,-1

0: producer不会等待broker发送ack

1: 当leader接收到消息以后发送ack

-1: 当全部的follower都同步消息成功后发送ack
request.required.acks=0

Consumer的负载均衡

当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提高topic的并发消费能力,步骤以下:

  • 一、假如topic1,具备以下partitions: P0,P1,P2,P3
  • 二、加入group A 中,有以下consumer: C0,C1
  • 三、根据partition索引号排序: P0,P1,P2,P3
  • 四、根据consumer.id排序: C0,C1
  • 五、计算倍数: M = [P0,P1,P2,P3].size / [C0,C1].size,本例值M=2(向上取整)
  • 六、而后依次分配partitions: C0 = [P0,P1],C1=[P2,P3],即Ci = [P(i * M),P((i + 1) * M -1)]

image

副本机制

因为Producer和Consumer都只会与Leader角色的分区副本相连,因此kafka须要以集群的组织形式提供主题下的消息高可用。kafka支持主备复制,因此消息具有高可用和持久性。

一个分区能够有多个副本,这些副本保存在不一样的broker上。每一个分区的副本中都会有一个做为Leader。当一个broker失败时,Leader在这台broker上的分区都会变得不可用,kafka会自动移除Leader,再其余副本中选一个做为新的Leader。

建立副本的2种模式——同步复制和异步复制

kafka维护了一个同步状态的副本集合(a set of In-Sync Replicas),简称ISR,集合中的节是和leader保持高度一致,任何一条消息只有被这个集合中的每一个节点读取并追加到日志中,才会向外部通知说“这个消息已经被提交”。

只有当消息被全部的副本加入到日志中时,才算是“committed”,只有committed的消息才会发送给consumer,这样就不用担忧一旦leader down掉了消息会丢失。

消息从leader复制到follower, 咱们能够经过决定Producer是否等待消息被提交的通知(ack)来区分同步复制和异步复制。

同步复制流程:
  1. producer联系zk识别leader
  2. 向leader发送消息
  3. leadr收到消息写入到本地log
  4. follower从leader pull消息
  5. follower向本地写入log
  6. follower向leader发送ack消息
  7. leader收到全部follower的ack消息
  8. leader向producer回传ack

异步复制流程:和同步复制的区别在于,leader写入本地log以后,直接向client回传ack消息,不须要等待全部follower复制完成。

kafka支持副本模式,那么其中一个Broker里的挂掉,一个新的leader就能经过ISR机制推选出来,继续处理读写请求。

介绍完kafka的基本概念,简单提一下为何要用kafka

解耦

在项目启动之初来预测未来项目会碰到什么需求,是极其困难的。消息队列在处理过程当中间插入了一个隐含的、基于数据的接口层,两边的处理过程都要实现这一接口。

冗余

有时在处理数据的时候处理过程会失败。除非数据被持久化,不然将永远丢失。对于传统的message queue而言,通常会删除已经被消费的消息,而Kafka集群会保留全部的消息,不管其被消费与否

扩展性

由于消息队列解耦了你的处理过程,因此增大消息入队和处理的频率是很容易的;只要另外增长处理过程便可。

灵活性 & 峰值处理能力

使用消息队列可以使关键组件顶住增加的访问压力,而不是由于超出负荷的请求而彻底崩溃。

可恢复性

当体系的一部分组件失效,不会影响到整个系统。
获取一个消息只是”预约”了这个消息,暂时把它移出了队列。除非客户端明确的表示已经处理完了这个消息,不然这个消息会被放回队列中去,在一段可配置的时间以后可再次被处理。

顺序保证

在许多状况下,数据处理的顺序都很重要。消息队列原本就是排序的,而且能保证数据会按照特定的顺序来处理。

缓冲

在任何重要的系统中,都会有须要不一样的处理时间的元素。

理解数据流 异步性

。消息队列提供了异步处理机制,容许你把一个消息放入队列,但并不当即处理它。你想向队列中放入多少消息就放多少,而后在你乐意的时候再去处理它们。

相关文章
相关标签/搜索