IT评测·应用市场-qidao123.com

标题: MQ概览及Kafka详解 [打印本页]

作者: 用多少眼泪才能让你相信    时间: 2024-7-20 02:42
标题: MQ概览及Kafka详解
概览

MQ 即 messagequeue 消息队列,是分布式体系的重要组件,主要办理异步消息,应用解耦,消峰等问题。从而实现高可用,高性能,可伸缩和终极一致性的架构。利用较多的MQ有:activeMQ,rabbitMQ,kafka,metaMQ。
MQ长处


MQ缺点


常见MQ对比

特性ActiveMQRabbitMQRocketMQKafka单机吞吐量万级,比 RocketMQ、Kafka 低一个数量级同 ActiveMQ10 万级,支持高吞吐10 万级,高吞吐,一般共同大数据类的体系来进行实时数据计算、日记采集等场景topic 数量对吞吐量的影响topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等呆板下,可以支持大量的 topictopic 从几十到几百个时间,吞吐量会大幅度下降,在同等呆板下,Kafka 只管包管 topic 数量不要过多,如果要支持大规模的 topic,需要增长更多的呆板资源时效性ms 级微秒级,这是 RabbitMQ 的一大特点,延迟最低ms 级延迟在 ms 级以内可用性高,基于主从架构实现高可用同 ActiveMQ非常高,分布式架构非常高,分布式,一个数据多个副本,少数呆板宕机,不会丢失数据,不会导致不可用消息可靠性有较低的概率丢失数据根本不丢颠末参数优化设置,可以做到 0 丢失同 RocketMQ功能支持MQ 领域的功能极其完备基于 erlang 开发,并发本事很强,性能极好,延时很低MQ 功能较为完善,还是分布式的,扩展性好功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日记采集被大规模利用 一般的业务体系要引入 MQ,最早各人都用 ActiveMQ,但是如今确实各人用的不多了,没颠末大规模吞吐量场景的验证,社区也不是很活跃,所以各人还是算了吧,我个人不推荐用这个了。
厥后各人开始用 RabbitMQ,但是确实 erlang 语言制止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳固的支持,活跃度也高。
不过如今确实越来越多的公司会去用 RocketMQ,确实很不错,究竟是阿里出品,但社区可能有突然黄掉的风险,目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度实在不算高,对本身公司技能实力有绝对自大的,推荐用 RocketMQ,否则归去老诚实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。
所以中小型公司,技能实力较为一般,技能挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。
如果是大数据领域的实时计算、日记采集等场景,用 Kafka 是业内尺度的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全天下这个领域的事实性规范。
JMS消息模子

JMS即JavaMessageService,Java消息服务应用步伐接口,是一个Java平台中关于面向消息中间件的API,用于在两个应用步伐之间,或分布式体系中发送消息,进行异步通讯。
JMS是基于JVM的消息署理规范,ActiveMQ、HornetMQ等是JMS的实现。
Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。我们可以简单的理解:两个应用步伐之间需要进行通讯,我们利用一个JMS服务,进行中间的转发,通过JMS的利用,我们可以解除两个步伐之间的耦合。
点对点模式

消息发送者发送消息,消息署理将其放入消息队列中,消息继承者从队列中获取消息,消息读取后被移除消息队列。每个消息都被发送到一个特定的队列,接收者从队列中获取消息。队列保留着消息,直到它们被消费或超时。

固然可能有多个客户端在队列中侦听消息,但只有一个可以读取到消息,之后消息将不存在,其他消费者将无法读取。也就是说消息队列只有唯逐一个发送者和继承者,但是并不能说只有一个接收者
特点:

发布订阅模式

发布者将消息发送到主题Topic中,多个订阅者订阅这个主题,订阅者不停的去轮询监听消息队列中的消息,那么就会在消息到达的同时接收消息。

特点:

kafka

kafka是一个分布式的基于发布/订阅模式的消息队列,主要应用于大数据实时处理领域。
基础架构



消费者组的作用为了提高消费本事,即提高并发。
解耦合是消息队列作用之一,当消费者宕机后,再次启动的时间会继续消费消息,而不是从头消费消息。由于这个特性所以消费者会保存一些消费的进度信息,被称为offset,保存的位置在kafka0.9之前保存在zookpeer当中,在此之后保存在kafka本地。即终极kafka会将消息保存在本地磁盘中,默认保留168个小时,即7天。
kafka中消息是以topic进行分类的,producer生产消息,consumer消费消息,都是面向topic的。topic是逻辑上的概念,而partition是物理上的概念,每个partition对应于一个log文件,该log文件中存储的就是producer生产的数据。
Producer生产的数据会被不停追加到该log文件末端,且每条数据都有本身的offset。consumer组中的每个consumer,都会实时记载本身消费到了哪个offset,以便堕落恢复时,从前次的位置继续消费。
发布订阅工作流程


消费者可以选择随时倒退或跳至所需的主题偏移量并阅读全部后续消息。
生产者

生产者文件存储

参考文章:


由于生产者生产的消息会不停追加到log文件末尾,为防止log文件过大导致数据定位效率低下,kafka采取了分片和索引机制,将每个partition分为多个segment。
每个segment对应两个文件:“.index”文件和“.log”文件。这些文件位于一个文件夹下,该文件夹的定名规则为:topic名称+分区序号。例如,first这个topic有三个分区,则其对应的文件夹为 first-0,first-1,first-2。其中,每个segment中的日记数据文件大小均相称。
   该日记数据文件的大小可以通过在kafka Broker的config/server.properties设置文件的中的“log.segment.bytes”进行设置,默认为1G大小(1073741824字节),在顺序写入消息时如果超出该设定的阈值,将会创建一组新的日记数据和索引文件。
  “.index”文件存储大量的索引信息,“.log”文件存储大量的数据,索引文件中的元数据指向对应数据文件中message的物理偏移地点。其中文件的定名是以第一个数据的偏移量来定名的。
kafka如何通过index文件快速找到log文件中的数据?
根据指定的偏移量,利用二分法查询定位出该偏移量对应的消息所在的分段索引文件和日记数据文件。然后通过二分查找法,继续查找出小于即是指定偏移量的最大偏移量,同时也得出了对应的position即实际物理位置。
根据该物理位置在分段的日记数据文件中顺序扫描查找偏移量与指定偏移量相称的消息。由于index文件中的每条对应log文件中存储内容大小都相同,所以想要找到指定的消息,只需要用index文件中的该条的大小加上该条的偏移量即可得出log文件中指定消息的位置。

生产者分区策略

分区的缘故原由:



生产者数据可靠性包管

为包管 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到 producer 发送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果 producer 收到 ack,就会进行下一轮的发送,否则重新发送数据。

方案长处缺点半数以上完成同步,就发 送 ack延迟低选举新的 leader 时,容忍 n 台 节点的故障,需要 2n+1 个副本全部完成同步,才发送ack选举新的 leader 时,容忍 n 台 节点的故障,需要 n+1 个副 本延迟高   理解 2n+1:
半数以上完成同步才可以发ACK,如果挂了n台有副本的服务器,那么就需要有别的n台正常发送(如许正常发送的刚好是总数(挂的和没挂的)的一半(n(挂的)+n(正常的)=2n)),由于是半数以上所以2n+1.(所以总数2n+1的时间最多只能容忍n台有故障)
  即,如果挂了n台有副本的服务器,那么存在副本的服务器的总和为 2n+1
  kafka选择了第二种方案,缘故原由如下:
1.同样为了容忍 n 台节点的故障,第一种方案需要 2n+1 个副本,而第二种方案只需要 n+1 个副本,而 kafka 的每个分区都有大量的数据,第一种方案会造成大量数据的冗余;
2.固然第二种方案的网络延迟会比较高,但网络延迟对 kafka 的影响较小;
采取第二种方案之后,假想以下情景: leader 收到数据,全部 follower 都开始同步数据,但有一个 follower,由于某种故障,迟迟不能与 leader 进行同步,那 leader 就要一直等下去,直到它完成同步,才能发送 ack。这个问题怎么办理呢?
Leader 维护了一个动态的 in-sync replica set 即ISR。
当和 leader 保持同步的 follower 集合。当 ISR 中的 follower 完成数据的同步之后,就会给 leader 发送 ack。如果 follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间阈值由replica.lag.time.max.ms参数设定。 Leader 发生故障之后,就会从 ISR 中选举新的 leader。
   kafka是通过消息条数差值(replica.lag.time.max.messages) 加 通讯时间好坏(同步时间replica.lag.time.max.ms) 两个条件来选副本进ISR,在高版本中不再关注副本的消息条数最大条件。
  为何会去掉消息条数差值参数?
由于kafka一般是按batch批量发数据到leader, 如果批量条数12条,replica.lag.time.max.messages参数设置是10条,那么当一个批次消息发到kafka leader,此时,ISR中就要踢掉全部的follower,很快follower同步完全部数据后,follower又要被加入到ISR,而且要加入到zookeeper中频繁操纵,所以去撤除该条件。
生产者数据一致性包管



生产者ack机制

对于某些不太重要的数据,对数据的可靠性要求不是很高,能够容忍数据的少量丢失,所以没须要等 ISR 中的 follower 全部接收获功。kafka为生产者提供了三种ack可靠性级别设置:

ExactlyOnce

将服务器的 ACK 级别设置为-1,可以包管 Producer 到 Server 之间不会丢失数据,即 At Least Once 语义,至少发送一次;相对的,将服务器 ACK 级别设置为 0,可以包管生产者每条消息只会被发送一次,即 At Most Once 语义,至多发送一次。
至少发送一次可以包管数据不丢失,但是不能包管数据不重复;相对的,至多发送一次可以包管数据不重复,但是不能包管数据不丢失。 但是,对于一些非常重要的信息,比如说买卖业务数据,下游数据消费者要求数据既不重复也不丢失,即 Exactly Once 语义,准确发送一次。
在0.11 版本的 Kafka,引入了一项庞大特性:幂等性。所谓的幂等性就是指生产者不论向 Server 发送多少次重复数据, Server 端都只会持久化一条。幂等性联合 At Least Once 语义,就构成了 Kafka 的 Exactly Once 语义。
要启用幂等性,只需要将 Producer 的参数中 enable.idempotence 设置为 true 即可。
Kafka的幂等性实现实在就是将原来下游需要做的去重放在了数据上游。开启幂等性的 Producer 在初始化的时间会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而Broker 端会对<ID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时, Broker 只会持久化一条。但是 PID 重启就会变革,同时不同的 Partition 也具有不同主键,所以幂等性无法包管跨分区跨会话的 Exactly Once。
生产者发送消息流程

kafka的生产者发送消息采取的是异步发送的方式。在消息发送的过程中,涉及到了两个线程——main 线程和 Sender 线程,以及一个线程共享变量——RecordAccumulator。

在生产者发送消息时,main线程将消息发送给 RecordAccumulator,当数据积聚到 batch.size 之后,sender线程才会不停从 RecordAccumulator 中拉取消息发送到 kafka的broker;如果数据迟迟未达到 batch.size,sender 线程期待 linger.time 之后就会发送数据。
消费者

消费者分区分配策略

一个消费者组中有多个消费者,一个主题有多个分区,所以必然会涉及到分区的分配问题,即确定哪个个分区由哪个消费者来消费。
消费分配策略:

轮询就不必说了,就是把分区按照hash排序,然后分配。range按范围分配,先将全部的分区放到一起然后排序,按照均匀分配的方式计算每个消费者会得到多少个分区,如果没有除尽,则会将多出来的分区依次计算到前面几个消费者。
比如这里是三个分区和两个消费者,那么每个消费者至少会得到1个分区,而3除以2后还余1,那么就会将多余的部分依次算到前面几个消费者,也就是这里的1会分配给第一个消费者,
如果按照Range分区方式进行分配,其本质上是依次遍历每个topic,然后将这些topic的分区按照其所订阅的消费者数量进行均匀的范围分配。这种方式从计算原理上就会导致排序在前面的消费者分配到更多的分区,从而导致各个消费者的压力不均衡。
消费者消费数据问题

消费者在消费的时间,需要维护一个offset,用于记载消费的位置,当offset提交时会有两个问题:重复消费和漏消费:

这里就需要注意offset的提交方式,offset默认是自动提交,当然这会造成消费的不准确。offset提交方式:

建议将offset保存在数据库中,使当前业务与offset提交绑定起来,如许可以一定程度制止重复消费问题,重复消费的问题,一方面需要消息中间件来进行包管。另一方面需要本身的处理逻辑来包管消息的幂等性。
kafka事件

kafka从0.11版本开始引入了事件支持。事件可以包管kafka在Exactly Once语义的基础上,生产和消费可以跨分区和会话,要么全部成功,要么全部失败。

   为了管理 Transaction, Kafka 引入了一个新的组件 Transaction Coordinator。 Producer 就是通过和 Transaction Coordinator 交互得到 Transaction ID 对应的任务状态。 Transaction Coordinator 还负责将事件全部写入 Kafka 的一个内部 Topic,如许纵然整个服务重启,由于事件状态得到保存,进行中的事件状态可以得到恢复,从而继续进行。
  
消息积存

如果线上遇到大量消息积存,那就是线上故障了.最可能是消费者出现故障
一般这个时间,只能临时告急扩容了:

如果没有消费者没有出现问题,而出现了消费积存的环境可以参考以下思路:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4