我目前正在尝试将PySpark和Cassandra集成在一起,并且在优化代码以使其更快执行方面遇到困难。
from pyspark import SparkContext, SparkConf
from pyspark.sql import SQLContext, SparkSession
from pyspark.sql.functions import sum as _sum
def connect_cassandra():
spark = SparkSession.builder \
.appName('SparkCassandraApp') \
.config('spark.cassandra.connection.host', 'localhost') \
.config('spark.cassandra.connection.port', '9042') \
.config('spark.cassandra.output.consistency.level','ONE') \
.master('local[*]') \
.getOrCreate()
sqlContext = SQLContext(spark)
return sqlContext
#--------THIS FUNCTION IS MY CONCERN ACTUALLY------------
def check_ip(ip, df):
rows= df.filter("src_ip = '"+ip+"' or dst_ip = '"+ip+"'") \
.agg(_sum('total').alias('data')) \
.collect()
print(rows[0][0])
#-----------------------------------------------------------
def load_df(sqlContext):
df = sqlContext \
.read \
.format('org.apache.spark.sql.cassandra') \
.options(table='acrs_app_data_usage', keyspace='acrs') \
.load()
return df
if __name__ == '__main__':
lists = ['10.8.25.6', '10.8.24.10', '10.8.24.11', '10.8.20.1', '10.8.25.15', '10.8.25.10']
sqlContext = connect_cassandra()
df = load_df(sqlContext)
for ip in lists:
check_ip(ip, df)
这里的函数check_ip()
带有一个ip和一个预加载的数据帧,该数据帧有3列(src_ip, dst_ip and total
)和大约250K行,作为参数,然后遍历它的总列添加它们并返回按提供的IP分组的汇总数据。
但是,当我执行脚本时,每个IP至少要花一秒钟的时间才能返回总和。我有超过32K个IP必须相同。而且时间很长。
任何帮助将不胜感激。预先感谢。
答案 0 :(得分:1)
简短的回答:不要使用循环。
可能的解决方案:
lists
转换为数据框。 lists_df
进行数据框内部联接两次,第一次在ip == src_ip
上,第二次在ip == dst_ip
unionAll
groupBy("ip").agg(_sum("total"))
这使用联接。因此,也许有一个更好的解决方案。