SparkStreaming的foreachPartition理解

首先我们要知道:

foreachRDD 作用于 DStream中每一个时间间隔的 RDD

foreachPartition 作用于每一个时间间隔的RDD中的每一个 partition

foreach 作用于每一个时间间隔的 RDD 中的每一个元素。

foreachRDD是作用在driver端的一种最常见的输出方式,而其他都作用在executor端。

所以注意!在driver端建立类似连接的话(或者想作为共享变量的对象)

rdd是获取不到的!这就是为什么我在向hbase写DStream的时候迟迟写不进去的原因!

举例:

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

当然 我们接下来肯定是想着把连接写到foreach里面解决问题的,但是这样容易炸!

因为每次遍历RDD的时候都会产生一个连接 创建连接和关闭连接都很频繁 造成系统不必要的开销

于是我们就用foreachPartition解决问题!

// 使用foreachPartitoin来减少连接的创建,RDD的每个partition创建一个链接
dstream.foreachRDD { rdd =>
  rdd.foreachPartition { partitionOfRecords =>
    val connection = createNewConnection()
    partitionOfRecords.foreach(record => connection.send(record))
    connection.close()
  }
}

还有优化手段 因为分区过多的话连接数也会变多 于是还可以用线程池

// 使用静态连接池,可以增加连接的复用、减少连接的创建和关闭。
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
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

后季暖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值