用HiBench执行Hadoop——Sort测试用例,进入 /HiBench-master/bin/workloads/micro/sort/hadoop 目录下,执行命令:

[root@node1 hadoop]# ./run.sh

执行后返回如下信息:

[root@node1 hadoop]# ./run.sh
patching args=  #enter_bench()
Parsing conf: /home/cf/app/HiBench-master/conf/hadoop.conf
Parsing conf: /home/cf/app/HiBench-master/conf/hibench.conf
Parsing conf: /home/cf/app/HiBench-master/conf/spark.conf
Parsing conf: /home/cf/app/HiBench-master/conf/workloads/micro/sort.conf
probe -.cdh5./lib/hadoop/../../jars/hadoop-mapreduce-client-jobclient--cdh5.14.2-tests.jar
start HadoopSort bench
hdfs -.cdh5./bin/hadoop --config /etc/hadoop/conf.cloudera.yarn fs -rm -r -skipTrash hdfs://node1:8020/HiBench/Sort/Output
Deleted hdfs://node1:8020/HiBench/Sort/Output  #rmr_hdfs()
hdfs -.cdh5./bin/hadoop --config /etc/hadoop/conf.cloudera.yarn fs -du -s hdfs://node1:8020/HiBench/Sort/Input
Submit MapReduce Job: /opt/cloudera/parcels/CDH--.cdh5./bin/hadoop --config /etc/hadoop/conf.cloudera.yarn jar /opt/cloudera/parcels/CDH--.cdh5./lib/hadoop/../../jars/hadoop-mapreduce-examples--cdh5. hdfs://node1:8020/HiBench/Sort/Input hdfs://node1:8020/HiBench/Sort/Output #run_hadoop_job()
The job took  seconds.
finish HadoopSort bench

发现HiBench执行Python监控程序脚本的命令为:

UID        PID  PPID  C STIME TTY          TIME CMD

root             : pts/    :: python2 /home/cf/app/HiBench-master/bin/functions/monitor.py HadoopSort  /home/cf/app/HiBench-master/report/sort/hadoop/conf/../monitor.log /home/cf/app/H

root         : pts/    :: python2 /home/cf/app/HiBench-master/bin/functions/execute_with_log.py /home/cf/app/HiBench-master/report/sort/hadoop/conf/../bench.log /opt/cloudera/parcels/CD

查看文件run.sh的内容:

  current_dir=`dirname "$0"`
  current_dir=`cd "$current_dir"; pwd`
  root_dir=${current_dir}/../../../../../
  workload_config=${root_dir}/conf/workloads/micro/sort.conf
  . "${root_dir}/bin/functions/load_bench_config.sh"

  enter_bench HadoopSort ${workload_config} ${current_dir}
  show_bannar start

  rmr_hdfs $OUTPUT_HDFS || true

  SIZE=`dir_size $INPUT_HDFS`
  START_TIME=`timestamp`
  run_hadoop_job ${HADOOP_EXAMPLES_JAR} sort -outKey org.apache.hadoop.io.Text -outValue org.apache.hadoop.io.Text -r ${NUM_REDS} ${INPUT_HDFS} ${OUTPUT_HDFS}

  END_TIME=`timestamp`
  gen_report ${START_TIME} ${END_TIME} ${SIZE}
  show_bannar finish
  leave_bench

在文件run.sh中,发现 run_hadoop_job() 调用了 start_monitor 方法:

function run_hadoop_job(){
    ENABLE_MONITOR=
    if [ "$1" = "--without-monitor" ]; then
        ENABLE_MONITOR=

    fi
    local job_jar=$
    shift
    local job_name=$
    shift
    local tail_arguments=$@
    local CMD="${HADOOP_EXECUTABLE} --config ${HADOOP_CONF_DIR} jar $job_jar $job_name $tail_arguments"
    echo -e "${BGreen}Submit MapReduce Job: ${Green}$CMD${Color_Off}"
     ]; then
        MONITOR_PID=`start_monitor`
    fi
    execute_withlog ${CMD}
    result=$?
     ]; then
        stop_monitor ${MONITOR_PID}
    fi
     ]; then
        echo -e "${BRed}ERROR${Color_Off}: Hadoop job ${BYellow}${job_jar} ${job_name}${Color_Off} failed to run successfully."
        echo -e "${BBlue}Hint${Color_Off}: You can goto ${BYellow}${WORKLOAD_RESULT_FOLDER}/bench.log${Color_Off} to check for detailed log.\nOpening log tail for you:\n"
        tail ${WORKLOAD_RESULT_FOLDER}/bench.log
        exit $result
    fi
}

查看 start_monitor 方法的定义:

function start_monitor(){
    MONITOR_PID=`${workload_func_bin}/monitor.py ${HIBENCH_CUR_WORKLOAD_NAME} $$ ${WORKLOAD_RESULT_FOLDER}/monitor.log ${WORKLOAD_RESULT_FOLDER}/bench.log ${WORKLOAD_RESULT_FOLDER}/monitor.html ${SLAVES} &`
#    echo "start monitor, got child pid:${MONITOR_PID}" > /dev/stderr
    echo ${MONITOR_PID}
}

还有 stop_monitor  方法的定义:

function stop_monitor(){
    MONITOR_PID=$
    assert $ "monitor pid missing"
#    echo "stop monitor, kill ${MONITOR_PID}" > /dev/stderr
    kill ${MONITOR_PID}
}

以及 execute_withlog 方法的定义:

function execute_withlog () {
    CMD="$@"
     ] ; then          # Terminal, beautify the output.
        ${workload_func_bin}/execute_with_log.py ${WORKLOAD_RESULT_FOLDER}/bench.log $CMD
    else                        # pipe, do nothing.
        $CMD
    fi
}

在 run.sh 中加入以下三行:

  echo "PID of this script: $$"
  echo "PPID of this script: $PPID"
  echo "UID of this script: $UID"

文件的部分内容如下:

  SIZE=`dir_size $INPUT_HDFS`
  START_TIME=`timestamp`
  run_hadoop_job ${HADOOP_EXAMPLES_JAR} sort -outKey org.apache.hadoop.io.Text -outValue org.apache.hadoop.io.Text -r ${NUM_REDS} ${INPUT_HDFS} ${OUTPUT_HDFS}

  echo "PID of this script: $$"
  echo "PPID of this script: $PPID"
  echo "UID of this script: $UID"

  END_TIME=`timestamp`
  gen_report ${START_TIME} ${END_TIME} ${SIZE}
  show_bannar finish
  leave_bench

执行后返回如下信息:

PID of this script:
PPID of this script:
UID of this script: 

用 ps -ef 查看发现 18804 和 32331 分别对应如下进程:

UID        PID  PPID  C STIME TTY          TIME CMD
root         : pts/    :: -bash
root         : pts/    :: /bin/bash ./run_bak.sh

经查找,发现:

在bash中,子shell进程的PID存储在一个特殊的变量\$\$中。这个变量只读,你不可以在脚本中修改它。除了\$\$, bash shell还会导出其他的只读变量。比如,\$PPID存储子shell父进程的ID(也就是主shell)。\$UID存储了执行这个脚本的当前用户ID。上面输出中,PID每次执行都会变化。这个因为每次运行都会创建一个新的shell。另一方面,PPID每次都会一样只要你在同一个shell中运行。

分析 monitor.py 发现如下方法调用:

pid=os.fork()

分析 execute_with_log.py 发现如下方法调用:

proc = subprocess.Popen(" ".join(command_lines), shell=True, bufsize=1, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

经过思考,利用 subprocess.Popen( ) 方法启动子进程并获取子进程返回值,子进程利用 \$\$ 变量获取PID并作为返回值传递给父进程,父进程可以启动监控程序记录子进程的运行数据。

参考:

https://www.jb51.net/article/62370.htm

https://www.cnblogs.com/ratels/p/11039813.html

https://www.cnblogs.com/ratels/p/11070615.html

https://www.cnblogs.com/zhoug2020/p/5079407.html

Python测试进阶——(6)Bash脚本启动Python监控程序并传递PID的更多相关文章

  1. Python测试进阶——(7)动手编写Bash脚本启动Python监控程序并传递PID

    如下: #./cf_workload_functions.sh function timestamp(){ # get current timestamp sec=`date +%s` nanosec ...

  2. Python测试进阶——(3)编写Python程序监控计算机的服务是否正常运行

    用python写了个简单的监控进程的脚本,当发现进程消失的时候,立即调用服务,开启服务. 脚本的工作原理是这样的:脚本读取配置文件,读取预先配置好的调用系统服务的路径和所要监控的服务在进程管理器中的进 ...

  3. Python测试进阶——(1)安装Python测试相关模块

    安装python 安装pip yum -y install epel-release yum -y install python-pip 安装psutil 参考:https://www.cnblogs ...

  4. Python测试进阶——(4)Python程序监控、存储、分析并可视化CPU和内存利用率

    monitor190617.py 监控cpu和内存利用率信息,组织成json格式,并写入到 record.txt 文件中: import psutil import time import json ...

  5. 年薪20万Python工程师进阶(7):Python资源大全,让你相见恨晚的Python库

    我是 环境管理 管理 Python 版本和环境的工具 pyenv – 简单的 Python 版本管理工具. Vex – 可以在虚拟环境中执行命令. virtualenv – 创建独立 Python 环 ...

  6. Python测试进阶——(5)Python程序监控指定进程的CPU和内存利用率

    用Python写了个简单的监控进程的脚本monitor190620.py,记录进程的CPU利用率和内存利用率到文件pid.csv中,分析进程运行数据用图表展示. 脚本的工作原理是这样的:脚本读取配置文 ...

  7. Python测试进阶——(2)配置PyCharm远程调试环境

    新建一个Python项目 配置Deployment,用于本地文件和远程文件的同步,在pycharm的菜单栏依次找到:Tools > Deployment > Configuration 点 ...

  8. python 测试框架nose

    python测试框架nose nose不是python自带模块,这里我才用pip的方式安装 pip install nose 这样就完成了安装,然后再确认下是否安装成功了,直接打开cmd输入noset ...

  9. Appium环境的安装与配置,Python测试脚本测试

    Appium自动化测试系列1 - Appium环境的安装与配置 发表于4个月前(2015-01-27 14:34)   阅读(803) | 评论(0) 0人收藏此文章, 我要收藏 赞0 寻找 会’偷懒 ...

随机推荐

  1. 简单bat脚本

    hwf.bat: set GAP_HOME=%~dp0\.. ::copy "%JAVA_HOME%\bin\javaw.exe" "%JAVA_HOME%\bin\HW ...

  2. php cli 下 php.ini 配置

    // 查看phpcli 模式下 扩展 php -m // 查看php cli 版本 php -v 查看命令行的ini路径,命令行下运行 php --ini Loaded Configuration F ...

  3. php 基础 获取远程连接

    1 file_get_contents get $opts = array( 'http'=>array( 'method'=>"GET", 'timeout'=> ...

  4. CURL_模拟登录

    <?php $curl = curl_init(); $url = "http://www.imooc.com/user/login"; //$url = "htt ...

  5. JAVA性能优化工具小记

    好记性不如烂笔头,戊戌年的最后一个工作日,把自己平时在开发过程中使用的一些java性能优化工具做一个简单的小结, 主要包括 jvisualvm.jfr.gdb和查看内存对象信息的几个linux命令. ...

  6. Struts2高级(插件)笔记一

    插件 Struts-plugin.xml 说明: Struts-plugin.xml文件是在tomcat服务器启动的时候加载的 该配置文件在classpath的根目录下 在每一个含有plugin字母的 ...

  7. MFC加载图片

    目录 1. 自适应方法 2. 加载原图方法 1. 自适应方法 /* 自适应方法 */ CRect rect; CRect rect1; CImage image; //创建图片类 image.Load ...

  8. python爬虫(七) mozillacookiejar

    MozillaCookiejar 保存百度得Cookiejar信息: from urllib import request from urllib import parse from http.coo ...

  9. 列表推导式、生成器表达式以及zip()max()max()/min()sum()sort()map()filter()的用法

    列表推导式: 基本格式: variable = [out_exp_res for out_exp in input_list if out_exp == 2] #out_exp_res: 列表生成元素 ...

  10. 嵌入式编程中使用 do{...} while(0) 的解释

    最近在看esp32的idf,有一些宏定义使用了do while(0)这种看起来好像没啥用的代码.然后我查了一下资料,发现在linux内核代码中经常用到这个东西! 现在就将这个东西整理一下. 为什么在内 ...