消息队列|青训营笔记

67 阅读7分钟

消息队列|青训营笔记

这是我参与【第五届青训营】伴学笔记创作活动的第12天。

一、重点知识

  • 消息队列的基础知识
  • Kafka的实现方式,重要内容、问题
  • BMQ的实现方式、重要内容、问题
  • Rocket的实现方式

二、详细知识点

1. 走进消息队列

1.1 基础问题

  • 系统崩溃:如果记录存储失效,如何反馈?
    • 解耦:添加一个消息队列,由消息队列反馈至数据库
  • 服务能力有限:庞大的请求量,处理订单服务器只能同时处理数个请求
    • 削峰:添加消息队列,每次取出一定量的请求
  • 发起订单后 链路耗时长尾:通知商家花费的时间长
    • 异步:通过消息队列广播到不同状态
  • 日志存储:日志如何处理
    • 日志处理创建消息队列,stash后存入

1.2 消息队列基础

  • 消息队列MQ
    • 保存消息的一个容器
    • 本质是一个队列
    • 支持高吞吐、高并发、高可用

1.3 发展历程

  • 早期TiB
  • IBM MQ/WebSphere
  • MSMQ
  • JMS:JAVA API
  • AMQP/RabbitMQ
  • Kafka
  • RocketMQ
  • Pulsar

1.4 常见业界消息队列

  • Kafka:分布式分区多副本日志提交服务,高吞吐下发挥较为出色
  • RocketMQ:低延迟、强一致、高性能、高可靠、万亿级容量、灵活可拓展性,实时场景应用广
  • Pulsar:下一代云原生分布式消息流平台,集消息、存储、轻量化函数式计算为一体,存算分离
  • BMQ:类似Pulsar

2. Kafka

2.1 使用场景

  • 搜索服务、直播服务、订单服务、支付服务
  • 日志信息
  • 用户行为
  • Metrics数据:程序运行中程序状态的采集

2.2 如何使用Kafka

  • 创建集群
  • 新增Topic
  • 编写生产者逻辑
  • 编写消费者逻辑

2.3 基本概念

  • topic:逻辑队列,不同topic建立不同的队列
  • cluster:物理集群,每个集群中可以建立不同topic
  • producer:生产者,将业务消息发送到topic中
  • consumer:消费者,消费topic中信息
  • ConsumerGroup:消费者组,不同组消费者消费进度不干涉 Screen Shot 2023-02-09 at 1.23.45 AM.png
  • offset:消息在partition内的相对位置信息,唯一ID,在partition内部严格递增
  • replica:副本数,每个分片有多个,leader会从ISR(In-Sync Replica)中选出

2.4 数据复制

  • 多个broker节点
  • leader向follower发送副本
  • controller负责分配其他的broker

2.5 Kafka架构

  • zookeeper负责存储原数据信息、分区信息
  • cluster内存在broker
  • 下不分配到不同的consumer group

2.6 一条消息的流程

  • producer生产
    • 如果等待成功后再返回,会发生延时:批量发送 batch
    • 带宽不够用:数据压缩减少消息大小
  • broker
  • consumer消费

2.7 broker消息文件结构

Screen Shot 2023-02-09 at 1.29.18 AM.png

  • 切分为不同的日志段,方便基于时间点的切分
  • LogSegment有日志、偏移量、时间戳等

2.8 Broker磁盘结构

  • 移动磁头找到对应磁道磁盘转动,找到对应扇区,写入
  • 寻道成本高
  • 顺序写可以减轻读写成本
  • 偏移量索引文件:二分找到小于目标offset的最大文件
    • 二分找到小于目标offset的最大索引位置
    • 二分找到小于目标时间戳最大索引位置
    • 通过offset找到最终数据

2.9 broker传统数据拷贝(零拷贝)

  • 内核态,从磁盘读取到read buffer,拷贝到应用空间(用户态)
  • 需要反复拷贝到内核空间
  • 由内核空间发送到消费者进程
  • 通过sync file把磁盘读取到内核空间,内核空间发送到网卡再发送到消费者进程

2.10 Consumer——消息接受端

  • Partition在Consumer Group中的分配
  • 手动分配:手动进行分配,consumer与partition分配由业务决定
    • 缺点:新加机器时没有额外的partition,需要停掉原本进程重新分配;导致数据中断
  • 自动分配 Rebalance:Coordinator重新计算每个consumer的分片,以此达到稳定状态
    • consumer发送寻找coordinator的request
    • broker找到group coordinator
    • group coordinator返回信息,同时设定一个consumer leader
    • consumer leader将分配方案返回给coordinator

2.11 Kafka数据复制

  • Kafka没有自己的缓存,依赖PageCache Screen Shot 2023-02-09 at 9.40.53 AM.png

2.12 Kafka重启操作

  • 重启Leader:从follower中选一个为leader
  • Leader切换,原leader需要追赶数据
  • 数据同步完成后,leader回切
  • 时间成本很大,因为需要一台一台重启 Screen Shot 2023-02-09 at 9.42.54 AM.png

2.13 Kafka替换、扩缩容

  • 新机器类似于重启,但需要从零开始追赶
  • 缩容:需要分配到其他机器上
  • 实际的时间成本很大

2.14 负载不均衡

  • 如果partition大小不均,在迁移时会增加I/O问题
  • 导致为了解决I/O问题引入新的I/O问题
  • 因为在统一进程中,大量I/O导致性能下降

3. BMQ消息队列

3.1 简介

  • 兼容kafka协议
  • 存算分离
  • 云原生消息队列 Screen Shot 2023-02-09 at 9.51.47 AM.png

3.2 运维操作对比

  • 利用proxy代理代替直接联系broker,减轻broker压力,同时方便添加和消除consumer
  • 重启:kafka需要数据复制,BMQ秒级完成
  • 替换:kafka需要数据复制,BMQ秒级完成
  • 扩缩容:kafka需要数据复制,BMQ秒级完成

3.3 HDFS写文件流程

  • 随机选取一定数量的datanode进行写入:根据副本数随机选择写入

3.4 BMQ文件结构

  • Kafka可能会存在partition不均衡
  • BMQ将partition分为segment,每个segment会写在不同的机器上;
    • 最后不需要将partition全部分在一个节点
    • 选取segment汇合成partition

3.5 broker-partition状态机

  • 保证任意分片在同一时刻只在一个broker上存活 Screen Shot 2023-02-09 at 9.59.41 AM.png

3.6 写文件流程

  • 信息进行数据校验,存入buffer,存入writer thread 存入storage
  • writer thread会写数据,然后flush,创建索引,创建checkpoint,存入新的segment file
  • failover:如果datanode节点挂了导致写文件失败,可以重新更换节点,进行重新写入

3.7 Proxy

  • 接受request,等待,存入cache,到达大小,返回数据
  • miss,进入storage,打开file,寻找阅读

3.8 多机房部署

  • proxy可以分别部署到多个broker上
  • 每个机房处理全量的partition
  • 在本地可以访问proxy
  • broker需要全部机房加在一起才能成为一个topic的全部分片

3.9 泳道消息

  • 解决主干泳道流量隔离问题以及泳道资源重复创建问题 Screen Shot 2023-02-09 at 10.06.51 AM.png

3.10 Databus

  • 使用原生SDK的问题
    • 客户端配置较为复杂
    • 不支持动态配置,更改配置需要停服
    • latency不敏感业务,batch效果不佳
  • 使用Databus
    • 简化消息队列客户复杂度
    • 解藕业务与topic
    • 缓解集群压力,提高吞吐

3.11 Mirror

  • 跨region读写的问题
    • 使用mirror通过最终一致方式解决 Screen Shot 2023-02-09 at 10.09.19 AM.png

3.12 Index

  • 希望通过写入的logid和userid或其他业务字段进行消息查询应该怎么做?
    • 创建索引表
    • 直接在BMQ中数据结构化,异步构建索引,通过index query读出数据

3.13 Parquet

  • 新型列式存储方式
  • 在BMQ中通过parquet engine可以使用不同方式构建parquet格式文件

4. RocketMQ

4.1 基本概念

  • 使用场景:低延时,针对电商、实时业务、业务峰值等
  • 与kafka区别
    • 拥有消息标签Tag:在topic下还能进行区分
    • partition——consumerqueue
    • 拥有生产者集群
    • controller——nameserver

4.2 RocketMQ架构

Screen Shot 2023-02-09 at 10.14.32 AM.png

4.3 存储模型

  • 所有数据发送到broker的commitLog
  • 根据分区,发送到不同的consumerqueue
  • 在consumerqueue中只存储offset

4.4 事务场景

  • 最终一致性 Screen Shot 2023-02-09 at 10.16.25 AM.png
  • 延迟发送/延迟消息:在consumerqueue提取后有scheduler进行延迟
  • 消费重试,死信队列:消费失败,若没超过最大重试次数,则投递至scheduleTopic,schedule延时投递到retryTopic队列
    • 若超过最大重试次数,发送到死信队列

三、课堂总结

本节课介绍了消息队列的相关知识。在大数据班的学习中,曾经学过Kafka相关的内容。而在本次课程中主要了解了Kafka、BMQ以及RocketMQ相关的知识。课程比较抽象,需要在课后结合代码进行进一步学习。