[英]Spark JDBC connection to SQL Server times out often
我正在通過sparklyr v0.6.2運行Spark v2.2.1,並通過jdbc從SQL Server中提取數據。 我似乎遇到了一些網絡問題,因為我的執行程序多次 (並非每次)對SQL Server進行寫操作都會失敗,並顯示以下錯誤:
Prelogin error: host <my server> port 1433 Error reading prelogin response: Connection timed out (Read failed) ClientConnectionId:...
我正在使用以下配置運行我的Sparklyr會話:
spark_conf = spark_config()
spark_conf$spark.executor.cores <- 8
spark_conf$`sparklyr.shell.driver-memory` <- "8G"
spark_conf$`sparklyr.shell.executor-memory` <- "12G"
spark_conf$spark.serializer <- "org.apache.spark.serializer.KryoSerializer"
spark_conf$spark.network.timeout <- 400
但是有趣的是,根據執行程序日志,我上面設置的網絡超時似乎並不適用:
18/06/11 17:53:44 INFO BlockManager: Found block rdd_9_16 locally
18/06/11 17:53:45 WARN SQLServerConnection: ConnectionID:3 ClientConnectionId: d3568a9f-049f-4772-83d4-ed65b907fc8b Prelogin error: host nciensql14.nciwin.local port 1433 Error reading prelogin response: Connection timed out (Read failed) ClientConnectionId:d3568a9f-049f-4772-83d4-ed65b907fc8b
18/06/11 17:53:45 WARN SQLServerConnection: ConnectionID:2 ClientConnectionId: ecb084e6-99a8-49d1-9215-491324e8d133 Prelogin error: host nciensql14.nciwin.local port 1433 Error reading prelogin response: Connection timed out (Read failed) ClientConnectionId:ecb084e6-99a8-49d1-9215-491324e8d133
18/06/11 17:53:45 ERROR Executor: Exception in task 10.0 in stage 26.0 (TID 77)
有人可以幫助我了解什么是登錄前錯誤以及如何避免此問題嗎? 這是我的寫功能:
function (df, tbl, db, server = NULL, user, pass, mode = "error",
options = list(), ...)
{
sparklyr::spark_write_jdbc(
df,
tbl,
options = c(
list(url = paste0("jdbc:sqlserver://", server, ".nciwin.local;",
"databaseName=", db, ";",
"user=", user, ";",
"password=", pass, ";"),
driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"),
options),
mode = mode, ...)
}
我剛剛將我的jdbc驅動程序更新為6.0版,但我認為這沒有什么不同。 我希望我正確安裝了它。 我只是將其放到Spark/jars
文件夾中,然后將其添加到Spark/conf/spark-defaults.conf
。
編輯我正在將24個分區中的23M行讀入Spark。 我的集群有4個節點,每個節點有8個核心和18G內存。 根據我當前的配置,我有4個執行器,每個執行器具有8個內核,每個執行器12G。 我讀取數據的功能如下所示:
function (sc, tbl, db, server = NULL, user, pass, repartition = 0, options = list(), ...)
{
sparklyr::spark_read_jdbc(
sc,
tbl,
options = c(
list(url = paste0("jdbc:sqlserver://", server, ".nciwin.local;"),
user = user,
password = pass,
databaseName = db,
dbtable = tbl,
driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver"),
options),
repartition = repartition, ...)
}
運行時,我將repartition
設置為24。 因此,我看不到與該帖子有關的建議。
編輯2
通過擺脫重新分區,我得以解決自己的問題。 誰能解釋為什么在這種情況下用sparklyr重新分區無效?
正如在另一個問題以及其他一些文章中所解釋的 ( partitionColumn,lowerBound,upperBound,numPartitions參數的含義是什么?) 相比,將csv文件中的mysql表轉換為spark數據集非常慢 , 從RDBMS讀取時在spark中進行分區通過JDBC , spark並行地從mysql讀取數據 )和非現場資源( Parallelizing Reads ),默認情況下,Spark JDBC源將所有數據順序讀取到單個節點中。
有兩種並行讀取的方法:
根據需要使用lowerBound
, upperBound
, partitionColumn
和numPartitions
options
的數字列進行范圍partitionColumn
,其中partitionColumn
是穩定的數字列( 偽列可能不是一個好的選擇 )
spark_read_jdbc( ..., options = list( ... lowerBound = "0", # Adjust to fit your data upperBound = "5000", # Adjust to fit your data numPartitions = "42", # Adjust to fit your data and resources partitionColumn = "some_numeric_column" ) )
predicates
列表-目前尚不支持sparklyr
。
重新分區( sparklyr::sdf_repartition
因為數據已經被加載后,它發生。因為洗牌(需要不能解決問題, repartition
)屬於最昂貴的操作在星火它可以很容易崩潰的節點。
結果使用:
spark_read_jdbc
repartition
參數:
sdf_repartition
只是一種崇拜貨物的做法,大多數時候弊大於利。 如果數據足夠小,無法通過單個節點進行管道傳輸,則增加分區數通常會降低性能。 否則它將崩潰。
話雖這么說-如果數據已經由單個節點處理過,則會引發一個問題,即是否完全可以使用Apache Spark。 答案將取決於您管道的其余部分,但僅考慮有問題的組件,可能會否定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.