前言
在 Broker端进行消息过滤
消息的Tag和Key
通过 Tag 进行过滤
用 SQL 表达式的方式进行过滤
Filter Server方式过滤
提高 Consumer 处理能力
Consumer 的负载均衡
提高 Producer 的发送速度
《RocketMQ实战与原理解析》
前言
本章介绍在大流量场景下,提高 RocketMQ 集群吞吐量的一些方法,有些方法当服务器出异常时会增大丢消息的概率,用户需要根据业务需求酌情使用。
在 Broker端进行消息过滤
在 Broker 端进行消息过滤,可以减少无效消息发送到 Consumer ,少占用网络带宽从而提高吞吐量。Broker 端有三种方式进行消息过滤。
消息的Tag和Key
对一个应用来说,尽可能只用一个 Topic ,不同的消息子类型用 Tag 来标识(每条消息只能有一个 Tag ),服务器端基于 Tag 进行过滤,并不需要读取消息体的内容,所以效率很高。发送消息设置了 Tag 以后,消费方在订阅消息时,才可以利用 Tag 在 Broker 端做消息过滤。
其次是消息的Key。对发送的消息设置好 Key ,以后可以根据这个 Key 来查找消息。所以这个 Key 一般用消息在业务层面的唯一标识码来表示,这样后续查询消息异常,消息丢失等都很方便 Broker 会创建专门的索引文件,来存 Key 到消息的映射,由于是哈希索引,应尽 Key ,避免潜在的哈希冲突。
Tag 和 Key 的主要差别是使用场景不同, Tag 用在 Consumer 的代码中,用来进行服务端消息过滤, Key 主要用于通过命令行查询消息。
通过 Tag 进行过滤
用 Tag 方式进行过滤的方法是传人感兴趣的 Tag 标签,Tag 标签是一个普通字符串,是在创建 Message 的时候添加的, Message 只能有一个 Tag 使用 Tag 方式过滤非常高效, Broker 端可以在 ConsumeQueue 中做这种过滤, 只从 CommitLog 里读取过滤后被命中的消息 ConsumerQueue 的存储 格式,如图所示
![94f260a5cd6719ccd8931ed8692ad770.png](https://i-blog.csdnimg.cn/blog_migrate/3010a21374dca7831f63eb01934ac00a.png)
Consume Queue 部分存储的是 Tag 对应的 hashcode ,是一个定长的 字符串,通过 Tag 过滤的过程就是对比定长的 hashcode。经过 hashcode 对比, 符合要求的消息被从 CommitLog 读取出来,不用担心 Hash 冲突问题,消息在被消费前,会对比完整的 Message Tag 字符串,消除 Hash 冲突造成的误读。
用 SQL 表达式的方式进行过滤
使用 Tag 方式过滤虽然高效,但是支持的逻辑比较简单,在构造 Message 的时候,还可以通过 putUserProperty 函数来增加多个自定义的属性,基于这些属性可以做复杂的过逻辑。
Message msg =new Message("TopicTest", tag, ("Hello RocketMQ " + i).getBytes(RemotingHelpe.DEFAULT_CHARSET));
/// Set some properties .
msg.putUserProperty("a", String.valueOf(i));
msg.putUserProperty("b", "hello");
代码中这个消息就有了两个特殊的属性值 a 和 b ,我们用类似 SQL 表达式的方式对消息进行过滤,用法如下(目前只支持在 PushConsumer 中实现这种过滤) :