这是我参与「第五届青训营 」伴学笔记创作活动的第12天。
消息队列
案例一:
本人想买东西,搜索直播间,点击直播间,搜索行为会被记录。
案例二:
很多人想要购买同一个商品,发起订单到处理订单,可能只能同时处理10个订单。
思考如果发生:系统崩溃、服务处理能力优先、链路耗时长、以及日志应该如何处理。
解决方案:添加消息队列。
在日志处理中:
Log->消息队列->LogStash->ES->Kibana
概念
消息队列是指保存消息的容器,本质上是一个队列,但是这个队列需要支持高吞吐、高并发并且要高可用。
发展历程
- TIB:消息队列诞生于1985年,服务于金融机构和新闻机构。
- WebSphere:诞生于1993年,商业消息队列平台市场的主要玩家
- MSMQ:微软发布于1997年。
- JMS:诞生于2001年本质上是一套JAVA API。
- AMQP:发布于2004年,同年RabbitMQ面试。
- Kafka:2010年由Linked开源。
- RocketMQ:2011年阿里中间件团队。
- Pulsar:2012年诞生于Yahoo内部。
消息队列Kafka
使用场景
搜索服务、直播服务、订单服务、支付服务
至
日志信息、Metrics数据、用户行为。
如何使用Kafka
首先创建Kafka集群->新增Topic->编写生产者逻辑->编写消费者逻辑。
基本概念
Topic:不同的业务场景可以看作不同的Topic
Cluster:物理集群,每个集群中可以建立多个不同的Topic。
Producer:生产者,负责将业务信息发送到Topic中。
Consumer:消费者,负责消费Topic中的消息。
ConsumerGroup:消费者组,不同组的Consumer互不干涉。
Offset:消息在partition中的相对位置,可以理解成唯一ID,在partition内部严格递增。
Replica:每个分片有多个Replica,Leader Replica将会从ISR中选出。
从消息的角度观察Kafka
Producer->Broker->Consumer
Producer->Message->Broker
Broker->Success->Producer
Broker中采用顺序写的形式,提高写入效率。
Consumer-消息的接收端
对于一个Consumer Group来说,多个分片可以并发的消费,可以大大提高消费的效率,但是需要解决的问题是,Consumer和Partition的分配问题,也就是对于每一个Partition来讲,该由哪一个Consumer来消费的问题。对于这个问题,我们一般有两种解决办法,手动分配与自动分配。
帮助Kafka提高吞吐和稳定性的功能
Producer:批量发送、数据压缩
Broker:顺序写,消息索引,零拷贝
Consumer:Rebalance
Kafka重启操作
如果对一个机器进行重启,首先要关闭一个Broker,如果此时该Broker上存在副本的Leader,那么该副本将发生Leader切换,切换到其他节点中并在ISR中的Follower副本。而此时,因为数据在不断地写入,对于刚刚关闭重启的Broker来说,和新的Leader之前一定会存在数据的滞后,此时这个Broker会追赶数据,重新加入ISR中,当数据追赶完成之后,我们需要切回Leader,这一步称为prefer leader,这一步的目的是为了避免,在一个集群长期运行之后,所有的leader都分布在少数的节点之上,导致数据的不均衡。
Kafka 负载不均衡
在这个场景中,同一个Topic有4个分片,两个副本,可以看到,对于分片1来说,数据量明显是要比其他的分片大的,当我们机器IO达到瓶颈时,可能需要把第一台Broker上面的Partition3迁移到其他负载小的Broker上。
Kafka存在的问题
- 运维成本高。
- 对于负载不均衡的场景,解决方案复杂。
- 没有自己的缓存,完全依赖Page Cache。
- Controller和Coordinator和Broker在同一进程中,大量IO会造成其性能下降。