我想調試在AWS EMR集羣上運行的Spark應用程序。如果我可以使用IntelliJ進行遠程連接和調試,那將會很棒。我已經搜索,但發現很少。AWS EMR - IntelliJ遠程調試Spark應用程序
是否有可能,如果有的話,有人可以指導我朝着正確的方向嗎?
謝謝。
我想調試在AWS EMR集羣上運行的Spark應用程序。如果我可以使用IntelliJ進行遠程連接和調試,那將會很棒。我已經搜索,但發現很少。AWS EMR - IntelliJ遠程調試Spark應用程序
是否有可能,如果有的話,有人可以指導我朝着正確的方向嗎?
謝謝。
首先,由於AWS EMR的衆多錯誤和意外的使用情況,我會告誡你要做的事情基本上是不可能的。我強烈建議支付您可以運行工作的最大單一實例(它們的c4.8xlarge
在負擔得起,而x1.32xlarge
爲真正的瘋狂!),並簡單地在該實例中安裝spark
並運行您的工作。
nc -l 5005
。 SSH到你的主人並嘗試echo "test" | nc your_ip_address 5005
。在您的機器終端上看到test
之前,請勿繼續。創建一個新的遠程配置。將調試器模式更改爲偵聽。命名配置並保存。當你點擊調試時,它會等待連接。在該窗口中,您將看到「運行遠程JVM的命令行參數」,讀書是這樣的:
-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5005,suspend=y
您可以刪除onthrow
和oncaught
線像我一樣。假設您的調試機器可以通過Internet訪問24.13.242.141
。假設它實際上是:
-agentlib:jdwp=transport=dt_socket,server=n,address=24.13.242.141:5005,suspend=y
我們將用它來設置Spark進程的調試。
有可調試兩個過程:駕駛過程(運行在您的SparkContext
實例化的代碼)和執行過程。最終,您會將這些JVM選項傳遞給的特殊參數以使連接發生。爲了調試驅動程序,使用
spark-submit --driver-java-options -agentlib:jdwp=transport=dt_socket,server=n,address=24.13.242.141:5005,suspend=y --class ...
出於調試執行過程中,你可以使用一個配置選項:
spark-submit --conf "spark.executor.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=n,address=24.13.242.141:5005,suspend=y" --class ...
調試的執行者是多餘的棘手,因爲會有多個進程。你不能像你在IntelliJ中想象的那樣真正地調試多個進程。此外,即使您聲稱可以,您也無法將AWS EMR中的執行程序數量限制爲1。我相信如果其他執行程序會失敗(當它們無法連接到您的調試會話時它們將會失敗)。但這一步未經測試。
可以修改參數既與SDK和Web控制檯。請注意,在SDK中,您不應該嘗試自己連接「參數」 - 將它們作爲數組項一樣將它們傳遞給您。
爲了調試驅動程序(同樣用slave的安全組來調試執行程序),您需要修改主機的安全組。創建一個安全組,允許出站連接到您的調試器的IP地址和端口(即TCP Outbound到24.13.242.141:5005)。您應該使用該條目創建安全組,並使用AWS SDK(.withAdditionalMasterSecurityGroups(...)
)將其添加到主/從屬作業流實例配置的安全組。我不確定如何從Web控制檯執行此操作。
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4"
插件陰影罐子。另外,啓用Zip64
。您會將:shadowJar
任務的結果上載到S3,以便在AWS EMR上實際執行。buildscript {
repositories {
mavenCentral()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.github.jengelman.gradle.plugins:shadow:1.2.4"
}
}
apply plugin: "com.github.johnrengelman.shadow"
shadowJar {
zip64 true
}
--deploy-mode cluster
和--master yarn
啓動星火應用程序(基本上沒有證件)。sc.hadoopConfiguration()
(例如,configuration.set("fs.s3n.impl", "org.apache.hadoop.fs.s3native.NativeS3FileSystem");
)。不要配置這些屬性! hadoop-aws
默認情況下在EMR環境中正常工作,並具有自動設置的相應屬性。log4j
日誌選項設置爲僅報告WARN
及更高版本。在此SDK,你將有做到這一點:.withConfigurations(new Configuration()
.withClassification("spark-log4j")
.addPropertiesEntry("log4j.rootCategory", "WARN, console"))
containers/applications_.../container.../stderr.gz
日誌中的錯誤你懶得調試之前!maximizeResourceAllocation
爲spark
分類。new Configuration()
.withClassification("spark")
.addPropertiesEntry("maximizeResourceAllocation", "true"))
sc.close()
)年底前關閉您的上下文。否則,紗線永遠不會啓動。歡迎無證。ClassLoader.getSystemClassLoader()
。如果class A
通常在a.jar
想要訪問b.jar
中的資源,並且class B
是b.jar
中的類,請使用B.class.getClassLoader().getResource...
。此外,使用相對路徑(在資源引用的開頭省略正斜槓)。我會建議捕獲NullPointerException
並嘗試這兩種方法,這樣無論它如何打包,您的JAR都能正常工作。Function
接口和類似的類,請確保創建一個無參數構造函數來執行您可能依賴的所有初始化。 Spark對閉包和函數實例都使用Kryo序列化(而不是Java序列化),如果您忽略爲特定於應用程序的初始化代碼提供無參數構造函數(例如,從資源加載),則不會執行所有操作您期待的初始化。
哇,非常感謝你這麼詳細的深入的答案 - 我會嘗試什麼似乎是一個徒勞的嘗試很快:D – null
我甚至不想嘗試這個了。反正...非常好的迴應 – Cristian