MQ学习笔记(一)Kafka简介

什么是MQ?

Message Queue 消息队列 ,在消息的传递过程中保存消息的容器。

父亲==》书架《==儿子

好处:应用解耦,异步提速,限流削峰

使用成本:引入复杂度,最终一致性,高可用性

何时使用:

生产者不需要从消费者处获得反馈

能够容忍短暂的不一致性

效果要大于副作用

应用场景

应用解耦

场景:用户下单之后,订单系统要通知库存系统

传统方式:订单系统直接调用库存系统提供的接口,如果库存系统出现故障会导致订单系统失败

异步提速

场景:用户注册成功之后,需要发送注册邮件及注册短信提醒

限流削峰

场景:现在我们每个月要搞一次大促,大促期间的并发可能会很高的,比如每秒3000个请求,假设现在有两台 机器处理请求,并且每台机器只能每次处理1000个请求,那多出来的1000个请求,可能就把我们整个系统给搞 崩掉;

解决办法:把请求存放在消息队列中,机器A和机器B只需要根据自己能够处理的请求数去消息队列中拿数据, 这样即便有每秒有1万个请求,也不会把整个系统给搞崩;

日志处理

场景:系统中存在海量日志需要处理,大吞吐、还需要支持流式处理,那就得上Kafka

常用MQ比对

ActiveMQ

老牌消息队列,使用Java语言编写,对JMS支持最好,采用多线程并发,资源消耗比较大,由于历史悠久,所以包袱也重,版本更新异常缓慢,集群模式下还需要依赖Zookeeper实现,最新架构的产品被命名为 ApolloMQ,目前国内使用率越来越少;

RabbitMQ

RabbitMQ结合erlang语言本身的并发优势,性能较好、延时低、吞吐量到万级,社区活跃度也比较高,但是难以定制和掌控,不利于做二次开发和维护;RabbitMQ集群动态扩展会比较麻烦,如果数据量没有那么大、项目 规模也不是特别大的话,优先选择功能比较完备的RabbitMQ;

Kafka

Kafka的特点其实很明显,超高的吞吐量[基于 Pull-拉模式来处理消息消费],ms级的延迟,极高的可用性以及可靠性,而且分布式可以任意扩展。唯一的一点劣势是有可能消息重复消费,对数据准确性会造成极其轻微的影 响,在大数据领域中以及日志采集中,这点轻微影响可以忽略。这个特性天然适合大数据实时计算以及日志收集,如果你的项目中有日志采集功能,首选肯定是kafka;

RocketMQ

天生为互联网领域、金融线而生,对于可靠性要求很高的场景,尤其是电商里面的订单扣款,以及业务削峰, 在大量交易涌入时,后端可能无法及时处理的情况,RocketMQ在稳定性上可能更值得信赖,这些业务场景在阿里双11已经经历了多次考验,如果你的业务有上述这种高并发场景,建议可以选择RocketMQ,另外,它是Java语言实现的,可以自己阅读源码、基于RocketMQ定制自己公司的MQ;

其他MQ

ZeroMQ[快、大吞吐量,仅提供非持久性队列,down机则丢失数据]、IBM MQ、Redis[支持MQ功 能,可以当做一个轻量级的队列服务来使用

Kafka架构设计

理解了上图,基本上就明白Kafka的整体架构,先来肢解各个组件

Boker-服务器

Kafka作为一个中间件,是帮我们存储和转发消息的,它做的事情就像中介,所以Kafka的服务也叫做Broker,默认是 9092的端口,生产者和消费者都需要跟这个Broker建立一个连接,才可以实现消息的收发。

Record-记录

客户端之间传输的数据叫做消息,或者叫做Record [记录];在客户端的代码中,Record可以是一个KV键值对;生产 者对应的封装类是ProducerRecord,消费者对应的封装类是ConsumerRecord;消息在传输的过程中需要序列化,所 以代码里面要指定序列化工具;消息在服务端的存储格式 [RecordBatch和Record]

Producer-生产者

发送消息的一方叫做生产者,接收消息的一方叫做消费者;Kafka为了提升消息发送速率,生产者不是逐条发送消息 给Broker,而是批量发送的,多少条发送一次由一个参数决定

Consumer-消费者

Kafka消费者获取消息的模式为:Push,消费者可以自己控制一次到底获取多少条消息

Topic-主题

生产者发送消息,要指定发给哪个队列。消费者接收消息,要指定从哪个队列接收;在Kafka里面,这个队列叫做 Topic,是一个逻辑的概念,可以理解为一组[不同业务用途的消息] 消息的集合;生产者发送消息时,如果Topic不存 在,会自动创建,由一个参数控制

Partition-分区

如果说一个Topic中的消息太多,会存在什么问题? 不方便横向扩展并发或者负载的问题 解决方法就是把一个Topic进行拆分,Kafka引入了一个Partition[分区]的概念,一个Topic可以划分成多个分区,分区 在创建Topic的时候指定,每个Topic至少有一个分区

Partition思想上有点类似于分库分表,实现的也是横向扩展和负载的目的

分区Replica副本机制

如果Partition的数据只存储一份,在发生网络或者硬件故障的时候,该分区的数据就无法访问或者无法恢复了, Kafka在0.8的版本之后增加了副本机制,每个Partition可以有若干个Replica[副本],副本必须在不同的Broker上面, 一般我们说的副本包括其中的主节点,由replication-factor指定一个Topic的副本数

如图:部署3个Broker,该Topic有3个分区,每个分区一共3个副本

Partition副本有Leader[红色]和Follower[非红色Partition]的概念。Leader在哪台机器是不一定的,通过选举产生的; 生产者发消息、消费者读消息都是针对Leader,Follower的数据是从Leader同步过来的。

Segment-段

Kafka的数据是放在后缀.log的文件中的,如果一个Partition只有一个log文件,消息不断地追加,这个log文件也会变 得越来越大,这个时候要检索数据效率就很低了;所以干脆把Partition再做一个切分,切分出来的单位就叫做段 [Segment],实际上Kafka的存储文件就是划分成段来存储的。

Consumer Group-消费者组

如果生产者生产消息的速率过快,会造成消息在Broker中堆积,影响Broker性能,通过增加消费者的数量,可以缓解消息在Broker上的堆积,问题又来了,这么多消费者,要确保大家去消费同一个Topic,Kafka引入了一个Consumer Group消费组的概念,在代码中通过group id来配置。消费同一个Topic的消费者不一定是同一个组,只有group id相同的消费者才是同一个消费者组,我们使一个消费者组去消费一个Topic的内容,就可以达到提高消费吞吐量的目 的;另外,同一个Group中的消费者,不能消费相同的Partition,Partition要在组内消费者间进行分配,如果想要同时消费同一个Partition的消息,只能通过其他的消费者组来消费;

Consumer Offset-偏移量

Partition中的消息是顺序写入的,被读取之后不会被删除,如果消费者挂了或者下一次读取,想要接着上次的位置读 取消息,或者从某个特定的位置读取消息,需要确保不会出现从头消费、重复消费的情况; Kafka的解决方案:因为消息是有序的,就可以对消息进行编号,用来标识一条唯一的消息,这个编号我们就把它叫 做Offset-偏移量;Offset记录着下一条将要发送给Consumer的消息的序号,这个消费者跟Partition之间的偏移量没有 保存在ZK,而是直接保存在服务端 [0.9版本以前维护在ZK中,但是ZK本身不适合大量写入,后来做了改动,将数据维护在kafka的_consumer_offsets主题下];

高级特性

消息幂等性

概念

如果消费失败了,消息需要重发,但在不清楚消费者是不是真的消费失败的情况下,就有可能会出现消息重复的情况;消息重复需要在消费端解决,也就是在消费者实现幂等性;考虑到所有的消费者都要做相同实现,Kafka干脆在 Broker实现了消息的重复性判断,解放消费者;去重肯定要依赖于生产者消息的唯一标识,不然是没办法知道是不是同一条消息。

两个重要机制

Producer ID - 幂等性的生产者每个客户端都有一个唯一编号;

Sequence Number - 幂等性的生产者发送的每条消息都会带相应的SN(若SN<服务端记录的min值,即消息重 复)

局限性

但Sequence Number并非全局有序,不能保证所有时间上的幂等,它的作用范围是有限的:

只能保证单分区上的幂等性

只能实现单会话上的幂等性(会话:Producer进程的一次运行)

即:不允许生产者在一次会话中向同一个Patition发送相同的消息;若要实现多个分区的消息的原子性,就要用到 Kafka的事务机制。

生产者事务

Kafka 0.11.0.0引入生产者事务特性,通过事务,Kafka可以保证跨生产者会话的消息幂等发送;事务实现的前提是幂 等性。

何时需要开启事务:

发送多条消息 (单体架构:1个Producer、Broker、Topic)

发送消息到多个Topic或者多个Partition(集群架构,不同的服务器[Broker])

消费后发送消息(消费者和生产者在同一块代码中,从上游接收消息,经过处理后发给下游,要保证接收消息 和发送消息同时成功)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值