Apache spark 星火流媒体&;卡夫卡:直接方法——一些困惑

Apache spark 星火流媒体&;卡夫卡:直接方法——一些困惑,apache-spark,spark-streaming,Apache Spark,Spark Streaming,最近,我尝试将spark streaming和kafka与它的直接方法结合起来。在我的应用程序中,我需要定期更新从elasticsearch加载的列表数据集。我写了一个线程来实现这一点,但是当我在spark集群中运行应用程序时,列表没有更新 然而,当我将spark streaming和kafka与基于接收器的方法集成并使用相同的线程时,列表被更新了 有人能给我解释一下吗?顺便问一下,有没有一种有效的方法(定期更新数据集)?谢谢 下面是我的一些代码: 直接法的主要方法是: if (args.len

最近,我尝试将spark streaming和kafka与它的直接方法结合起来。在我的应用程序中,我需要定期更新从elasticsearch加载的列表数据集。我写了一个线程来实现这一点,但是当我在spark集群中运行应用程序时,列表没有更新

然而,当我将spark streaming和kafka与基于接收器的方法集成并使用相同的线程时,列表被更新了

有人能给我解释一下吗?顺便问一下,有没有一种有效的方法(定期更新数据集)?谢谢

下面是我的一些代码: 直接法的主要方法是:

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)。你确定你没有混淆它们吗?你能更新你的问题吗