Apache spark 星火流媒体&;卡夫卡:直接方法——一些困惑
最近,我尝试将spark streaming和kafka与它的直接方法结合起来。在我的应用程序中,我需要定期更新从elasticsearch加载的列表数据集。我写了一个线程来实现这一点,但是当我在spark集群中运行应用程序时,列表没有更新 然而,当我将spark streaming和kafka与基于接收器的方法集成并使用相同的线程时,列表被更新了 有人能给我解释一下吗?顺便问一下,有没有一种有效的方法(定期更新数据集)?谢谢 下面是我的一些代码: 直接法的主要方法是:Apache spark 星火流媒体&;卡夫卡:直接方法——一些困惑,apache-spark,spark-streaming,Apache Spark,Spark Streaming,最近,我尝试将spark streaming和kafka与它的直接方法结合起来。在我的应用程序中,我需要定期更新从elasticsearch加载的列表数据集。我写了一个线程来实现这一点,但是当我在spark集群中运行应用程序时,列表没有更新 然而,当我将spark streaming和kafka与基于接收器的方法集成并使用相同的线程时,列表被更新了 有人能给我解释一下吗?顺便问一下,有没有一种有效的方法(定期更新数据集)?谢谢 下面是我的一些代码: 直接法的主要方法是: if (args.len
if (args.length < 2) {
System.err.println("Usage: DirectKafkaWordCount <brokers> <topics>\n"
+ " <brokers> is a list of one or more Kafka brokers\n"
+ " <topics> is a list of one or more kafka topics to consume from\n\n");
System.exit(1);
}
String brokers = args[0];
String topics = args[1];
// Create context with 2 second batch interval
SparkConf conf = new SparkConf().setAppName("DirectReceiverLogAnalysis");
conf.set("es.index.auto.create", "true");
// Create the streaming context with a 2 second batch size
JavaStreamingContext jssc = new JavaStreamingContext(getContext(conf),new Duration(2000));
// 初始化rule
loadRules(jssc.sparkContext());
// 定期更新rule
RuleThread ruleThread = new RuleThread(jssc.sparkContext());
ruleThread.start();
HashSet<String> topicsSet = new HashSet<String>(Arrays.asList(topics.split(",")));
HashMap<String, String> kafkaParams = new HashMap<String, String>();
kafkaParams.put("metadata.broker.list", brokers);
// Create direct kafka stream with brokers and topics
JavaPairInputDStream<String, String> messages = KafkaUtils
.createDirectStream(jssc, String.class, String.class,
StringDecoder.class, StringDecoder.class, kafkaParams,topicsSet);
// Get the lines
JavaDStream<String> lines = messages.map(new Function<Tuple2<String, String>, String>() {
public String call(Tuple2<String, String> tuple2) {
return tuple2._2();
}
});
// get the windowDstream
JavaDStream<String> windowed_messageDStream = lines.window(
new Duration(6000), new Duration(4000));
// dispose of the streams with rules
windowed_messageDStream
.foreachRDD(new Function<JavaRDD<String>, Void>() {
public Void call(JavaRDD<String> rdd) throws Exception {
// TODO Auto-generated method stub
if (rdd.count() > 0) {
SQLContext sqlContext = JavaSQLContextSingleton
.getInstance(rdd.context());
DataFrame json_rdd = sqlContext.jsonRDD(rdd);
json_rdd.registerTempTable("logs");
json_rdd.printSchema();
System.out
.println("---------------size-------------"
+ sqlList.size());
// 数据匹配
for (int i = 0; i < sqlList.size(); i++) {
try {
DataFrame result = sqlContext.sql(sqlList
.get(i));
if (result.count() > 0) {
JavaEsSparkSQL.saveToEs(result,
"matching/logs");
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
});
// Start the computation
jssc.start();
jssc.awaitTermination();
// 终止线程
ruleThread.setStop(true);
}
// 加载rules
public static void loadRules(JavaSparkContext context) {
// 初始化rule
JavaRDD<Map<String, Object>> esRDD = JavaEsSpark.esRDD(context,
"sql_rules/logs").values();
// collect the rules to list
sqlList = esRDD.map(new Function<Map<String, Object>, String>() {
public String call(Map<String, Object> map) throws Exception {
return (String) map.get("sql");
}
}).collect();
}
The thread class:
public class RuleThread extends Thread {
public boolean threadStop = false;
public JavaSparkContext context;
public RuleThread(JavaSparkContext context) {
this.context = context;
}
public void setStop(boolean stop) {
this.threadStop = stop;
}
@Override
public void run() {
try {
while (!threadStop) {
Thread.sleep(1000 * 60 * 1);
LogAnalysis.loadRules(context);
}
} catch (Exception e) {
e.printStackTrace();
}
}
if(args.length<2){
System.err.println(“用法:DirectKafkaWordCount\n”
+“是一个或多个Kafka代理的列表\n”
+“是要从中使用的一个或多个卡夫卡主题的列表\n\n”);
系统出口(1);
}
字符串代理=args[0];
字符串主题=args[1];
//以2秒的批处理间隔创建上下文
SparkConf conf=new SparkConf().setAppName(“DirectReceiverLogAnalysis”);
conf.set(“es.index.auto.create”、“true”);
//以2秒的批量大小创建流式处理上下文
JavaStreamingContext jssc=newJavaStreamingContext(getContext(conf),newDuration(2000));
// 初始化规则
loadRules(jssc.sparkContext());
// 定期更新规则
RuleThread RuleThread=新的RuleThread(jssc.sparkContext());
ruleThread.start();
HashSet-topicsSet=新的HashSet(Arrays.asList(topics.split(“,”));
HashMap kafkaParams=新HashMap();
kafkaParams.put(“metadata.broker.list”,brokers);
//创建带有代理和主题的直接卡夫卡流
JavaPairInputStream消息=KafkaUtils
.createDirectStream(jssc、String.class、String.class、,
StringDecoder.class、StringDecoder.class、kafkaParams、TopicSet);
//接电话
JavadStreamLines=messages.map(新函数(){
公共字符串调用(Tuple2 Tuple2){
返回tuple2._2();
}
});
//获取窗口流
JavaDStream windowed_messageDStream=lines.window(
新期限(6000),新期限(4000);
//使用规则处理流
窗口消息流
.foreachRDD(新函数(){
公共Void调用(JavaRDD)引发异常{
//TODO自动生成的方法存根
如果(rdd.count()>0){
SQLContext SQLContext=JavaSQLContextSingleton
.getInstance(rdd.context());
DataFrame json_rdd=sqlContext.jsonRDD(rdd);
json_rdd.RegisterEmptable(“日志”);
json_rdd.printSchema();
系统输出
.println(“--------------尺寸------------------”
+sqlList.size());
// 数据匹配
对于(int i=0;i0){
saveToEs(结果,
“匹配/日志”);
}
}捕获(例外e){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}
返回null;
}
});
//开始计算
jssc.start();
jssc.aittimination();
// 终止线程
ruleThread.setStop(真);
}
// 加载规则
公共静态void加载规则(JavaSparkContext上下文){
// 初始化规则
JavaRDD esRDD=JavaEsSpark.esRDD(上下文,
“sql_规则/日志”).values();
//收集要列出的规则
sqlList=esRDD.map(新函数(){
公共字符串调用(映射)引发异常{
return(String)map.get(“sql”);
}
}).收集();
}
线程类:
公共类RuleThread扩展线程{
公共布尔threadStop=false;
公共JavaSparkContext上下文;
公共规则线程(JavaSparkContext上下文){
this.context=上下文;
}
公共无效设置停止(布尔停止){
this.threadStop=停止;
}
@凌驾
公开募捐{
试一试{
而(!threadStop){
线程睡眠(1000*60*1);
LogAnalysis.loadRules(上下文);
}
}捕获(例外e){
e、 printStackTrace();
}
}
}采用基于接收器的方法,使用zookeeper地址(主机:2181)。而在直接方法中,我们使用卡夫卡代理地址(主机:9092)。你确定你没有混淆它们吗?你能用一些代码更新你的问题吗?@Clyde D'Cruz:谢谢你的回答!我想你不明白我的问题。我想问的是使用线程更新spark streaming应用程序中的数据,该线程在基于接收器的方法中工作,但在直接方法中不工作。您是否也可以包括启动应用程序所使用的命令?对于直接,那么基于接收者的方法呢?@ClydeD'Cruz:对于基于接收者的方法:spark submit--class driver class--master spark:192.168.122.61:7077应用程序jar zookeeper url组名主题名threads num checkPoint Dir对于基于接收者的方法,使用zookeeper地址(主机:2181)。而在直接方法中,我们使用卡夫卡代理地址(主机:9092)。你确定你没有混淆它们吗?你能更新你的问题吗