簡體   English   中英

將 Spark DataFrame 寫入 Redis 時如何提高速度?

[英]How to increase speed when writing Spark DataFrame to Redis?

我正在開發基於 Flask 的書籍推薦 API,發現要管理多個請求,我需要預先計算相似度矩陣並將其存儲在某處以供將來查詢。 這個矩陣是使用 PySpark 基於約 150 萬個具有書籍 ID、名稱和元數據的數據庫條目創建的,結果可以用這個模式來描述( ij用於書籍索引, dot表示它們的元數據的相似性):

StructType(List(StructField(i,IntegerType,true),StructField(j,IntegerType,true),StructField(dot,DoubleType,true)))

最初,我打算使用 spark-redis 連接器將其存儲在 Redis 上。 但是,以下命令似乎以非常慢的速度運行(即使初始書籍數據庫查詢大小限制為非常適中的 40k 批處理):

similarities.write.format("org.apache.spark.sql.redis").option("table", "similarities").option("key.column", "i").save()

Spark 將初始任務分為 9 個階段中的 3 個,大約需要 6 個小時。 奇怪的是,Spark 執行器對存儲 memory 的使用率非常低,大約 20kb。 Spark 應用程序 UI 描述了一個典型的階段活動階段:

org.apache.spark.sql.DataFrameWriter.save(DataFrameWriter.scala:271)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
py4j.Gateway.invoke(Gateway.java:282)
py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
py4j.commands.CallCommand.execute(CallCommand.java:79)
py4j.GatewayConnection.run(GatewayConnection.java:238)
java.lang.Thread.run(Thread.java:748)

是否有可能以某種方式加快這個過程? 我的 Spark session 是這樣設置的:

SUBMIT_ARGS = "  --driver-memory 2G --executor-memory 2G --executor-cores 4 --packages mysql:mysql-connector-java:5.1.39 pyspark-shell"
os.environ["PYSPARK_SUBMIT_ARGS"] = SUBMIT_ARGS
conf = SparkConf().set("spark.jars", "spark-redis/target/spark-redis_2.11-2.4.3-SNAPSHOT-jar-with-dependencies.jar").set("spark.executor.memory", "4g")
sc = SparkContext('local','example', conf=conf) 
sql_sc = SQLContext(sc)

您可以嘗試使用Append保存模式來避免檢查表中是否已經存在數據:

similarities.write.format("org.apache.spark.sql.redis").option("table", "similarities").mode('append').option("key.column", "i").save()

此外,您可能想要更改

sc = SparkContext('local','example', conf=conf) 

sc = SparkContext('local[*]','example', conf=conf) 

利用您機器上的所有內核。

順便說一句,在 Redis 中使用i作為鍵是否正確? 它不應該是ij的組合嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM