写点什么

理解 RocketMQ

用户头像
awen
关注
发布于: 2021 年 02 月 26 日
理解RocketMQ

目录

  1. 概念

  2. 架构

  3. 部署

  4. 客户端工具

  5. 最佳实践

  6. 例子

  7. 附录

概念

  1. Apache RocketMQ 是一个分布式、流式模型的消息平台,有如下几个特点:

1. low latency

2. high perference

3. Reliability

4. trillion-level capacity

5. flexible scalability

  1. Apache RocketMQ 提供了 OpenMessaging 的默认实现

  2. WHY: 点我奥

架构

四大组成部分

  1. Name Servers

  2. Brokers

  3. Producers

  4. Consumers


以上四大部分均可以水平扩展,不存在单点的问题


NameServer Cluster

Name Servers 提供了轻量级的服务发现与路由功能。每个 NameServer 记录了全量的路由信息,并提供相应的读写服务,支持快速存储扩容


Broker Cluster

Brokers 通过提供轻量级的 Topic 和 Queue 机制来管理消息存储。支持推和拉模型,容错机制(2 copys or 3 copys),提供了强大的消锋填谷和累计百亿级顺序消息堆积能力。另外,Brokers 还提供了其他传统消息系统中缺少的灾难恢复、丰富的指标统计和告警机制等。


Producer Cluster

Producers 支持分布式部署。分布式的生产者通过多种负载均衡方式发送消息至 Broker。消息发送处理支持快速失败和低延时。


Consumer Cluster

Consumers 支持分布式部署,即支持推模型也支持拉模型。Consumers 同样支持集群消费和广播。Consumers 提供了实时消息订阅机制且能满足大部分 Consumer 需求。


Name Server

NameServer 是一个完全的基础性服务,提供了两大特性:

1. Broker 管理,NameServer 接收 Broker Cluster 的注册请求并提供了心跳监测机制对 Broker 判活

2. Routing 管理,每个 NameServer 包含了 Broker 集群的所有路由信息和客户端查询的队列信息。

客户端如何获取 NameServer 的地址信息?有四种方式:

1. 硬编码:producer.setNamesrvAddr("ip:port”)

2. Java Options:rocketmq.namesrv.addr

3. 环境变量:NAMESRV_ADDR

4. Http endpoint


Programmatic Way > Java Options > Environment Variable > HTTP Endpoint

详情见:http://rocketmq.apache.org/rocketmq/four-methods-to-feed-name-server-address-list/


Broker Server

Broker 负责消息存储、发送、查询、HA 等,主要包含如下几个模块:

1. Rmoting Module:borker 入口,负责处理请求

2. Client Manager:管理客户端(Produer & Consumer)和客户端订阅 Topic 信息

3. Store Service:提供简易 API 从物理硬盘存储和查询消息

4. HA Service:提供了主从之间的数据同步特性

5. Index Service:针对消息特定的 key 构建索引,方便快速查询

部署

Broker

Brokers 根据角色划分可以分为两大类:Master & Slave

Master 提供读写访问操作而 Slave 只提供读操作。

为了搭建没有单点故障的高可用 Broker 集群,需要部署几个 Broker 集。一个 Broker 集包含一个 Master(brokerId=0)和几个 brokerId 不重复的 slaves(brokerId!=0),一个 broker set 中的所有 broker 拥有相同的 brokerName。在一些场景中, 一个 broker set 一般至少包含两个 broker。每个 Topic 至少在两个或两个以上的 broker 存在。


NameServer

建议至少部署两台 NameServer,以确保在一个实例 crash 后整个集群可以继续提供服务。只要有一台 NameServer 存活,整个集群即可用。

NameServer 遵循各自独立不共享的设计模式。所有 Broker 发送信息数据到所有 NameServer。Producer/Consumer 当发送或接收消息的时候可以从任何一个存活的 NameServer 获取 meta data。


##Broker 配置


客户端工具 CLI Admin Tool


复制模式

1. 为了确保成功发送的消息不丢失,RocketMQ 提供了 Sync & Async 两种复制模式

2. 像很多其他系统一样,sync brokers 等待 commit log 成功复制到 slave 后再确认。而 Async brokers,消息被 master 处理后立即返回。


最佳实践

  1. 核心概念

  2. Broker

  3. Producer

  4. Consumer

  5. NameServer

  6. JVM/Kernel Config


##核心概念


  1. Produer

生产者发送业务系统产生的消息到 brokers。RocketMQ 提供了多重发送方式:同步、异步、one-way(比如日志)


  1. Produer Group

相同角色的生产者聚集成组。为了防止原来的生产者 crash after transaction,同组下的另一个生产者实例会被 broker 通知 coomit or role back transaction。

注意:一般一个组下一个 producer 实例已经足够可靠,减少不必要的开销

  1. Consumer

消费者从 brokers 获取消息反馈给应用。RocketMQ 提供了两种类型的 comsumers

1. PullConsumer

2. PushConsumer

封装 pulling,消费处理,提供消费接口供 Consumer 实现处理逻辑


  1. Consumer Group

1. 与前面提到的 Producer Group 概念非常类似,完全相同角色的 comsumers 聚集成组为 Consumer Group

2. Consumer Goup 是一个广泛的概念,在消息消费方面,达到负载均衡,容错处理非常简单。

3. 同组下的消费者实例必须拥有完全相同的 Topic 订阅


  1. Topic

Topic 是生产者发送消息和消费者拉去消息的范畴。Topics 与 producers & consumers 之间松耦合。可以有 0,1 或多个 producers 发送消息到一个 Topic;反过来,一个 producer 发送消息到不同的 topics。从消费端开来,一个 topic 可以被 0,1 或多个 consumer groups。而一个 consumer group,类似的可以订阅 1 或多个 topics 只要这个 consuer group 下的实例保持一致的订阅。


  1. Message

Message 是被传送的信息。一个 message 必须包含一个 topic(可以理解为邮件发送地址)。一个消息可以包含一个可选择的 tag 和一些额外的 key-value 属性。比如,在开发过程中你可以设置一个业务 key 在你的消息并且在 broker 上查找消息来定位问题。


  1. Message Queue

Topic 被分为 1 到多个 sub-topics,”message queues”


  1. Tag

Tag,换句话说 sub-topic,为用户提供了额外的弹性。With tag,相同业务模块的不同用途的消息可以拥有相同的 topic 和不同的 tag。Tags 对我们代码的整洁性和清晰度是有益的,并且 tags 可以完善 RocketMQ 提供的查询机制

  1. Broker

Broker 是 RocketMQ 系统的一个重要组件。它接收来自 producers 发来的消息,存储并处理来自 consumers 端的拉取请求。Broker 也存储了消息关联的 meta data,包括 consumer groups,consuming progress offsets 以及 topic/queue 信息。


  1. Name Server

NameServer 作为路由信息提供者服务。Producer/Consumer 客户端查询 topics 找到相应的 broker list。


  1. Message Model

Cluster

Broadcasting


  1. Message Order

Oderly

Concurrently


  1. Broker

Broker Role:Broker 分为 ASYNCMASTER,SYNCMASTER 和 SLAVE.如果不能容忍消息丢失,建议 m-s-sync 模式部署。如果可以接受消息丢失,但希望高可用,建议 m-s-async 模式部署。如果想简单点,可以 as-no-。s 部署。

FlushDiskType:建议 ASYNCFLUSH,因为 SYNCFLUSH 带来高昂的开销而损失性能。如果期望可靠性高,建议使用 m-s-sync。

ReentrantLock VS CAS

os.sh


  1. Producer

SendStatus

FLUSHDISKTIMEOUT

FLUSHSLAVETIMEOUT

SLAVENOTAVAILABLE

SEND_OK

Duplication or Missing

消息重试

消息幂等,防止 Consumer 重复消费

Timeout

缺省超市时间为 3 秒,可以自定义 send(msg, timeout),不建议超时时间太长

Message Size

建议不超过 512k,一批不超过 1M

Async Sending

Producer Group

在同一个 jvm 中在一个 producer group 只能创建一个 producer 实例,一个就足够了

Thread Safety

Performance

3~5 个 producers,异步发送

为每个 producer 设置实例名字


  1. Consumer

不同 Consumer Group 可以独自消费相同的 topic,并且各自有各自的消费 offsets。确保下同 Group 的 Consumer 订阅了相同的 topics

MessageListener

Orderly

消费者锁定消息队列确保顺序消费。这样会带来性能开销,但如果你关心消息的是有帮助的。不建议抛出异常,可返回 SUSPENDCURRENTQUEUEAMoment。

Concurrently

并发访问,高性能。同样不建议抛出异常,建议返回 RECOMSUME_LATER。

Consume Status

Blocking

不建议阻塞监听,因为这样会阻塞线程池,甚至停止消费进程

Thread Number

Consumer 内部使用线程池处理消费,可以设置 setConsumeThreadMin 和 setConsumeThreadMax

ConsumeFromWhere

CONSUMEFROMLAST_OFFSET

CONSUMEFROMFIRST_OFFSET

CONSUMEFROMTIMESTAMP

Duplication

原因

Producer 消息重发

Consumer 停止导致一些 offsets 没有及时更新到 Broker

解决方案

幂等


  1. NameServer

在 RocketMQ 中,NameServers 被设计用来协调分布式系统中的组件,协调工作主要通过管理 topic 路由信息完成。

两大协调工作

1. Brokers 定期同步更新 meta data 到每个 name server

2. NameServers 用最新的路由信息服务于 producers,consumers 和命令行。


  1. JVM

JVM Options

Version jdk1.8

-server -Xms8g -Xmx8g -Xmn4g

如果不关心 Broker 的启动时长,可以设置

-XX:+AlwaysPreTouch

关闭 biased locking 减少 jvm 停顿,可以设置:

-XX:-UseBiasedLocking

Use G1

-XX:+UseG1GC -XX:G1HeapRegionSize=16m -XX:G1ReservePercent=25 -XX:InitiatingHeapOccupancyPercent=30

Rolling GC log file

-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=30m

GC log file 指向内存文件系统

-Xloggc:/dev/shm/mqgc%p.log


  1. Kernel Config

Linux Kernel Parameters

os.sh

vm.extrafreekbytes

RocketMQ 使用此值降低内存分配延迟

vm.minfreekbytes

低于 1024k,系统容易宕机,在高负载下容易死锁

vm.maxmapcount

RokcetMQ 使用 mmqp 加载 CommitLog 和 ConsumeQueue,建议调高这个参数

vm.swappiness

建议 10

File descriptor limits 建议设置为 655350

Disk scheduler 建议 deadline IO


附录

附录 1

Linux 磁盘 IO 调度策略

1. cfq(Complete Fairness Queueing),这是一个复杂的调度策略,按进程创建多个队列,试图保持对多个进程的公平(忽略了读、写操作的不同消耗)

2. deadline,这是一个比较单间的策略,只分了读和写两个队列(加速读取量比较大的系统),内核为每个 IO 操作设置了一个超时时间

3. noop,这个策略最简单,只有单个队列,只有一些简单合并操作


附录 2

文件句柄数(文件描述符)设置

shell 级,ulimit –n num

用户级,修改/etc/security/limitis.conf

root soft nofile 65535

root hard nofile 65535

备注:

1、soft 数小于等于 hard 数

2、系统会给出一个建议值/proc/sys/fs/file-max,但是 limits.conf 设定可以超过建议值


附录 3

MMAP VS DMA

MMAP:将磁盘文件映射到内存,通过修改内存就能达到修改磁盘文件的目的。利用操作系统的 Page 实现文件到物理内存的映射,之后对物理内存的操作会在适当的时候同步到硬盘上。适合大量小数据块高效传输,依赖于 cpu,不太适合大数据块传输。

DMA:Direct Memory Access,是一种硬件机制,降低对 cpu 的依赖,适合大数据块传输。


发布于: 2021 年 02 月 26 日阅读数: 21
用户头像

awen

关注

Things happen for a reason. 2019.11.15 加入

还未添加个人简介

评论

发布
暂无评论
理解RocketMQ