SparkStreaming之foreachRDD的正确使用姿势

SparkStreaming之foreachRDD的正确使用姿势

1、错误方式

假如connection不支持序列化,那么会报序列化相关的异常,因为connection在Driver端生成,一般的连接是不支持序列化的,需要被序列化之后传递到Executor端,所以这样尽量避免

dstream.foreachRDD { rdd =>
  //创建一个连接
  val connection = createNewConnection()  // 代码在Driver端执行
  rdd.foreach { record =>
    connection.send(record) // 代码在Executor执行
  }
}

2、小小改正

小小的改正就是将connection的创建在Executor端执行

dstream.foreachRDD { rdd =>
  rdd.foreach { record =>
    val connection = createNewConnection() //在Executor端执行
    connection.send(record)
    connection.close()
  }
}

3、进一步改正

在2中,实际上是为每个RDD的每个元素都创建了一个连接,这样会增加不必要的资源创建、销毁开销,所以尽量一个分区创建一个connection

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

4、最终优化

虽然3有了进一步的节省资源开销,但是还是不尽人意,所以用一个连接池作为静态对象,来创建相应的连接

//请注意,应按需延迟创建池中的连接,如果一段时间不使用,则超时,这样可以最有效地将数据发送到外部系统
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
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值