我有一份工作,每隔10秒从Kafka接收数据,然后我格式化数据并插入到cassandra中,但是我的工作越来越慢,这让我很困惑。
根据我的统计数据,每10秒消息少于100条,第一次处理时间最多只需1秒,但几天后处理速度变慢,需要14秒才能处理10秒&# 39;数据现在。
如果有一些因素会让工作变慢,我感到很困惑。
我注意到处理python -m pyspark.daemon
也会花费越来越多的内存,是否有一些方法可以降低内存成本。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
24527 yao.yu 20 0 10.334g 9.823g 3580 R 96.8 66.9 3424:56 python
代码如下:
if __name__ == "__main__":
conf = SparkConf().setAppName("Kafka_To_Cassandra").set("spark.streaming.kafka.maxRatePerPartition", "1000")
sc = SparkContext(conf = conf)
ssc = StreamingContext(sc, 10)
brokers, topic = sys.argv[1:]
kvs = KafkaUtils.createDirectStream(ssc, [topic], {"metadata.broker.list": brokers, "auto.offset.reset": "smallest"})
lines = kvs.map(lambda x: x[1]) \
.filter(lambda s: 'identifier' in s) \
.filter(lambda s: 'app_name' in s) \
.filter(lambda s: 'app_version' in s)
map_lines = lines.map(mapper).filter(lambda s: 'JsonLoadException' not in s)
#map_lines.pprint()
map_lines.foreachRDD(lambda rdd: rdd.foreachPartition(save_to_cassandra))
ssc.start()
ssc.awaitTermination()
答案 0 :(得分:0)
此配置可能会对您有所帮助。
spark.cleaner.ttl
Spark将记住任何元数据(生成的阶段,生成的任务等)的持续时间(秒)。定期清理将确保忘记超过此持续时间的元数据。这对于运行Spark很多小时/天非常有用(例如,在Spark Streaming应用程序中运行24/7)。请注意,任何在内存中持续时间超过此持续时间的RDD也将被清除。
答案 1 :(得分:0)
最后,我使用Scala再次使用Spark-Cassandra-Connector编写代码。
我确信Cassandra的连接花费了大量内存,因此官方的Spark Streaming Design Patterns for using foreachRDD建议你创建一个连接池,这样你就不必每次都为每个RDD构建一个连接或foreachPartition。但我不知道如何使python-cassandra-driver支持它。
我使用Scala重构我的代码,Spark-Cassandra-Connector非常好地支持Spark Streaming。然后我的工作稳定工作了几个星期甚至几个月,没有内存泄漏。