[ 消息队列 | 青训营笔记]

97 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天

消息队列

在大学的计算机相关课程中,实际开发中所使用的技术如数据库等都或多或少有所涉及,消息队列却很少被提到。但在实际开发中,消息队列的应用是很常见的。

简介

消息队列的应用场景是什么?

案例1:用于系统崩溃的恢复

案例2:服务并发处理能力有限

案例3:链路耗时存在长尾

案例4:日志存储

对于以上的应用场景,一个通用的解决方案就是通过消息队列进行解耦

对于案例1:先将数据存入消息队列,再从消息队列写入存储。(生产者消费者模式)

对于案例2:使用消息队列进行削峰

对于案例3:通过消息队列,异步地处理业务链路(在数据写入消息队列后就返回给用户,同时在后台继续处理)

对于案例4:一般日志地写入是Log->消息队列->LogStash->ElasticSearch->Kinana

通过以上案例的分析,可以知道消息队列(Message Queue)需要满足高吞吐、高并发以及高可用 的特性。

消息队列的发展历程

1985年 Information Bus(TIB)

1993年 IBM开始研发商业消息队列

1997年 微软研发了MSMQ

2001年 JMS, SUN发布的一套消息队列API、

2004年 Apache发布了一套消息队列规范AMQP,同年RabbitMQ面世

2010年 LinkedIn开源了Kafka

2011年 Alibaba发布了RocketMQ

2012年 Yahoo发布了Pulsar

目前来说比较常见的消息队列有:

  • Kafka:分布式、多分区、多副本的日志提交服务,特点是高吞吐
  • RocketMQ:低延迟、强一致、高性能高可靠,实时性较好
  • Pulsar:云原生分布式消息流平台,采用存储计算分离的设计
  • BMQ:类似Pulsar、存算分离,用于高吞吐的离线业务场景,可以替换掉Kafka

Kafka

Kafka的使用场景

一般用在离线的消息处理当中:

  • 日志信息
  • Metrics数据(程序在运行当中的QPS、服务延迟等数据)的存储
  • 用户行为(例如搜索、点赞、评论、收藏等)

如何使用Kafka?

  1. 创建Kafka集群
  2. 创建一个Topic并设置其分区数量
  3. 引入Kafka的SDK:
    1. 编写生产者逻辑代码
    2. 编写消费者逻辑代码

Kafka如何支持高吞吐的?

  • Producer:对于消息的生产者,消息使用批量处理+消息压缩来提高消息发送量

  • Broker:将收到的消息存储到磁盘

    • 日志文件以LogSegment形式存储
    • 进行顺序写入以加快速度
    • 通过二分查找寻找小于目标offset的最大文件,采用二分查找目标offset的最大索引位置
    • 零拷贝
  • Consumer:

    • Consumer Group分组,组内不同的Consumer拉取不同分区的数据
    • 通过一个Coordinater(协调者)来对Group内部的Consumer进行分区分配(称为Rebalance)

BMQ

支持Kafka的协议,实现了读写分离,与Kafka的区别在于其文件存储在一个底层的分布式存储系统。

相比于Kafka而言,BMQ的运维(重启、替换、扩缩容)都可以在秒级别完成,而Kafka则需要较长的时间(分钟级别甚至更多)

由于BMQ的底层是分布式文件系统如HDFS,它会选择随机的一些DataNode进行写入,负载均衡性好。

RocketMQ

应用场景与上述两者不同:主要用于实时的业务例如电商中的注册、订单、物流等等,也会涉及到一些秒杀的场景。

高级特性:

  • 事务消息:

    • 在事务消息中,会发送half message,如果后续步骤成功则会提交
    • 如果超时,server会回查、如果发现事务失败则会回滚(可能已经落盘的消息)
  • 延迟发送

    • 消息队列定时发送
  • 失败消息处理

    • 消费失败时会进行延期投递、如果再超过次数上限则会发送到死信队列中(此时这条消息只能进行人工介入的后续处理了)