我正在做一个小项目,我在Twitter提要上进行情感分析。我对Kafka和Spark流媒体还很陌生,但是鉴于在线信息,我很难找到问题的原因。我的spark程序侦听名称为“ twitter”的kafka(v。0.10)主题,其中包含打包为json的tweets。我使用以下代码:
from pyspark.sql import SparkSession, udf
from pyspark.sql.functions import *
from pyspark.sql.types import *
from afinn import Afinn
def afinn_score(row):
afinn = Afinn(language='en', emoticons=True)
return afinn.score(row)
def main():
spark = SparkSession.builder.appName("TwitterSentiment").getOrCreate()
spark.sparkContext.setLogLevel("WARN")
afinn_score_udf = udf(afinn_score, DoubleType())
schema = StructType([
StructField("text", StringType(), True)
])
kafka_df = spark \
.readStream.format("kafka") \
.option("kafka.bootstrap.servers", "localhost:9092") \
.option("subscribe", "twitter") \
.load() \
.select(from_json(col("value").cast("string"), schema).alias("tweets"), "timestamp") \
.select("tweets.*", "timestamp")
sentiment_df = kafka_df \
.withWatermark("timestamp", "15 seconds") \
.withColumn("sentiment", afinn_score_udf(kafka_df.text))
print_df = sentiment_df \
.withWatermark("timestamp", "15 seconds") \
.groupBy(sentiment_df.timestamp, window(sentiment_df.timestamp, "10 seconds")) \
.agg(count(sentiment_df.sentiment).alias("tweet_count"), avg(sentiment_df.sentiment).alias("avg_sentiment"))
query = print_df.writeStream \
.outputMode('append') \
.format("console") \
.start()
if __name__ == "__main__":
main()
我的问题是我从kafka经纪人那里收到的时间戳总是相同的。所有批次的时间戳为:“ 1970-01-01 00:59:59.999”,但是偏移量会正确增加。这意味着我的groupBy仅返回一个字段。 请注意,我将kafka 0.10与spark sql maven软件包一起使用:2.11-2.3.2,谢谢。
更新1: 我最终使用了Twitter feed数据中包含的“ timestamp_ms”字段。使用此时间戳,我可以使结构化流工作。但是我也在另一台机器上尝试过该代码,并且嵌入在Kafka中的时间戳信息仍然保持不变。