[英]Problem with transformation JavaRDD<Status> to JavaRDD<String>
我正在嘗試將Twitter上的推文保存到MongoDb數據庫。
我有RDD<Status>
,我正在嘗試使用幫助ObjectMapper將其轉換為JSON格式。但是這種轉換存在一些問題(
public class Main {
//set system credentials for access to twitter
private static void setTwitterOAuth() {
System.setProperty("twitter4j.oauth.consumerKey", TwitterCredentials.consumerKey);
System.setProperty("twitter4j.oauth.consumerSecret", TwitterCredentials.consumerSecret);
System.setProperty("twitter4j.oauth.accessToken", TwitterCredentials.accessToken);
System.setProperty("twitter4j.oauth.accessTokenSecret", TwitterCredentials.accessTokenSecret);
}
public static void main(String [] args) {
setTwitterOAuth();
SparkConf conf = new SparkConf().setMaster("local[2]")
.setAppName("SparkTwitter");
JavaSparkContext sparkContext = new JavaSparkContext(conf);
JavaStreamingContext jssc = new JavaStreamingContext(sparkContext, new Duration(1000));
JavaReceiverInputDStream<Status> twitterStream = TwitterUtils.createStream(jssc);
//Stream that contains just tweets in english
JavaDStream<Status> enTweetsDStream=twitterStream.filter((status) -> "en".equalsIgnoreCase(status.getLang()));
enTweetsDStream.persist(StorageLevel.MEMORY_AND_DISK());
enTweetsDStream.print();
jssc.start();
jssc.awaitTermination();
}
static void saveRawTweetsToMondoDb(JavaRDD<Status> rdd,JavaSparkContext sparkContext) {
try {
ObjectMapper objectMapper = new ObjectMapper();
SQLContext sqlContext = new SQLContext(sparkContext);
JavaRDD<String> tweet = rdd.map(status -> objectMapper.writeValueAsString(status));
DataFrame dataFrame = sqlContext.read().json(tweet);
Map<String, String> writeOverrides = new HashMap<>();
writeOverrides.put("uri", "mongodb://127.0.0.1/forensicdb.LiveRawTweets");
WriteConfig writeConfig = WriteConfig.create(sparkContext).withJavaOptions(writeOverrides);
MongoSpark.write(dataFrame).option("collection", "LiveRawTweets").mode("append").save();
} catch (Exception e) {
System.out.println("Error saving to database");
}
}
JavaRDD<String> tweet = rdd.map(status -> objectMapper.writeValueAsString(status));
這是一個問題。不JavaRDD<String>
類型需要JavaRDD<String>
但是映射被推斷為javaRDD<R>
不幸的是,Java類型推斷並不總是很聰明,因此在這種情況下,我要做的是將lambda的所有位提取為變量,直到找到Java無法為其提供准確類型的變量為止。 然后,我給該表達式指定我認為應該具有的類型,並查看Java為什么抱怨它。 有時,這只是編譯器中的一個限制,您必須將表達式顯式“轉換”為所需的類型,其他時候,您會發現代碼存在問題。 就您而言,代碼對我來說很好,所以還必須有其他東西。
但是,我有一條評論:在這里,您只需一次支付JSON序列化的費用(從Status
到JSON字符串),然后進行反序列化(從JSON字符串到Row
)。 另外,您沒有為您的Dataset
提供任何架構,因此它必須進行兩次數據傳遞(或取決於配置的數據樣本)才能推斷出架構。 如果數據很大,所有這些都可能會非常昂貴。 我勸你寫從一個轉換Status
,以Row
,如果性能是一個問題,如果直接Status
比較簡單。
另一個“順便說一句”:您隱式序列化了ObjectMapper
,很可能您不想這樣做。 該類似乎確實支持Java序列化,但是具有特殊的邏輯 。 由於Spark的默認配置是使用Kryo(其性能比Java序列化要好得多),因此我懷疑在使用默認的FieldSerializer
時,它會做正確的事情。 您有三種選擇:
ObjectMapper
類型的對象進行序列化/反序列化。 那會起作用,但不值得付出努力。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.