Flink消耗的内存超出预期

时间:2018-05-03 13:51:56

标签: scala hdfs apache-flink ram rocksdb

我使用Flink 1.4.1处理事务事件,使用HDFS存储检查点信息以进行容错。

创建了一个作业,用于汇总有关客户,星期几和小时的信息,从而创建一个配置文件,如下面的代码所示。

val stream = env.addSource(consumer)
val result = stream
  .map(openTransaction => {
    val transactionDate = openTransaction.get("transactionDate")
    val date = if (transactionDate.isTextual)
      LocalDateTime.parse(transactionDate.asText, DateTimeFormatter.ISO_DATE_TIME).toInstant(ZoneOffset.UTC).toEpochMilli
    else
      transactionDate.asLong
    (openTransaction.get("clientId").asLong, openTransaction.get("amount").asDouble, new Timestamp(date))
  })
  .keyBy(0)
  .window(SlidingEventWeekTimeWindows.of(Time.days(28), Time.hours(1)))
  .sum(1)

在上面的代码中,流有三个字段:" transactionDate"," clientId"和"金额"。我们通过clientId创建一个键控流和一个总和量的滑动窗口。我们的数据库中有大约100.000个唯一的活动clientIds。

运行一段时间后,作业使用的总RAM稳定在 36 GB ,但HDFS中存储的检查点仅使​​用 3 GB 。有没有办法减少作业的RAM使用率,可能是通过配置Flink的复制因子或使用RocksDB?

1 个答案:

答案 0 :(得分:1)

使用RocksDB绝对应该考虑这个状态大小,并且根据使用模式,可以使用更小的检查点,因为它只通过复制新的或更新的SST来递增地执行。

要注意的一些事项,请记住:

  • 每个有状态运算符并行子任务都有自己的RocksDB 实例。
  • 如果您确实切换到RocksDB进行检查点操作 开始运行比你需要的慢,确保 您正在使用的序列化尽可能高效。
  • Flink根据您的支持文件系统提供一些PredefinedOptions,确保您选择适当的
  • 如果预定义选项不适合您,您可以覆盖RocksDB后端的OptionsFactory并微调各个RocksDB选项

关于Flink中具有键控时间窗口的内存使用情况的另一个注意事项是,如果您要进入数十万或数百万,“定时器”可能会占用大量内存。 Flink计时器是基于堆的(在撰写本文时)并且独立于状态后端进行同步检查点。