관리 메뉴

HAMA 블로그

HAMA 쉘 분석 본문

HAMA

HAMA 쉘 분석

[하마] 이승현 (wowlsh93@gmail.com) 2015. 9. 30. 17:32



참고로 위의 모식도는 하둡의 쉘 실행모습입니다. 하마도 하둡과 매우 비슷합니다.

$ bin/start-bspd.sh

위와 같이 start-bspd.sh 로 부터 시작합니다. 마스터 노드에서 실행합니다.

bin=`dirname "$0"`

bin=`cd "$bin"; pwd`       //  bin 디렉토리의 경로를 얻는다.


. "$bin"/hama-config.sh  // hama-config.sh 를 내부적으로 실행한다.


"$bin"/hama-daemons.sh --config "${HAMA_CONF_DIR}" start zookeeper   // 주키퍼 부터 시작하고

"$bin"/hama-daemon.sh --config $HAMA_CONF_DIR start bspmaster   // bspmaster 실행

"$bin"/hama-daemons.sh --config $HAMA_CONF_DIR start groom      // groom 실행 


bin/hama-config.sh

hama-config.sh 안에서는 conf/hama-env.sh 를 실행하며, groomserver 를 export

conf/hama-env.sh

hama-env.sh 에서는 아래와 같이 JAVA_HOME 등을 설정합니다.

# The java implementation to use.  Required.
export JAVA_HOME=/usr/lib/jvm/java-7-oracle

# Where log files are stored.  $HAMA_HOME/logs by default.
# export HAMA_LOG_DIR=${HAMA_HOME}/logs

# The maximum amount of heap to use, in MB. Default is 1000.
# export HAMA_HEAPSIZE=1000

# Tell Hama whether it should manage it's own instance of Zookeeper or not.
export HAMA_MANAGES_ZK=true 


hama-daemon.sh 을 통해 bspmaster 를  실행합니다. 

#!/usr/bin/env bash

usage="Usage: hama-daemon.sh [--config <conf-dir>] [--hosts hostlistfile] (start|stop) <hama-command> <args...>"


# if no args specified, show usage

if [ $# -le 1 ]; then

  echo $usage

  exit 1

fi


bin=`dirname "$0"`

bin=`cd "$bin"; pwd`


. "$bin"/hama-config.sh


# get arguments

startStop=$1

shift

command=$1

shift


hama_rotate_log ()

{

    log=$1;

    num=5;

    if [ -n "$2" ]; then

num=$2

    fi

    if [ -f "$log" ]; then # rotate logs

while [ $num -gt 1 ]; do

   prev=`expr $num - 1`       

   [ -f "$log.$prev" ] && mv "$log.$prev" "$log.$num"

   num=$prev

done

mv "$log" "$log.$num";

    fi

}


if [ -f "${HAMA_CONF_DIR}/hama-env.sh" ]; then

  . "${HAMA_CONF_DIR}/hama-env.sh"

fi


# get log directory

if [ "$HAMA_LOG_DIR" = "" ]; then

  export HAMA_LOG_DIR="$HAMA_HOME/logs"

fi

mkdir -p "$HAMA_LOG_DIR"


if [ "$HAMA_PID_DIR" = "" ]; then

  HAMA_PID_DIR=/tmp

fi


if [ "$HAMA_IDENT_STRING" = "" ]; then

  export HAMA_IDENT_STRING="$USER"

fi


# some variables

export HAMA_LOGFILE=hama-$HAMA_IDENT_STRING-$command-$HOSTNAME.log

export HAMA_ROOT_LOGGER="INFO,DRFA"

log=$HAMA_LOG_DIR/hama-$HAMA_IDENT_STRING-$command-$HOSTNAME.out

pid=$HAMA_PID_DIR/hama-$HAMA_IDENT_STRING-$command.pid


# Set default scheduling priority

if [ "$HAMA_NICENESS" = "" ]; then

    export HAMA_NICENESS=0

fi


case $startStop in

  (start)

    mkdir -p "$HAMA_PID_DIR"


    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

      fi

    fi


    if [ "$HAMA_MASTER" != "" ]; then

      echo rsync from $HAMA_MASTER

      rsync -a -e ssh --delete --exclude=.svn --exclude='logs/*' --exclude='contrib/hod/logs/*' $HAMA_MASTER/ "$HAMA_HOME"

    fi


    hama_rotate_log $log

    echo starting $command, logging to $log

    cd "$HAMA_HOME"

    nohup nice -n $HAMA_NICENESS "$HAMA_HOME"/bin/hama --config $HAMA_CONF_DIR $command "$@" > "$log" 2>&1 < /dev/null &

    echo $! > $pid

    sleep 1; head "$log"

    ;;

          

  (stop)


    if [ -f $pid ]; then

      if kill -0 `cat $pid` > /dev/null 2>&1; then

        echo stopping $command

        kill `cat $pid`

      else

        echo no $command to stop

      fi

    else

      echo no $command to stop

    fi

    ;;


  (*)

    echo $usage

    exit 1

    ;;


esac


--------------------------------------------------------------------------------------------------------

- 역 따옴표는 따옴표나 작은 따옴표와는 완전히 다른 용도로 쓰인다. 공백 문자를 포함하는 데에는 쓰이지 않는다.  글의 앞쪽에서 다음 라인을 사용했던 것을 기억해 보라:

x=$(expr $x + 1)

이미 당신이 알듯이, 명령 expr $x + 1 결과가 변수 x 들어가게 된다.  따옴표를 사용한 다음의 명령도  같은 결과를 낸다:

x=`expr $x + 1`

어느 것을 사용해야 하는가 하는 문제는 순전히 당신에게 달려 있다. 당신이 좋은 쪽을 선택하라.  따옴표가 $(...) 보다 자주 사용되는 것을   있을 것이다. 하지만, $(...) 보다 읽기 쉽다. 다음과 같은 경우엔 특히  그렇다:

$!/bin/bash
echo "I am `whoami`"

--------------------------------------------------------------------------------------------------------

-nohup : 로그아웃 하여 터미널을 빠져나가도 실행중인 프로그램이 종료되지 않고 계속 수행될수 있게 하는 명령

프로그램을 데몬처럼 실행하고 싶을 때는 아래와 같이 하면 됩니다. 

" 명령어 & "
여기서 '&'는 백그라운드로 실행하라는 뜻입니다.
그런데, 이 방법은 실행한 사용자가 로그아웃하면 프로그램도 함께 종료됩니다.
이럴때는 nohup 이란 명령어를 사용하면 됩니다.

 

nohup(노헙) 정의
리눅스, 유닉스에서 쉘스크립트파일(*.sh)을 데몬형태로 실행시키는 프로그램

 

nohup 주의사항
nohup으로 실행할 쉘스크립트파일(*.sh)은 현재 퍼미션이 755이상 상태여야 한다.

chmod 755 shell.sh

--------------------------------------------------------------------------------------------------------

rsync 동기화 툴 

# rsync options source destination


로컬 컴퓨터에 있는 moniwiki 디렉토리를 원격 컴퓨터로 복사하는 예제다.

# rsync -avz moniwiki/ yundream@192.168.56.101:/home/yundream/backups


원격 컴퓨터의 내용을  로컬로 복사 

# rsync -avzh yundream@192.168.56.101:/home/yundream/backups ./


Rsync는 -e 옵션을 이용해서 ssh, rsh와 같은 remote shell 프로그램을 선택할 수 있다. 보통 안전한 통신을 보장해주는 ssh

를 이용한다. -e 옵션이 없다면 ssh를 사용한다.


data 디렉토리를 복사에서 제외한다.
# rsync -avz  --exclude 'data' yundream@192.168.56.101:/home/yundream/backups ./


별표(*)도 사용할 수 있다.
# rsync -avz  --exclude '*.bak' yundream@192.168.56.101:/home/yundream/backups ./

rsync는 파일이나 디렉토리가 없으면 새로 만든다. 그러나 파일이나 디렉토리가 존재할 경우 삭제하고 싶을 때도 있을 거다.

이럴때 
--delete 옵션을 사용한다.

로컬 서버에 "text.txt"파일이 있으면 삭제한 후 복사하는 예제다.
# touch test.txt
# rsync -avz --delete yundream@192.168.56.101:/home/yundream/backups ./





최종적으로 hama 를 실행합니다. 


bin=`dirname "$0"`

bin=`cd "$bin"; pwd`


. "$bin"/hama-config.sh


cygwin=false

case "`uname`" in

CYGWIN*) cygwin=true;;

esac


# if no args specified, show usage

if [ $# = 0 ]; then

  echo "Usage: hama [--config confdir] COMMAND"

  echo "where COMMAND is one of:"

  echo "  bspmaster            run the BSP Master node"

  echo "  groom                run the Groom node"

  echo "  zookeeper            run a Zookeeper server"

  echo "  job                  manipulate BSP jobs"

  echo "  jar <jar>            run a jar file"

  echo "  pipes               run a pipe job"

  echo "  seqdumper            run SequenceFileDumper"

  echo " or"

  echo "  CLASSNAME            run the class named CLASSNAME"

  echo "Most commands print help when invoked w/o parameters."

  exit 1

fi


# get arguments

COMMAND=$1

shift


if [ -f "${HAMA_CONF_DIR}/hama-env.sh" ]; then

  . "${HAMA_CONF_DIR}/hama-env.sh"

fi


# some Java parameters

if [ "$JAVA_HOME" != "" ]; then

  #echo "run java in $JAVA_HOME"

  JAVA_HOME=$JAVA_HOME

fi

  

if [ "$JAVA_HOME" = "" ]; then

  echo "Error: JAVA_HOME is not set."

  exit 1

fi


JAVA=$JAVA_HOME/bin/java

JAVA_HEAP_MAX=-Xmx1000m


# check envvars which might override default args

if [ "$HAMA_HEAPSIZE" != "" ]; then

  #echo "run with heapsize $HAMA_HEAPSIZE"

  JAVA_HEAP_MAX="-Xmx""$HAMA_HEAPSIZE""m"

  #echo $JAVA_HEAP_MAX

fi


# CLASSPATH initially contains $HAMA_CONF_DIR

CLASSPATH="${HAMA_CONF_DIR}"

CLASSPATH=${CLASSPATH}:$JAVA_HOME/lib/tools.jar


# for developers, add Hama classes to CLASSPATH

if [ -d "$HAMA_HOME/core/target/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/core/target/classes

fi

if [ -d "$HAMA_HOME/core/target/test-classes/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/core/target/test-classes

fi


# for developers, add Commons classes to CLASSPATH

if [ -d "$HAMA_HOME/commons/target/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/commons/target/classes

fi

if [ -d "$HAMA_HOME/commons/target/test-classes/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/commons/target/test-classes

fi


# for developers, add Graph classes to CLASSPATH

if [ -d "$HAMA_HOME/graph/target/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/graph/target/classes

fi

if [ -d "$HAMA_HOME/graph/target/test-classes/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/graph/target/test-classes

fi


# for developers, add ML classes to CLASSPATH

if [ -d "$HAMA_HOME/ml/target/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/ml/target/classes

fi

if [ -d "$HAMA_HOME/ml/target/test-classes/classes" ]; then

  CLASSPATH=${CLASSPATH}:$HAMA_HOME/ml/target/test-classes

fi


# so that filenames w/ spaces are handled correctly in loops below

IFS=


# for releases, add core hama jar to CLASSPATH

for f in $HAMA_HOME/hama-**.jar; do

  CLASSPATH=${CLASSPATH}:$f;

done


# add libs to CLASSPATH

for f in $HAMA_HOME/lib/*.jar; do

  CLASSPATH=${CLASSPATH}:$f;

done


# add user-specified CLASSPATH last

if [ "$HAMA_CLASSPATH" != "" ]; then

  CLASSPATH=${CLASSPATH}:${HAMA_CLASSPATH}

fi


# default log directory & file

if [ "$HAMA_LOG_DIR" = "" ]; then

  HAMA_LOG_DIR="$HAMA_HOME/logs"

fi

if [ "$HAMA_LOGFILE" = "" ]; then

  HAMA_LOGFILE='hama.log'

fi


# default policy file for service-level authorization

if [ "$HAMA_POLICYFILE" = "" ]; then

  HAMA_POLICYFILE="hama-policy.xml"

fi


# restore ordinary behaviour

unset IFS


# figure out which class to run

if [ "$COMMAND" = "bspmaster" ] ; then

  CLASS='org.apache.hama.BSPMasterRunner'

  BSP_OPTS="$BSP_OPTS $BSP_BSPMASTER_OPTS"

elif [ "$COMMAND" = "groom" ] ; then

  CLASS='org.apache.hama.GroomServerRunner'

  BSP_OPTS="$BSP_OPTS $BSP_GROOMSERVER_OPTS"

elif [ "$COMMAND" = "zookeeper" ] ; then

  CLASS='org.apache.hama.ZooKeeperRunner'

elif [ "$COMMAND" = "job" ] ; then

  CLASS='org.apache.hama.bsp.BSPJobClient'

elif [ "$COMMAND" = "pipes" ] ; then

  CLASS='org.apache.hama.pipes.Submitter'

elif [ "$COMMAND" = "seqdumper" ] ; then

  CLASS='org.apache.hama.pipes.util.SequenceFileDumper'

elif [ "$COMMAND" = "jar" ] ; then

  CLASS=org.apache.hama.util.RunJar

  BSP_OPTS="$BSP_OPTS"

else

  CLASS=$COMMAND

fi


# cygwin path translation

if $cygwin; then

  CLASSPATH=`cygpath -p -w "$CLASSPATH"`

  HAMA_HOME=`cygpath -w "$HAMA_HOME"`

  HAMA_LOG_DIR=`cygpath -w "$HAMA_LOG_DIR"`

  TOOL_PATH=`cygpath -p -w "$TOOL_PATH"`

fi


# cygwin path translation

if $cygwin; then

  JAVA_LIBRARY_PATH=`cygpath -p "$JAVA_LIBRARY_PATH"`

fi


HAMA_OPTS="$HAMA_OPTS -Dhama.log.dir=$HAMA_LOG_DIR"

HAMA_OPTS="$HAMA_OPTS -Dhama.log.file=$HAMA_LOGFILE"

HAMA_OPTS="$HAMA_OPTS -Dhama.home.dir=$HAMA_HOME"

HAMA_OPTS="$HAMA_OPTS -Dhama.id.str=$HAMA_IDENT_STRING"

HAMA_OPTS="$HAMA_OPTS -Dhama.root.logger=${HAMA_ROOT_LOGGER:-INFO,console}"

if [ "x$JAVA_LIBRARY_PATH" != "x" ]; then

  HAMA_OPTS="$HAMA_OPTS -Djava.library.path=$JAVA_LIBRARY_PATH"

fi  

HAMA_OPTS="$HAMA_OPTS -Dhama.policy.file=$HAMA_POLICYFILE"

# run it

exec "$JAVA" $JAVA_HEAP_MAX $HAMA_OPTS -classpath "$CLASSPATH" $CLASS "$@"




- 변수를 참조할 때는 보통 큰 따옴표(" ")로 묶어 주는게 좋습니다. 이렇게 하면 $, `(backquote), \(이스케이프)를 제외한 모든 특수 문자들을 보존해 줍니다. 

작은 따옴표(' ')도 큰 따옴표와 비슷하게 동작하지만 $의 특별한 의미를 꺼 버려서 변수 참조가 일어나지 않게 합니다. 작은 따옴표안의 '을 제외한 모든 특수 문자들은 단순히 문자 그대로 해석됩니다. 작은 따옴표("완전한 쿼우팅")를 큰 따옴표("부분 인용")보다 좀 더 엄격한 방법이라고 생각하면 됩니다.

"$@" 는  이쉘을 호출할때 사용한 모든 arg 를 그대로 써줍니다. ("$1" 은 첫번째 인자만)

JAVA 에 -server 옵션이 없는 이유는 코어가 2개이상 메모리가 1기가 이상이면 자동적으로
  VM -s erver 이 적용될것이기때문입니다.

if [ -e $filename ] ; then    // 파일이 존재하는지 , -f  일반파일인지 , -d 디렉토리인

IFS(Internal File Seperator)

IFS는 명령어의 옵션을 설정하거나 프로그램의 아귀먼트를 지정할때 명령어와 옵션, 프로그램과 아귀먼트를 구분해주는 일종의 시스템 구분 인자를 말한다. 

#!/bin/bash var="'(]\\{}\$\"" echo $var # '(]\{}$" echo "$var" # '(]\{}$" 차이가 없죠? echo IFS='\' echo $var # '(] {}$" \ 가 빈 칸으로 바뀌었네요. echo "$var" # '(]\{}$" # S.C. 제공 exit 0



hama-daemons.sh 를 통해 groom 들을 실행합니다. 

usage="Usage: hama-daemons.sh [--config confdir] [--hosts hostlistfile] [start|stop] command args..."


# if no args specified, show usage

if [ $# -le 1 ]; then

  echo $usage

  exit 1

fi


bin=`dirname "$0"`

bin=`cd "$bin"; pwd`


. $bin/hama-config.sh


remote_cmd="cd ${HAMA_HOME}; $bin/hama-daemon.sh --config ${HAMA_CONF_DIR} $@"

args="--config ${HAMA_CONF_DIR} $remote_cmd"

command=$2


case $command in

  (zookeeper)

    exec "$bin/zookeepers.sh" $args

    ;;

  (*)

    exec "$bin/grooms.sh" $args

    ;;

esac


grooms.sh 실행 

#!/usr/bin/env bash


usage="Usage: grooms.sh [--config confdir] command..."

# if no args specified, show usage
if [ $# -le 0 ]; then
  echo $usage
  exit 1
fi

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

. "$bin"/hama-config.sh

# If the groomservers file is specified in the command line,
# then it takes precedence over the definition in 
# hama-env.sh. Save it here.
HOSTLIST=$HAMA_GROOMS

if [ -f "${HAMA_CONF_DIR}/hama-env.sh" ]; then
  . "${HAMA_CONF_DIR}/hama-env.sh"
fi

if [ "$HOSTLIST" = "" ]; then
  if [ "$HAMA_GROOMS" = "" ]; then
    export HOSTLIST="${HAMA_CONF_DIR}/groomservers"
  else
    export HOSTLIST="${HAMA_GROOMS}"
  fi
fi

for groom in `cat "$HOSTLIST"|sed  "s/#.*$//;/^$/d"`; do
 ssh $HAMA_SSH_OPTS $groom $"${@// /\\ }" $groom \
   2>&1 | sed "s/^/$groom: /" &
 if [ "$HAMA_GROOM_SLEEP" != "" ]; then
   sleep $HAMA_GROOM_SLEEP
 fi
done

wait


SED는 스트림 에디터입니다. 스트림 에디터는 입력 스트림(파일이나 파이프를 통한 입력)에 대해서 단순한 텍스트 교체가 필요할 때 쓰입니다.

1. 주소 지정

주소 지정이란 편집하고자 하는 행을 선택하는 것을 말한다. 이 주소는 숫자나 정규표현식 또는 둘의 조합으로 표현한다. 주소를 지정하지 않은 경우 입력 파일 전체 행에 대하여 작업을 진행한다.

sed ‘1,3p’ datafile

: datafile 1행에서 3행까지 출력한다. p는 행을 출력하라는 명령어이다.


sed -n ‘/[Ll]ove/p’ datafile

: datafile에서 Love love를 포함하는 행만 출력한다.


레퍼런스:http://hyunkie.tistory.com/51



'HAMA' 카테고리의 다른 글

HAMA 시작하기  (0) 2015.09.30
[하마 인사이드] 1. HAMA with K-Means  (0) 2015.05.05
Comments