消息队列介绍
可以独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束。
系统的一部分组件失效时,不会影响到整个系统。消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。
有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。
在访问量剧增的情况下,应用仍然需要继续发挥作用,但是这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。
很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。
我们知道常见的消息系统有Kafka、RabbitMQ、ActiveMQ等等,但是这些消息系统中所使用的消息模式如下两种:
点对点模式(一对一,消费者主动拉取数据,消息收到后消息清除)
发布/订阅模式(一对多,消费者消费数据之后不会清除消息)
常用消息系统对比
Kafka是一个开源消息系统,由Scala写成。是由Apache软件基金会开发的一个开源消息系统项目,该项目的目标是为处理实时数据提供一个统一、高通量、低等待的平台。
Kafka是一个分布式消息队列:生产者、消费者的功能。它提供了类似于JMS的特性,但是在设计实现上完全不同,此外它并不是JMS规范的实现。
Kafka对消息保存时根据Topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。无论是kafka集群,还是producer和consumer都依赖于zookeeper集群保存一些meta信息,来保证系统可用性。
0.7 #上古版本,提供了最基础的消息队列功能
0.8 #引入了副本机制,成为了一个真正意义上完备的分布式高可靠消息队列解决方案
0.8.2 #新版本 Producer API,即需要指定 Broker 地址的 Producer
0.9 #增加了基础的安全认证 / 权限,Java 重写了新版本消费者 API
0.10.0.0 #引入了 Kafka Streams
0.11.0.0 #提供幂等性 Producer API 以及事务(Transaction) API,对 Kafka 消息格式做了重构。
1.0 #Kafka Streams 的各种改进
2.0 #Kafka Streams 的各种改进
1)Producer:消息生产者,就是向 kafka broker 发消息的客户端;
2)Consumer:消息消费者,向 kafka broker 取消息的客户端;
3)Consumer Group (CG):消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
4)Broker :一台 kafka 服务器就是一个 broker。一个集群由多个 broker 组成。一个 broker可以容纳多个 topic。
5)Topic:可以理解为一个队列,生产者和消费者面向的都是一个topic;
6)Partition:为了实现扩展性,一个非常大的 topic 可以分布到多个 broker(即服务器)上,一个 topic 可以分为多个partition,每个 partition 是一个有序的队列;
7)Replica:副本,为保证集群中的某个节点发生故障时,该节点上的 partition 数据不丢失,且 kafka 仍然能够继续工作,kafka 提供了副本机制,一个 topic 的每个分区都有若干个副本,一个leader和若干个follower。
8)leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是 leader 。
9)follower:每个分区多个副本中的“从”,实时从 leader 中同步数据,保持和leader数据的同步。leader 发生故障时,某个 follower 会成为新的 leader。
Kafka数据处理步骤
kafka只支持Topic
1、每个group中可以有多个consumer,每个consumer属于一个consumer group;通常情况下,一个group中会包含多个consumer,这样不仅可以提高topic中消息的并发消费能力,而且还能提高"故障容错"性,如果group中的某个consumer失效那么其消费的partitions将会有其他consumer自动接管。
2、对于Topic中的一条特定的消息,只会被订阅此Topic的每个group中的其中一个consumer消费,此消息不会发送给一个group的多个consumer;那么一个group中所有的consumer将会交错的消费整个Topic,每个group中consumer消息消费互相独立,我们可以认为一个group是一个"订阅"者。
3、在kafka中,一个partition中的消息只会被group中的一个consumer消费(同一时刻);
一个Topic中的每个partions,只会被一个"订阅者"中的一个consumer消费,不过一个consumer可以同时消费多个partitions中的消息。
4、kafka的设计原理决定,对于一个topic,同一个group中不能有多于partitions个数的consumer同时消费,否则将意味着某些consumer将无法得到消息。
kafka只能保证一个partition中的消息被某个consumer消费时是顺序的;事实上,从Topic角度来说,当有多个partitions时,消息仍不是全局有序的。
事实上,消息被路由到哪个partition上由producer客户端决定,比如可以采用"random"“key-hash”"轮询"等。
如果一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。
当一个group中,有consumer加入或者离开时,会触发partitions均衡.均衡的最终目的,是提升topic的并发消费能力,步骤如下:
partitions: P0,P1,P2,P3
consumer:C0,C1
P0,P1,P2,P3
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)]
参考链接:https://blog.csdn.net/weixin_48067943/article /details/108228110https://blog.csdn.net/weixin_45894220 /article/details/127867556