FMQ的同步中间件英文名称为MirrorMaker,是在FMQ-Client的基础上引变而来的,用来作为跨机房的数据同步的工具。在网络异常等特殊情况下,也能在可靠性和性能上都能够满足公司线上需求而开发的一套同步中间件。
MirrorMaker设计思路比较好理解,利用消费者从源机房拉取消息,并利用生产者发送消息至目标机房。但往往网络环境、broker集群稳定性、topic队列都会不断变化,在这种特殊情况下,也要实现一个高可靠、高性能的消息同步中间件需要考虑的细节非常多。比如消息幂等性、自动监控并切换网络出口、监控异常报警等。FMQ-mirrormaker就是针对这种特殊场景进行了定制化开发,实现高可靠和高性能的消息同步中间件。
配置管理:配置source和target的broker的url、同步线程数、报警配置以及队列大小等
报警管理:基于event发布中心订阅相关的事件,并接入报警平台进行报警
消息同步管理:包括消费者管理、队列管理、生产者管理、Offset管理
监控管理:实时从broker获取需要监控的数据,并暴露接口给fmq-monitor获取监控数据
mirrormaker-api:暴露api接口,供外部调用
mirrormaker-biz:具体的业务逻辑,包括监控、同步、报警、配置等信息
mirrormaker-bootstrap:启动类,包括(监控,配置、报警、消息同步)四大服务的启动
AbstractBootstrap: 作为最上层的抽象类,提供了doBootstrap()、doShutdown()供子类去实现,同时还持有事件发布接口、日志接口以及Config
Monitor:持有 SyncManager 实例,通过它来获取监控数据
Alarmer:通过订阅相关的事件提供报警服务
SyncManager:TargetDCProducer、SourceDCConsumer和TopicAndOffsetManager的大管家,用来协调消息同步。同时还会监听相应的事件,比如 网络不通、网络切换、新增同步topic、修改partition等等,对这些事件进行相应的处理来保证消息同步的正确性。
TopicAndOffsetManager:
1、获取需要同步的topic和分区,并定期更新topic和分区
2、获取并管理当前环境的source和target端的 分区对应的offset(source->brokerOffset、commitOffset,target->brokerOffset)
SouceDCConsumer:
订阅需要同步的topic,并将消息放入queue中。定期提交缓存中的offset。
TargetDCProducer:
每个partition会启动一个线程来读取queue中消息,并写入目标broker,写成功后,将该消息的offset提交至缓存中。
mirrormaker基于candy2的事件中心对异常情况进行了处理,使其真正意义上保证了跨机器消息同步的可靠性和实时性。
主要事件如下:
add_topic:定期检测是否有新增topic并加入至同步列表中
remove_topic:释放占有的资源
modify_partion_num:定期检测,并将修改后的分区加入同步列表中
source_net_not_available: 定期检查网络情况,不通则抛出事件,由Alarmer报警
source_net_be_switched: 如果网络不通时间超过一定阀值,则会对source 网络进行切换(事先备好备用网络出口),切换成功后,再进行同步
target_net_not_available:目标端网络不通,抛出事件,由Alarmer报警 (备注:target的broker 一般和mirrormaker在同一机房,网络不通也不需要切换)
由于同步过程中,任何情况都可能发生,所以对于offset的何时提交尤为重要。一般正常情况是消费一条消息就提交,这样会存在以下二个问题:
(1)频繁提交,会无形中给服务器增加压力
(2)作为同步中间件,应将整个同步的过程作为一个原子操作,也就是说消息要真正写入target端,才算同步成功,此时offset才会提交,否则不算同步成功
基于以上二种情况,我们在消息同步成功后将offset存入缓存中,并由消费者定期提交缓存中的offset,这样既降低了因频繁提交offset给服务器增加的压力,也将同步过程作为一个原子操作。同时还提供了饿JVM的钩子,保证宕机情况下,缓存里的offset能正常提交。
主要功能点:
1、获取各点mirrormaker的监控数据
Source端的TPS、Target端的TPS
partition的sourceoffset、cacheoffset、commitoffset、lag(同步滞后数)
2、手动操作mirrormaker,比如网络不通,可以手动切换网络等等
实现一个简单的同步中间件还是比较容易,但要在特殊情况下实现一个高可靠、高性能的同步中间件还是相对复杂的多,本章中的大幅篇幅基本上都是围绕如何建立高可靠、高性能的同步中间件。同步同步中间件实现消息的正常传输。