Linux shell 多进程 简单方式

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

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

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

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

#!/bin/bash
vars()
{
    # 此函数定义了全局变量
    # 每次执行的最大进程数
    pool_number='5'
    # 总共循环次数
    process_sum_num='5'
}

process()
{
    # 此函数为后台执行函数
    echo "后台进程 $1"
    ssh es${1} "sleep 10"
    if [ $? -eq 0 ];then
        echo "后台进程 $1 [SUCESS]"
    else
        echo "后台进程 $1 [ERROR]"
    fi
}
pool()
{
    # 此函数为循环提交任务
    process_number=0
    for i in `seq $process_sum_num`;do
        process $i &
        process_number=$(($process_number + 1))
        # 判断当前提交的进程数是否到达了全局变量中定义的每次执行的最大数量
        if [[ $(($process_number % $pool_number)) == 0 ]];then
            # 如果已经满足了最大进程数 那么则执行等待 等待所有进程执行完毕才会开始新一轮的循环
            wait
        fi
    done
    sleep 0.5;echo "process running sucess."
}
start()
{
    vars
    pool
}
start

某天,再写一个数据备份脚本的时候有了新的想法,由于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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值