shell 多进程 简单方式

好多大佬都利用&符号加for循环将其放在后台执行,有利有弊,代码如:

#!/bin/bash
for i in `seq 100`;do
sleep 1 &
done

这样虽然执行了一百次循环,但是每次的sleep都放在了后台,一秒不到就结束了 而且完全不可控,我想要下载东西时,同时创建了大量连接放在后台 对于cpu内存都有不小的压力,同时大幅度占用带宽.

还有大佬写了个难以理解的可控的方式,每次同时放在后台一定数量的进程,但是有点难以理解.

某天,再写一个数据备份脚本的时候有了新的想法,由于HBASE中有大量的表,单条备份太慢,同时放在后台Hadoop资源不够用,同时还要知道那些表备份成功或失败,只能放在后台一条命令远远不够,所有进程全部卡死,思考后将备份语句及判断写在函数中,利用for循环将函数放在后台.同时设置变量加判断方式检查放在后台的进程数,如果足够多则执行wait等待进程执行完毕,脚本如下.

#!/bin/bash
# 删除三天之前
# 70张表24分钟
# 需要安装bc命令 并且HBASE及Hadoop添加了环境变量
LogDir='/var/log/data-backup'
mkdir $LogDir
LogFile='data-migration'
start(){
   source /etc/profile >/dev/null
   BackupTime=`date +%F`
   Backup_hbase_command='org.apache.hadoop.hbase.mapreduce.Export'
   HDFS_path='/backup'
   local_path='/backup'
   # 此参数为备份文件保存几天
   remove_day='3'
   # concurrent_number 同时放在后台执行的进程数量
   # 此参数为同时运行备份进程的数量,增加会提高备份速度但是很消耗Hadoop资源,每条都会创建一个MapReduce任务,可以根据当前集群配置适当增加以提高速度
   concurrent_number='1'
   if [ ! -f ${LogDir} ];then
       mkdir -p ${LogDir}
   fi
}
# HBASE 备份
# 将被放在后台执行的函数
backup_command(){
   echo "[ `date +%F-%T` ] $i start backup,this is a tables $a"
   # 此处的$i则是for 循环体中的变量 i
   hbase ${Backup_hbase_command} $i ${HDFS_path}/${BackupTime}/$i >>$LogDir/${LogFile}-$a.log 2>&1
   # 判断上一条结果是否成功
   if [ $? -eq 0 ];then
       echo "[ `date +%F-%T` ] $i backup sucess"
   else
       echo "[ `date +%F-%T` ] $i backup error"
   fi
}

HbaseBackup(){
   echo "[ `date +%F-%T` ] Hbase backup start"
   echo "list" |hbase shell >/dev/null
   if [ $? -eq 0 ];then
       echo "HBASE status is a: started"
   else
       echo "HBASE statua is a: stoped!"
       exit
   fi
   a='1'
   for i in `echo "list"|hbase shell |sed '1,6d'|sed '$d'|sed '$d'|sed '$d'`;do
   # 依旧是利用了for循环,但是不执行单条命令,将命令写进函数中,直接将函数放在后台
       backup_command &
       # 判断当前取余是否等于0,如果是则放在后台的函数足够多,判断为真则执行wait ,wait作用是等待后台的进程执行完毕,然后重新开始了循环
       if [[ `echo "$a % ${concurrent_number}"|bc` == 0  ]];then
           wait
           a=`echo "$a + 1"|bc`
       else
           a=`echo "$a + 1"|bc`
       fi
   done
}
data_export_local(){
   echo "[ `date +%F-%T` ] hdfs to local started"
   hdfs dfs -copyToLocal ${HDFS_path}/${BackupTime} ${local_path}
   echo "[ `date +%F-%T` ] hdfs to local stoped"
}
hive_backup(){
   echo "[ `date +%F-%T` ] hive backup start"
   backup_path='/backup/hive'
   backup_time=`date +%F`
   if [ ! -f ${backup_path} ];then
       mkdir -p $backup_path
   fi
   hdfs dfs -copyToLocal /user/hive ${backup_path}
   # 手动重复执行此处会有提示输入 y 但是不可见
   mv ${backup_path}/hive ${backup_path}/hive-${backup_time}
   hive_remove_time=`date -d "${remove_day} day ago" +%F`
   rm -rf ${backup_path}/hive-${hive_remove_time}
   echo "[ `date +%F-%T` ] hive backup end"
}
remove_time_backup(){
   remove_time=`date -d "${remove_day} day ago" +%F`
   hdfs dfs -rmr ${HDFS_path}/${remove_time}
   rm -rf ${local_path}/${remove_time}
}
start >>$LogDir/${LogFile} 2>&1
HbaseBackup >>$LogDir/${LogFile} 2>&1
data_export_local >>$LogDir/${LogFile} 2>&1
remove_time_backup >>$LogDir/${LogFile} 2>&1
hive_backup >>$LogDir/${LogFile} 2>&1
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章