关于DStream的输出(foreachRDD)操作

输出操作允许将Dstream的数据推送到外部系统,例如数据库或文件系统。由于输出操作实际上允许外部系统使用变换后的数据,所以他们触发所有DStream变换的实际执行(类似于RDD的action操作)。目前定义了以下输出操作:

这里写图片描述

使用foreachRDD的设计模式

dstream.freachRDD是一个强大的语句,允许将数据发送到外部系统。但是,了解如何正确有效地使用这个语句很重要。下面提供以下常见的错误:

通常向外部系统写入数据需要创建一个连接对象(例如远程服务器的TCP连接)并使用它将数据发送到运城系统。为此,开发人员可能会无意中尝试在Spark 的Driver中创建连接对象,然后尝试在Spark Worker中使用它来在RDD中保存记录。例如:

dstream.foreachRDD { rdd =>
  val connection = createNewConnection()  // executed at the driver
  rdd.foreach { record =>
    connection.send(record) // executed at the worker
  }
}

这是不正确的,因为这需要将连接对象序列化并从驱动程序发送到工作人员。这样的连接对象很少能跨机器传输。此错误可能会显示为序列化错误(连接对象不可序列化),初始化错误(连接对象需要在Worker初始化)等。正确的解决方案是在Worker创建连接对象。
但是,这可能会导致另一个常见的错误,为每个记录创建一个新的连接。例如:

dstream.foreachRDD { rdd =>
  rdd.foreach { record =>
    val connection = createNewConnection()
    connection.send(record)
    connection.close()
  }
}

通常,创建连接对象具有时间和资源开销。因此,创建和销毁每个记录的连接对象可能会引起不必要的高开销,并可显著降低系统的总体吞吐量。一个更好的解决方案是使用rdd.foreachPartition-创建一个连接对象,并使用该连接对象在RDD分区中发送所有记录。

dstream.foreachRDD { rdd =>
  rdd.foreachPartition { partitionOfRecords =>
    val connection = createNewConnection()
    partitionOfRecords.foreach(record => connection.send(record))
    connection.close()
  }
}

这样可以在多个记录上分摊连接创建开销。
最后,可以通过跨多个RDD/批次重用连接对象来进一步优化。可以维护连接对象的静态池,而不是将多个批次的RDD推送到外部系统时重新使用,从而进一步减少开销

dstream.foreachRDD { rdd =>
  rdd.foreachPartition { partitionOfRecords =>
    // ConnectionPool is a static, lazily initialized pool of connections
    val connection = ConnectionPool.getConnection()
    partitionOfRecords.foreach(record => connection.send(record))
    ConnectionPool.returnConnection(connection)  // return to the pool for future reuse
  }
}

请注意,池中的连接应根据需要是懒加载,如果一段时间不使用,则会超时。这实现了最有效的将数据发送到外部系统。
其他需要记住的点
1.DStreams通过输出操作进行延迟执行,就像RDD由RDD action操作进行延迟执行。具体来说,DStream输出操作中的RDD动作强制处理接收到的数据。因此,如果你的应用程序没有任何输出操作,或者具有dstream.foreach()等输出操作,而在其中又没有任何RDD操作,则不会执行任何操作。系统将简单的接收数据并将其丢弃。
2.默认情况下,输出操作是一个一个执行的。他们按照他们在应用程序中定义的顺序执行。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值