使用Spark的MapReduce调用其他函数并进行聚合

时间:2019-01-14 02:18:46

标签: java apache-spark mapreduce sentiment-analysis aws-glue

我非常不熟悉spark,但是我敢肯定,有一种比我目前做的更快的好方法。

本质上,我有一个S3存储桶,其中包含大量twitter数据的JSON。我想浏览所有这些文件,从JSON中获取文本,对文本进行情感分析(当前使用Stanford NLP),然后将Tweet + Sentiment上传到数据库(现在我正在使用dynamo,但这不是成败)

我当前拥有的代码是

        /**
         * Per thread:
         * 1. Download a file
         * 2. Do sentiment on the file -> output Map<String, List<Float>>
         * 3. Upload to Dynamo: (a) sentiment (b) number of tweets (c) timestamp
         *
         */

        List<String> keys = s3Connection.getKeys();

        ThreadPoolExecutor threads = new ThreadPoolExecutor(40, 40, 10000, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));
        threads.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());

        for (String key : keys) {
                threads.submit(new Thread(() -> {
                    try {
                        S3Object s3Object = s3Connection.getObject(key);
                        Map<String, List<Float>> listOfTweetsWithSentiment = tweetSentimentService.getTweetsFromJsonFile(s3Object.getObjectContent());
                        List<AggregatedTweets> aggregatedTweets = tweetSentimentService.createAggregatedTweetsFromMap(listOfTweetsWithSentiment, key);

                        for (AggregatedTweets aggregatedTweet : aggregatedTweets) {
                            System.out.println(aggregatedTweet);
                            tweetDao.putItem(aggregatedTweet);
                        }
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                }));
        }

这有效并且很好。通过在特定日期范围内运行此代码(即getKeys仅获取特定日期范围的键),并在不同的EC2上分解了该过程的许多实例,我能够将过程加速到大约2个小时。日期范围。

但是,必须有一个更快的方法来完成一个好的ole map-reduce,但是我只是不知道如何开始研究它。是否可以在我的地图中进行情感分析,然后根据时间戳进行缩减?

此外,我一直在研究使用AWS Glue,但我看不到在那里使用Stanford NLP库的好方法。

任何人和所有帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

是的,您可以使用Apache Spark来完成。设计应用程序,配置基础结构等方法有很多。我提出了一个简单的设计:

  1. 您正在使用AWS,因此请使用Spark创建EMR集群。包含Zeppelin进行交互式调试将很有用。

  2. Spark使用多个数据抽象。您的朋友是RDD和数据集(请阅读有关它们的文档)。将数据读取到数据集的代码可能相同:

    SparkSession ss = SparkSession.builder().getOrCreate();
    Dataset<Row> dataset = ss.read("s3a://your_bucket/your_path");
    
  3. 现在您有一个Dataset<Row>。这对于类似SQL的操作很有用。为了进行分析,您需要将其转换为Spark RDD:

    JavaRDD<Tweet> analyticRdd = dataset.toJavaRDD().map(row -> {
      return TweetsFactory.tweetFromRow(row);
    });
    
  4. 因此,您可以使用analyticRdd来进行分析。只是不要忘记让所有与数据一起使用的服务都可序列化。