环境
当前方法
- 使用kafkaStream.foreachRDD (new VoidFunction<JavaRDD<String>>() {
@Override
public void call(JavaRDD<String> microBatch) throws Exception {
ClientConfig clientConfig = new ClientConfig();
clientConfig.addAddress("myHost:5701"); //Define connection
HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
//Do processing
}
}
对数据进行操作,并为每个微批(RDD)建立连接。这种情况每30秒发生一次(Durations.seconds(30))。
COPY atomic.events
FROM 's3://path-to/bucket/THE_FILE_NAME.extension'
CREDENTIALS 'aws_access_key_id=xxx;aws_secret_access_key=xxx'
REGION AS 'eu-west-1'
DELIMITER '\t'
MAXERROR 1
EMPTYASNULL
FILLRECORD
TRUNCATECOLUMNS
TIMEFORMAT 'auto'
ACCEPTINVCHARS
LZOP;
提问:想要在每个Spark工作者上打开一次连接(提交作业时),而不是每个微批次的新连接。什么是实现这一目标的正确方法?
答案 0 :(得分:0)
由于Spark序列化作业并将其分发到Workers,因此重写反序列化方法以执行 init 任务(创建JDBC连接,初始化变量等)有助于Spark Streaming。
覆盖默认反序列化方法(Java)
@Override
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
//Init 1
ClientConfig clientConfig = new ClientConfig();
clientConfig.addAddress("myHost:5701"); //Define connection
HazelcastInstance client = HazelcastClient.newHazelcastClient(clientConfig);
//Init 2
kafkaProducer=new KafkaProducer<>(kafkaProducerProps);
}
或者,可以使用static hack进行初始化任务,直到Cloudera / Databricks人员添加init support inherently in Spark。
答案 1 :(得分:0)
您需要的信息在这里得到了很好的解释: https://spark.apache.org/docs/latest/streaming-programming-guide.html#design-patterns-for-using-foreachrdd
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
}
}
在foreachPartition中,主体在执行程序中本地执行。在那里,您可以建立静态客户端连接(例如,每个工作人员将使用其自己的静态对象)
希望对您有帮助。
谢谢