RocketMQ的服务端数据过滤机制实践

86 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情

前言

我们还是看数据库同步这块技术设计场景。一个数据库中可能会包含很多表的数据,比如订单数据库,他里面除了订单信息表以外,可能还包含很多其他的表。 所以我们在进行数据库binlog同步的时候,很可能是把一个数据库里所有表的binlog都推送到MQ里去的!
所以在MQ的某个Topic中,可能是混杂了订单数据库里几个甚至十几个表的binlog数据的,不一定仅仅包含我们想要的表的binlog数据!
那么此时假设我们的大数据系统仅仅关注订单数据库中的表A的binlog,并不关注其他表的binlog,那么大数据系统可能需要在获取到所有表的binlog之后,对每条binlog判断一下,是否是表A的binlog?
如果不是表A的binlog,那么就直接丢弃不要处理;如果是表A的binlog,才会去进行处理! 但是这样的话,必然会导致大数据系统处理很多不关注的表的binlog,也会很浪费时间,降低消息的效率。

解决方案

在发送消息的时候,给消息设置tag和属性

/**
 * 有参构造函数.
 *
 * @param topic 消息主题, 最长不超过255个字符; 由a-z, A-Z, 0-9, 以及中划线"-"和下划线"_"构成.
 * @param tag 消息标签, 请使用合法标识符, 尽量简短且见名知意
 * @param key 业务主键
 * @param body 消息体, 消息体长度默认不超过4M, 具体请参阅集群部署文档描述.
 */
public Message(String topic, String tag, String key, byte[] body) {
    this.topic = topic;
    this.body = body;

    this.putSystemProperties(SystemPropKey.TAG, tag);
    this.putSystemProperties(SystemPropKey.KEY, key);
}

在消费消息的时候,根据tag和属性进行过滤

consumer.subscribe("TopicName","tagA tagB");

RocketMQ还是支持比较丰富的数据过滤语法的,如下所示:
(1)数值比较,比如:>,>=,<,<=,BETWEEN,=;
(2)字符比较,比如:=,<>,IN;
(3)IS NULL 或者 IS NOT NULL;
(4)逻辑符号 AND,OR,NOT;
(5)数值,比如:123,3.1415;
(6)字符,比如:'abc',必须用单引号包裹起来;
(7)NULL,特殊的常量
(8)布尔值,TRUE 或 FALSE