spark源碼閱讀-腳本篇(bin)


 

spark都進化到2.0了,雖然之前對spark有所了解但總感覺似懂非懂的,所以想花時間看看源碼。

面對大量的源碼從哪里着手呢,想到老子的一句話“天下難事必作於易,天下大事必作於細”,所以就從腳本部分來啃。

因本人腳本編程能力也並不是那么強,所以在總結的時候會穿插一些shell的東西。此處只介紹shell腳本,不涉及bat腳本。

 

先按照首字母順序介紹下每個腳本的功能:

spark-1.5.0/bin

beeline:基於SQLLine CLI的JDBC客戶端,可以連接到hive,操作hive中的數據。

load-spark-env.sh:導入conf目錄下的spark-env.sh文件。

pyspark:python調用spark.

run-example:運行examples目錄下的示例。

spark-class:調用org.apache.spark.launcher.Main, 多被其他腳本調用。

spark-shell:spark shell交互腳本。

spark-sql:spark sql運行腳本。

spark-submit:spark作業提交腳本。

sparkR:R語言調用spark。

再介紹下腳本之間的調用關系:

[注]箭頭所指方向為被依賴或被引用的腳本

 

部分腳本解析:

spark-calss部分代碼:

# The launcher library will print arguments separated by a NULL character, to allow arguments with
# characters that would be otherwise interpreted by the shell. Read that in a while loop, populating
# an array that will be used to exec the final command.
CMD=()
while IFS= read -d '' -r ARG; do
   CMD+=("$ARG")
 done < <("$RUNNER" -cp "$LAUNCH_CLASSPATH" org.apache.spark.launcher.Main "$@")

exec "${CMD[@]}"

注解:對比之前版本的腳本,現在的腳本簡化了很多東西,好多判斷都移動到了java或scala代碼內。下一步就是分析org.apache.spark.launcher.Main 這個類。

 

spark-shell 代碼:

#!/usr/bin/env bash

# Shell script for starting the Spark Shell REPL

#驗證是否是cygwin
cygwin=false
case "`uname`" in
  CYGWIN*) cygwin=true;;
esac

# 開啟posix模式
set -o posix

#獲取父級目錄的絕對路徑,$0為當前腳本名
export FWDIR="$(cd "`dirname "$0"`"/..; pwd)"
export _SPARK_CMD_USAGE="Usage: ./bin/spark-shell [options]"

#手動添加 -Dscala.usejavacp=true,scala 默認不會使用 java classpath
SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Dscala.usejavacp=true"

#腳本入口,實際調用的是spark-submit腳本
function main() {
  if $cygwin; then
    
    stty -icanon min 1 -echo > /dev/null 2>&1
    export SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Djline.terminal=unix"
    "$FWDIR"/bin/spark-submit --class org.apache.spark.repl.Main --name "Spark shell" "$@"
    stty icanon echo > /dev/null 2>&1
  else
    export SPARK_SUBMIT_OPTS
    "$FWDIR"/bin/spark-submit --class org.apache.spark.repl.Main --name "Spark shell" "$@"
  fi
}

# Copy restore-TTY-on-exit functions from Scala script so spark-shell exits properly even in
# binary distribution of Spark where Scala is not installed
exit_status=127
saved_stty=""

# restore stty settings (echo in particular)
function restoreSttySettings() {
  stty $saved_stty
  saved_stty=""
}

function onExit() {
  if [[ "$saved_stty" != "" ]]; then
    restoreSttySettings
  fi
  exit $exit_status
}

# 中斷時進行的操作
trap onExit INT

# 保存終止設置
saved_stty=$(stty -g 2>/dev/null)
# clear on error so we don't later try to restore them
if [[ ! $? ]]; then
  saved_stty=""
fi

#調用main函數
main "$@"

# 記錄腳本退出狀態
# then reenable echo and propagate the code.
exit_status=$?
onExit

注解:顯然spark-shell調用的是spark-submit ,利用--class org.apache.spark.repl.Main --name "Spark shell"傳入參數。

此處本人主要對shell交互的實現比較感興趣,后續會調研下,之后研究的類自然是class org.apache.spark.repl.Main。

 spark-sql代碼

export FWDIR="$(cd "`dirname "$0"`"/..; pwd)"
export _SPARK_CMD_USAGE="Usage: ./bin/spark-sql [options] [cli option]"
exec "$FWDIR"/bin/spark-submit --class org.apache.spark.sql.hive.thriftserver.SparkSQLCLIDriver "$@"

注解:這部分腳本簡單明了,要調研的類也很清楚:org.apache.spark.sql.hive.thriftserver.SparkSQLCLIDriver 。

spark sql雖然操作的是hive,但是比HQL快多了,基於內存的計算果斷有優勢啊。

  

spark-submit代碼

SPARK_HOME="$(cd "`dirname "$0"`"/..; pwd)"

# disable randomized hash for string in Python 3.3+
export PYTHONHASHSEED=0

exec "$SPARK_HOME"/bin/spark-class org.apache.spark.deploy.SparkSubmit "$@"

注解:不兼容python3.3+以上的版本,具體原因不明,表示沒怎么接觸過python。

調用spark-class實現的job提交,以何種模式提交的判斷猜測應該在org.apache.spark.deploy.SparkSubmit中。

 

sparkR代碼:

export SPARK_HOME="$(cd "`dirname "$0"`"/..; pwd)"
source "$SPARK_HOME"/bin/load-spark-env.sh
export _SPARK_CMD_USAGE="Usage: ./bin/sparkR [options]"
exec "$SPARK_HOME"/bin/spark-submit sparkr-shell-main "$@"

注解:實現的方式與python類似。

 

shell不明點參照:

1.set -o posix

set命令是shell解釋器的一個內置命令,用來設置shell解釋器的屬性,從而能夠控制shell解釋器的一些行為。

在set命令中,選項前面跟着 - 號表示開啟這個選項, + 表示關閉這個選項。

POSIX,Portable Operating System Interface。
是UNIX系統的一個設計標准,很多類UNIX系統也在支持兼容這個標准,如Linux。
遵循這個標准的好處是軟件可以跨平台。
所以windows也支持就很容易理解了,那么多優秀的開源軟件,支持了這個這些軟件就可能有windows版本,就可以完善豐富windows下的軟件。

set -o posix:開啟bash的posix模式。

2.command -v java

 command [-pVv] command [arg ...]

用command指定可取消正常的shell function尋找。只有內建命令及在PATH中找得到的才會被執行。

"-p"選項,搜尋命令的方式是用PATH來找。"-V"或"-v"選項,會顯示出該命令的一些簡約描述。

3.[ [[ test

[ is a shell builtin
[[ is a shell keyword
test is a shell builtin

[ = test

[[ 可用 && |  ,常用可避免錯誤。

4.read -d 

 -d :表示delimiter,即定界符,一般情況下是以IFS為參數的間隔,但是通過-d,我們可以定義一直讀到出現執行的字符位置。例如read –d madfds value,讀到有m的字符的時候就不在繼續向后讀,例如輸入為 hello m,有效值為“hello”,請注意m前面的空格等會被刪除。這種方式可以輸入多個字符串,例如定義“.”作為結符號等等

 read命令 -n(不換行) -p(提示語句) -n(字符個數) -t(等待時間) -s(不回顯)

5.setty

 stty(set tty)命令用於顯示和修改當前注冊的終端的屬性。

tty -icanon 設置一次性讀完操作,如使用getchar()讀操作,不需要按enter
 
stty icanon 取消上面設置
 

[-]icanon
enable erase, kill, werase, and rprnt special characters

6.$@

 輸入參數,常與shift連用。參數較多或參數個數不確定時可用。

總結:

 shell腳本遵循簡單明了的原則,而對比以前的腳本也會發現這點,一些復雜的判斷邏輯大多都移入源碼里了,例如submit腳本中運行模式的判斷,這樣會使腳本精簡很多。

 bin下的腳本都以2個空格為縮進,同一腳本中邏輯不同的代碼塊之間空行分隔,另有必要的注釋,風格統一。

 環境變量或全局變量的引入是放在load-spark-env.sh中的,其他腳本再以 . 的方式引入,腳本復用。

parent_dir="$(cd "`dirname "$0"`"/..; pwd)"  是一段很有用的代碼。

命令性質的腳本統一放在了bin下,而功能性質的大多都放在了sbin下。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM