实时任务数据丢失

20 篇文章 4 订阅

1. 背景描述

flink实时任务:

  1. 从kafka集群读取源数据
  2. 从redis定期全量拉取用户白名单,然后进行广播
  3. 源数据connect白名单数据,源数据根据白名单数据进行过滤处理
  4. 过滤处理完后的数据,http推送、写redis、写log等

2. 问题分析

上线验证的时候,有些数据丢失,而且比较频繁,分析可能原因:

  1. kafka源数据丢失。这个有可能,但是小概率事件,不应该那么频繁出现。
  2. redis拉取白名单后广播操作。这个有可能,需要重点排查。
  3. 过滤以及数据处理。这个不太可能,可以添加日志证明自己猜想,实际也是没有问题的。
  4. http推送、写redis、写log等错误。这些操作比较稳定,也没有太大问题。

3. 定位排查

3.1 redis拉取数据并广播

分析代码,有两个问题

  • redis拉取间隔短,每隔2秒钟拉取一次。如果间隔短,数据量大会有性能问题;如果间隔大,白名单生效时间又受影响。刷新间隔将2秒改成2分钟,还是可以接受。
  • 广播变更更新逻辑:获取广播状态,先clear后更新,clear和更新之间会有问题,示例代码如下:

if (in2._2.nonEmpty) {
  val broadcastState = context.getBroadcastState(whiteListDesc) // 获取广播状态
  broadcastState.clear // 先删除
broadcastState.put(in2._1, in2._2) // 后更新
}

上述代码有三个问题:一是clear后可能刚好有有数据到达,但还put还没有生效,这时数据无法正确处理;二是clear操作其实可以删除,put操作时会删除旧和更新最新值;三是没有比较新旧值,直接put操作,频率写操作,性能低下,事实上白名单也并不经常更新,所以put之前最好判断一下。

正确处理方式:应该获取广播变量,与最新数据对比,如果不相等,才更新广播,优化后如下 :

// 更新状态
if (value._2.nonEmpty) {
val broadcastState = context.getBroadcastState(whiteListDesc) // 获取广播状态

  // 获取广播变量,新旧比较,如果不等才更新,否则忽略
val newSet = value._2
val oldSet = broadcastState.get(value._1)
if (Tools.equals(oldSet, newSet) == false) {
broadcastState.put(value._1, value._2)
}
}

3.2 kafka集群消息丢失

变量广播问题解决之后,发现还是有数据丢失。仔细跟踪,生产端是双活生产,就是数据可能随机写两个kafka集群,但消费端将两个fafka集群的brokers合成当作一个kafka集群的brokers。实际两个集群的brokers之间是有分号隔开的。

示例代码如下

DataStream<ConsumerRecord<String, String>> stream = env.addSource(getConsumer(params, brokers));

将两个或者多个集群的brokers按分号隔开,创建两个或者多个DataStream,然后再union,修改后如下

DataStream<ConsumerRecord<String, String>> streams = null;
List<String> brokerList = Arrays.asList(params.get(game + ".kafka.source.brokers").split(";"));
for (int index = 0; index < brokerList.size(); ++index) {
    String brokers = brokerList.get(index);
    DataStream<ConsumerRecord<String, String>> stream = env.addSource(getConsumer(params, brokers))
            .setParallelism(parallelism)
            .name("kafka-reader-" + index)

    if (streams == null) {
        streams = stream;
    } else {
        streams = streams.union(stream);
    }
}

重新验证问题,数据丢失的问题解决。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值