欢迎关注github《大数据成神之路》
什么是输出操作:?
- 输出操作是针对流数据经过转化操作后得到数据要执行的操作
- 输出操作和RDD的惰性求值是一样的道理,如果Dstream没有被执行输出操作 ,那么Dstream就都不会被求值
- 我们之前使用的print()就是一种调试性输出
- Dstream有spark类似的save()的操作
saveAsHadoopFiles()函数的使用
代码案例:
result.saveAsHadoopFiles("outputDir","txt",Text.class,LongWritable.class,outFormat.class);
class outFormat extends SequenceFileOutputFormat<Text, LongWritable> { }
foreachRDD 将数据发送到外部系统
- dstream.foreachRDD允许我们把数据发送到外部系统
- 一般我们都是在foreachRDD中创建数据库驱动连接,比如MySQL,Redis,Elasticsearch等等,然后通过驱动后写入外部
- 但是:::::这种方式的误区有太多太多了
- 上面这个是foreachRDD的源码,我们可以看内层还有一个循环
- 那么这个时候我们把我们的创建数据库驱动放到外层中,这样会导致connection被序列化之后传输到task中,rdd是分布式的,所以有些spark工作的线程就会报驱动器未初始化的异常
- 那如果你放到内层中,worker中呢,那你每个批处理Dstream都会创建一个驱动器连接,直接导致sparkStreaming效率低下,我们要知道,驱动器的创建是很消耗资源的
目前比较好的一种解决办法就是静态资源池,官网建议的是采用懒创建的方式
package tools;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;
/**
* Created by 張燿峰
* 静态资源池
*
* @author 孤
* @date 2019/4/16
* @Varsion 1.0
*/
public class ConnectionPool {
private static LinkedList<Connection> connectionQueue;
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized static Connection getConnection() {
try {
if (connectionQueue == null) {
connectionQueue = new LinkedList<>();
}
for (int i = 0; i < 10; i++) {
Connection conn = DriverManager.getConnection("jdbc:mysql://spark1:3307/test", "root", "root");
connectionQueue.push(conn);
}
} catch (Exception e) {
e.printStackTrace();
}
return connectionQueue.poll();
}
/**
* return push connection
*
* @param conn this connection
*/
public static void returnConnection(Connection conn) {
connectionQueue.push(conn);
}
}
result.foreachRDD(rdd -> {
rdd.foreachPartition(partitionOfRecords -> {
Connection connection = ConnectionPool.getConnection();
Tuple2<String, Integer> wordCount;
while (partitionOfRecords.hasNext()) {
wordCount = partitionOfRecords.next();
String sql = "insert into wordcount(word,count) " + "values('" + wordCount._1 + "',"
+ wordCount._2 + ")";
Statement stmt = connection.createStatement();
stmt.executeUpdate(sql);
}
ConnectionPool.returnConnection(connection);
});
});
try {
streamingContext.start();
streamingContext.awaitTermination();
streamingContext.close();
} catch (InterruptedException e) {
e.printStackTrace();
}