一般通过订阅mysql的binlog 异构数据到别的存储,如ES。
大概的流程为通过databus或者canal 这样的组件订阅binlog,发送kafka队列,通过flink消费kafka。因为我们这边业务比较特殊,导致mysql数据的变更有尖刺的情况,在业务高峰期数据变更的QPM为60W/分钟,flink最大的消费能力为20W/分钟,在这种消费速度和生产速度不对等的情况,ES的数据有会10分钟以上的延时。 因此需要提升flink的的并发数,但是当flink的并发数大于kafka partition的数据量时,会有乱序的问题影响数据的一致性。
比如:10分01秒修改id=100这条数据的状态为1,10分02秒修改状态为2,flink并发消费时候不能100%的保证先处理01秒的数据,在处理02秒的消息。如果先处理02秒的数据,最后处理01秒的数据,那就会造成mysql和ES数据不一致的问题,mysql状态为2,ES中状态为1。解决方法就是如果如果先处理的02秒的消息,再收到01秒的消息时直接丢弃即可。
在flink中可以很轻易的实现过期消息的过滤,通过flink keyby方法+ status 即可,代码如下:
package com.ikuboo.learn.flink.datastream;
import org.apache.flink.api.common.functions.RichFilterFunction;
import org.apache.flink.api.common.state.StateTtlConfig;
import org.apache.flink.api.common.state.ValueState;
import org.apache.flink.api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.time.Time;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.datastream