这是我参与「第五届青训营」伴学笔记创作活动的第 10 天
消息队列的使用场景
- 系统崩溃
- 服务处理能力有限
- 链路耗时长
- 日志如何处理
解决方案
-
系统崩溃
-
流量过大,服务无法处理
-
处理链路耗时长
-
日志处理
什么是消息队列
消息队列(MQ),指保存消息的一个容器,本质是个队列。但这个队列呢,需要支持高吞吐,高并发,并且高可用。
发展历程
不同组件对比
- kafka:分布式的、分区的、多副本的日志提交服务,在高吞吐场景下发挥较为出色,Kafka适合实时数据流处理和日志处理等场景。
- RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量和灵活的可扩展性,在一些实时场景中运用较广,RocketMQ适合大规模分布式系统,如电商、金融等。
- Pulsar:是下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,采用存算分离的架构设计。Pulsar适合实时数据分析、IoT、社交网络等领域。
- BMQ:和Pulsar架构类似,存算分离,初期定位是承接高吞吐的离线业务场景,逐步替换掉对应的Kafka集群
Kafaka
使用场景
- 服务的日志信息
- Metrics数据
- 搜索、点赞、评论等用户行为
基本概念
- Topic:Kakfa中的逻辑队列,可以理解成每一个不同的业务场景就是一个不同的topic,对于这个业务来说,所有的数据都存储在这个topic中
- Cluster:kafka的物理集群,每个集群中可以新建多个不同的topic
- Producer:顾名思义,也就是消息的生产端,负责将业务消息发送到Topic当中
- Partition:通常topic会有多个分片,不同分片直接消息是可以并发来处理的,这样提高单个Topic的吞吐
- offset:消息在partition内的相对位置信息,可以理解唯一ID,在partition内部严格递增。
- Replica:分片的副本,分布在不同的机器上,可用来容灾,Leader对外服务,Follower异步去拉取leader的数据进行一个同步。如果leader挂掉,可以将Follower提升成leader在对外进行服务
- ISR:意思是同步中的副本,对于Follower来说,始终和leader是有一定差距的,但当这个差距比较小的时候,我们就可以将这个follower副本加入到SR中,不再ISR中的副本是不允许提升成Leader的
Kafka如何保证高吞吐
Producer:
- 通过批量发送消息减少io次数,加强发送能力
- 通过压缩,减少消息大小,目前支持Snappy、Gzip、 LZ4、 ZSTD压缩算法
Brocker如何存储数据:
消息的备份都会转化为log进行保存,而每条log都会划分为多个切片
而brocker采用顺序写,提高写入效率。同时broker也采用偏移量索引文件的方案以及零拷贝(减少数据在内存中复制的次数)进行更快速地读写
Consumer:
有两种分配方式:
- 手动分配,也就是Kafka中所说的Low Level消费方式进行消费,这种分配方式的一个好处就是启动比较快,因为对于每一个Consumer来说, 启动的时候就已经知道了自己应该去消费哪个消费方式;缺点也很明显,即当cosumer宕机需要新启服务时,可能需要对服务进程进行启停而这对于部分线上业务来说是致命的
- 所以Kafka也提供了自动分配的方式,这里也叫做High Level的消费方式,简单的来说,就是在我们的Broker集群中, 对于不同的Consumer Group来讲,都会选取一台Broker当做Coordinator,而Coordinator的作用就是 帮助Consumer Group进行分片的分配,也叫做分片的rebalance, 使用这种方式,如果ConsumerGroup中有发生宕机,或者有新的Consumer加入,整个partition和Consumer都会重新进行分配来达到一 个稳定的消费状态
Kafka的缺点
- 运维成本高
- 对于负载不均衡的场景,解决方案复杂
- 没有自己的缓存,完全依赖Page Cache
- Controller和Coordinator和Broker在同一进程中,大量IO会造成其性能下降