shell 指令碼實戰筆記(10)--spark叢集指令碼片段念念碎

來源:互聯網
上載者:User

標籤:des   blog   http   使用   os   檔案   

前言:

  通過對spark叢集指令碼的研讀, 對一些重要的shell指令碼技巧, 做下筆記.

*). 取當前指令碼的目錄

sbin=`dirname "$0"` sbin=`cd "$sbin"; pwd`

代碼評註:
# 以上代碼為擷取執行指令碼所在的目錄的常用技巧
# sbin=$(dirname $0) 返回可能是相對路徑, 比如./
# sbin=$(cd $sbin; pwd) 採用pwd, 來返回指令碼所在目錄的絕對路徑

*). 迴圈遍曆指令碼參數

while (( "$#" )); do  case $1 in    --with-tachyon)      TACHYON_STR="--with-tachyon"    ;;  esac  shiftdone

代碼評註:
# 這是段遍曆指令碼參數的常見程式碼片段
# shell指令碼中$#表示參數個數
# 由於$0是指令碼名稱本身佔據, 因此指令碼對參數的遍曆從$1開始, 藉助shift變數左移, 方便了對變長參數列表的遍曆
# 基於事件的xml解析方式, 當採用pull方式去遍曆的時候, 差不多也是類似的代碼結構
# 當然需要注意, shift處理參數變數之後, 對後續指令碼代碼處理變數是有影響的(負作用), 因此最佳實務是集中處理指令碼參數

*). 引入配置指令碼

. "$sbin/spark-config.sh"

代碼評註:
# shell指令碼中‘.‘ 等同於source, 把呼叫指令碼作為調用方指令碼的自身的一部分執行, source <shell_file>通常用於匯入應用的配置參數
# source/exec/fork 外部指令碼的區別, 詳見這篇

*). 預設參數處理

if [ "$SPARK_MASTER_PORT" = "" ]; then  SPARK_MASTER_PORT=7077fi

代碼評註:
# 對變數預設值的處理方式
# 注意對變數添加"", if [ $SPARK_MASTER_PORT = "" ] 會報錯誤: "[: =: unary operator expected"
# 類似的代碼可採用-z $SPARK_MASTER_PORT的方式

if [ -z $SPARK_MASTER_PORT ]; then  SPARK_MASTER_PORT=7077fi

*). $!的使用和pid檔案的使用

nohup nice -n $SPARK_NICENESS "$SPARK_PREFIX"/bin/spark-class $command "[email protected]" >> "$log" 2>&1 < /dev/null &newpid=$!echo $newpid > $pid

代碼評註:
# nohup 表示進程脫離session運行
# nice -n 用於調整進程nice值
# 2>&1 表示把標準錯誤(stderr, 2)關聯到標準輸出(stdout, 1), 可以簡寫為 &>
# $!表示上一個shell命令(後台運行)的pid
# echo $newpid > $pid (代表檔案), 是把進程pid寫入到進程的pid檔案中去
# 很多服務(比如apache)會選擇把自身的pid(進程id)寫入到pid檔案中去, 至於為何這麼做? 各有各的應用情境, 下面的kill -0就應用到了

*). kill -0 的使用, 檢測進程是否存在, 重入(誤判)問題

if [ -f $pid ]; then  if kill -0 `cat $pid` > /dev/null 2>&1; then    echo $command running as process `cat $pid`. Stop it first.    exit 1  fifi

代碼評註:
# kill -0 <pid> 只是簡單的向進程發送一個signal(不影響進程運行), 用來檢測進程是否存在, 存在(echo $? => 0), 不存在(echo $? => 1)
# if [ -f $pid ] 判斷pid檔案是否存在, cat $pid, 則是擷取pid值, 這與上面pid檔案相吻合
# kill -0 `cat $pid` > /dev/null 2>&1 後面的‘> /dev/null 2>&1‘用於去掉不必要資訊到控制台
疑問:
# 重入問題: 有點類似tcp的問題, socket佔據的四元組(src: ip+port, dest: ip+port), 遺留的tcp包, 對後續重新複用port的socket造成的幹擾
# 假設: pid寫入到pid檔案後, 然後進程退出, 然後有後續的新進程佔據了這個pid, 那麼指令碼根據這個pid判斷之前的進程是否存活就沒意義了, 由此導致誤判
# linux kernel對pid的分配採用了延時再分配的策略, pid被複用而導致重判, 這個需要注意

*). 並發+wait使用

for slave in `cat "$HOSTLIST"|sed "s/#.*$//;/^$/d"`; do  ssh $SPARK_SSH_OPTS $slave $"${@// /\\ }"     2>&1 | sed "s/^/$slave: /" &  if [ "$SPARK_SLAVE_SLEEP" != "" ]; then    sleep $SPARK_SLAVE_SLEEP  fidonewait 

代碼評註:
# shell指令碼沒有多線程的概念, 且預設執行子shell是阻塞的, 因此只能通過後台運行多個子進程來類比
# ssh $slave "<command> " & 是把ssh命令放在後台運行
# wait, 是指等待所有的後台進程結束, 才繼續進行下去
# 這是很好的並發CountDownLatch的編程實踐

*). sed命令使用

sed "s/#.*$//;/^$/d"sed "s/^/$slave: /"

代碼評註:
# 使用流編輯器sed, 對常值內容進行替換和刪除, 贊sed

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.