shell命令行并行神器 - parallel

news2024/11/15 10:25:26

shell命令行并行神奇 - parallel

概述

GNU parallel 是一个 shell 工具,用于使用一台或多台计算机并行执行作业。作业可以是单个命令或必须为输入中的每一行运行的小脚本。典型的输入是文件列表、主机列表、用户列表、URL 列表或表列表。作业也可以是从管道读取的命令。 GNU parallel 然后可以拆分输入并将其通过管道并行传输到命令中。

  • 在 shell 中编写循环,你会发现 GNU parallel 可以取代大部分循环,并通过并行运行多个作业来使它们运行得更快。

  • 对于每一行输入,GNU parallel 将以该行作为参数执行命令。如果没有给出命令,则执行输入行。多条线路将并行运行。

  • GNU parallel 确保命令的输出与顺序运行命令的输出相同。这使得使用 GNU parallel 的输出作为其他程序的输入成为可能。
    在这里插入图片描述

基本语法

熟悉xargs的同学对这个应该理解起来很快

1、生成五个文件并重定向输入

seq 5 | parallel seq {} '>' example.{}
# 回忆一下for 循环怎么写来着
# for i in `seq 5`;do echo `seq $i` > example-for.$i;done

2、parallel的输入

::: 后面跟的是其从命令行的输入

  • parallel echo ::: 1 2 3 4 5

输出是

1
2
3
4
5
  • parallel wc ::: example.*

输入是文件名

1 1 2 example.1
2 2 4 example.2
3 3 6 example.3
4 4 8 example.4
5 5 10 example.5

wc 默认输出解释

wc example.3
3 3 6 example.3
#行数 单词数 字节数 文件名
  • parallel echo ::: S M L ::: Green Red

多个::: 输入,输出是排列组合

S Green
S Red
M Green
M Red
L Green
L Red
  • find example.* -print | parallel echo File

parallel从标准输入读取

File example.1
File example.2
File example.3
File example.4
File example.5

3、和命令行的结合

# parallel echo counting lines';' wc -l ::: example.*
counting lines
1 example.1
counting lines
2 example.2
counting lines
3 example.3
counting lines
4 example.4
counting lines
5 example.5

用{}进行字符替换,这个是不是和xargs 很像

parallel echo test lines';' wc -l ::: example.*
test example.1
1 example.1
test example.2
2 example.2
test example.4
4 example.4
test example.3
3 example.3
test example.5
5 example.5

当有多个输入的时候,使用{1} {2}

例如需要分别统计example.*中的行数和字节数

# parallel echo count {1} in {2}';' wc {1} {2} ::: -l -c ::: example.*
count -l in example.1
1 example.1
count -l in example.2
2 example.2
count -l in example.3
3 example.3
count -l in example.4
4 example.4
count -l in example.5
5 example.5
count -c in example.1
2 example.1
count -c in example.2
4 example.2
count -c in example.3
6 example.3
count -c in example.4
8 example.4
count -c in example.5
10 example.5

–dry-run 测试

# parallel --dry-run echo count {1} {2} ';' wc {1} {2} ::: -c -l ::: example.*
# 看这个结果已经不是顺序得了
echo count -c example.1 ; wc -c example.1
echo count -c example.2 ; wc -c example.2
echo count -c example.3 ; wc -c example.3
echo count -c example.5 ; wc -c example.5
echo count -c example.4 ; wc -c example.4
echo count -l example.1 ; wc -l example.1
echo count -l example.2 ; wc -l example.2
echo count -l example.3 ; wc -l example.3
echo count -l example.4 ; wc -l example.4

4、输出

5、并行数量

当然这个是并行的,并行数设置多少合适呢?

默认值是和你的os 的cores相同。一般为了限制parallel占据所有的cpu资源,建议使用 --jobs限制其并发数,作为脚本的参数输入比较常见

–jobs 0 竟可能多的并行

测试

# 并行为1,理论上就是5+4+3+2+1 =15 s
time parallel --jobs 1 sleep {}';' echo {} done ::: 5 4 3 1 2
# 并行为0,取决于最慢的那个sleep
time parallel --jobs 0 sleep {}';' echo {} done ::: 5 4 3 1 2

如果是五个job

Job slot 1: 55555
Job slot 2: 4444
Job slot 3: 333
Job slot 4: 1
Job slot 5: 22

6、处理大文本数据

将数据块传递给标准输入上

#seq 1000000 | parallel --pipe wc
 165668  165668 1048571
 149796  149796 1048572
 149796  149796 1048572
 149796  149796 1048572
 149796  149796 1048572
 149796  149796 1048572
  85352   85352  597465

大约 1 MB 的块传递给每个作业

1mb的行数、字符数、字节数

实战 并发docker run

并行启动dokcer 容器进行redis key迁移,效能大幅度提升。

通过以下脚本可以体会到 parallel的魅力:

  • 代替了shell中的循环
  • 线程数量可控制(原生shell循环做不到)
  • 多线程输出可保证顺序(原生shell循环做不到)
#!/bin/bash
# date 2023年2月9日17:57:20
# author ninesun
# desc parallel docker run  
set -e
set -o pipefail
# 获取到程序的绝对路径
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
# parallel 并行数量
JOBS=${JOBS:-5}

ERRORS="$(pwd)/errors"
INFO="$(pwd)/info"

dockerrun() {
	f=$1
    docker rm -f redis-img-${f}
    # echo ${f}
    docker run  --name redis-img-${f} 10.50.10.185/harbortest/redis-mig:1.2 python3 redisMigrate.py 10.50.10.45 19000 10.50.10.170 7100 \
     ${f} ::: "${files[@]}" >  $INFO/dockerrun.log

}
echo
echo

main(){
	# get the indexfile
	IFS=$'\n'
	mapfile -t files < <(find ./ -name "st*.txt.*" -o -name "line*.txt.*" |sed 's|./||'| sort)
	unset IFS
	# docker run all jobs
	echo "Running in parallel with ${JOBS} jobs."
	# 开启$jobs 个 /opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun xxx.txt
	parallel --tag --verbose --ungroup -j"${JOBS}" "$SCRIPT" dockerrun {1} ::: "${files[@]}"

	if [[ ! -f "$ERRORS" ]]; then
		echo "No errors, hooray!"
	else
		echo "[ERROR] Some images did not build correctly, see below." >&2
		echo "These images failed: $(cat "$ERRORS")" >&2
		exit 1
	fi
}

run(){
	args=$*
	f=$1

	if [[ "$f" == "" ]]; then
		main "$args"
	else
		$args
	fi
}

run "$@"

10个并发测试

./mig-v2.sh



Running in parallel with 10 jobs.
Academic tradition requires you to cite works you base your article on.
When using programs that use GNU Parallel to process data for publication
please cite:

  O. Tange (2011): GNU Parallel - The Command-Line Power Tool,
  ;login: The USENIX Magazine, February 2011:42-47.

This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing.

To silence the citation notice: run 'parallel --bibtex'.

/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.000
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.001
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.002
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.003


lineurl.txt.000
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.004
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.005


lineurl.txt.001


lineurl.txt.002
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.006
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.007
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.008


lineurl.txt.004


lineurl.txt.003
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.009


lineurl.txt.008


lineurl.txt.005


lineurl.txt.007


lineurl.txt.006


lineurl.txt.009
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.010


lineurl.txt.010
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.000


startline.txt.000
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.001


startline.txt.001
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.002


startline.txt.002
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.003


startline.txt.003
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.004


startline.txt.004
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.005


startline.txt.005
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.006


startline.txt.006
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.007


startline.txt.007
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.008


startline.txt.008
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.009


startline.txt.009
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun startline.txt.010


startline.txt.010
No errors, hooray!

10个线程 压测性能

2g2c 本地拉起的虚拟机

10mins迁移完成
在这里插入图片描述

 ]# bash -x mig-v2.sh
+ set -e
+ set -o pipefail
+++ dirname mig-v2.sh
++ cd .
++ pwd
++ basename mig-v2.sh
+ SCRIPT=/opt/redis-mig/redis_key_mig/mig-v2.sh
+ JOBS=1
++ pwd
+ ERRORS=/opt/redis-mig/redis_key_mig/errors
++ pwd
+ INFO=/opt/redis-mig/redis_key_mig/info
+ echo

+ echo

+ run
+ args=
+ f=
+ [[ '' == '' ]]
+ main ''
+ IFS='
'
+ mapfile -t files
++ find ./ -name 'st*.txt.*' -o -name 'line*.txt.*'
++ sed 's|./||'
++ sort
+ unset IFS
+ echo

+ echo 'Running in parallel with 1 jobs.'
Running in parallel with 1 jobs.
+ parallel --tag --verbose --ungroup -j1 /opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun '{1}' ::: lineurl.txt.000 lineurl.txt.001 lineurl.txt.002 lineurl.txt.003 lineurl.txt.004 lineurl.txt.005 lineurl.txt.006 lineurl.txt.007 lineurl.txt.008 lineurl.txt.009 lineurl.txt.010 startline.txt.000 startline.txt.001 startline.txt.002 startline.txt.003 startline.txt.004 startline.txt.005 startline.txt.006 startline.txt.007 startline.txt.008 startline.txt.009 startline.txt.010
Academic tradition requires you to cite works you base your article on.
When using programs that use GNU Parallel to process data for publication
please cite:

  O. Tange (2011): GNU Parallel - The Command-Line Power Tool,
  ;login: The USENIX Magazine, February 2011:42-47.

This helps funding further development; AND IT WON'T COST YOU A CENT.
If you pay 10000 EUR you should feel free to use GNU Parallel without citing.

To silence the citation notice: run 'parallel --bibtex'.

/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.000


lineurl.txt.000
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.001


lineurl.txt.001
/opt/redis-mig/redis_key_mig/mig-v2.sh dockerrun lineurl.txt.002

参考

GNU_Parallel_2018.pdf

https://www.gnu.org/software/parallel/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/343183.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

98年的确实卷,公司新来的卷王,我们这帮老油条真干不过.....

都说00后躺平了&#xff0c;但是有一说一&#xff0c;该卷的还是卷。这不&#xff0c;前段时间我们公司来了个00后&#xff0c;工作没两年&#xff0c;跳槽到我们公司起薪18K&#xff0c;都快接近我了。后来才知道人家是个卷王&#xff0c;从早干到晚就差搬张床到工位睡觉了。 …

电脑麦克风没声音怎么办?这3招就可以解决!

最近有用户在使用电脑麦克风进行视频录制时&#xff0c;发现麦克风没有声音。这是什么原因&#xff1f;电脑麦克风没有声音怎么办&#xff1f;关于解决方案&#xff0c;我专门整理了三种方法来帮你们&#xff0c;一起来看看吧&#xff01; 操作环境&#xff1a; 演示机型&#…

在TitanIDE中使用ChatGPT辅助科研开发

作者&#xff1a;行云创新CEO 马洪喜 命题&#xff1a;太空望远镜拍摄的照片处理 假设&#xff1a;我是图形科学家&#xff0c;但不是特别懂Python 先上传一张银河系照片&#xff0c;目的是把彩色转成灰度&#xff1a; 然后我不会啊&#xff0c; 问问chatGPT 彩色图片转灰度…

电话号码的字母组合-力扣17-java

一、题目描述给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。示例 1&#xff1a;输入&#xff1a;digits "23"输出…

Android 一体机研发之修改系统设置————自动锁屏

Android 一体机研发之修改系统设置————屏幕亮度 Android 一体机研发之修改系统设置————声音 Android 一体机研发之修改系统设置————自动锁屏 修改系统设置系列篇章马上开张了&#xff01; 本章将为大家细节讲解自动锁屏。 自动锁屏功能&#xff0c;这个可以根据…

简述springIOC容器的bean加载流程

参考笔记:https://blog.51cto.com/u_14006572/3118363 https://zhuanlan.zhihu.com/p/386335813 https://blog.csdn.net/mrathena/article/details/115654379 目录结构 spring ioc容器的加载&#xff0c;大体上经过以下几个过程&#xff1a; 资源文件定位、解析、注册、实例化…

UWA Pipeline 2.4.1 版本更新说明

UWA Pipeline是一款面向游戏开发团队的本地协作平台&#xff0c;旨在为游戏开发团队搭建专属的DevOps研发交付流水线&#xff0c;提供可视化的CICD操作界面、高可用的自动化测试以及UWA性能保障服务的无缝贴合等实用功能。 在本次UWA Pipeline 2.4.1版本更新中&#xff0c;主要…

PIL.Image与cv2之间的常用API汇总

简单介绍 主要是因为经常用到这两个&#xff0c;经常弄混淆&#xff0c;所以&#xff0c;总结一番。持续更新。 from PIL import Image import cv2 as cv import numpy as np import matplotlib.pyplot as plt1、读取文件与写入文件 1.1 Image.open() img_pil Image.open…

电商数据监测——中国白酒行业数据浅析

大国盛世酿,万家潭酒香。中国白酒是中国特色文化之一。 2022年&#xff0c;国内白酒总产量为671.2万千升&#xff0c;处于持续下滑的态势。 白酒产量不佳&#xff0c;但线上平台的销售情况却成绩优异。2022年&#xff0c;京东平台白酒的年度总销量超3500万件&#xff0c;同比去…

操作系统开发:编写开机引导

操作系统是用来管理与协调硬件工作的&#xff0c;开发一款操作系统有利于理解底层的运转逻辑&#xff0c;本篇内容主要用来理解操作系统是如何启动的&#xff0c;又是如何加载磁盘中的内核的&#xff0c;该系列文章参考各类底层书籍&#xff0c;通过自己的理解并加以叙述&#…

彻底理解 cookie、session、token (一)

发展史 1、很久很久以前&#xff0c;Web 基本上就是文档的浏览而已&#xff0c; 既然是浏览&#xff0c;作为服务器&#xff0c; 不需要记录谁在某一段时间里都浏览了什么文档&#xff0c;每次请求都是一个新的HTTP协议&#xff0c; 就是请求加响应&#xff0c; 尤其是我不用记…

阿里巴巴在开源压测工具 JMeter 上的实践和优化

Apache JMeter [1] 是 Apach 旗下的开源压测工具&#xff0c;创建于 1999 年初&#xff0c;迄今已有超过 20 年历史。JMeter 功能丰富&#xff0c;社区&#xff08;用户群体&#xff09;庞大&#xff0c;是主流开源压测工具之一。 性能测试通常集中在新系统上线或大型活动前&…

l1和l2接口如何进行编写?一定要掌握这几个元素

在这个大数据时代&#xff0c;很多地方都需要用到l1和l2接口&#xff0c;l1和l2接口在应用程序与数据库之间起着桥梁的作用&#xff0c;是实现数据的整合与共享的重要帮手。 l1和l2接口适用于各行各业&#xff0c;应用场景的不断拓展&#xff0c;l1和l2接口的发展也兴起&#…

浏览器广告拦截插件| 浏览器搜索广告横飞怎么办

文章目录浏览器广告拦截插件| 浏览器搜索广告横飞怎么办一、效果二、安装浏览器广告拦截插件| 浏览器搜索广告横飞怎么办 浏览器广告横飞怎么办&#xff1f;今天教你一招解决&#xff01;很多小伙伴说自己用的浏览器总是有广告。 今天咱们就针对这个问题分享一个浏览器插件&a…

【面试题】JavaScript中递归的理解

大厂面试题分享 面试题库后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★地址&#xff1a;前端面试题库递归 RecursionTo iterate is human, to recurse, divine. 理解迭代&#xff0c;神理解递归。本文会以 JavaScript为主、有部分 Rust 举例说明。…

【python--networkx】函数说明+代码讲解

【Python–NetworkX】函数说明代码讲解 文章目录【Python--NetworkX】函数说明代码讲解1. 介绍1.1 前言1.2 图的类型&#xff08;Graph Types&#xff09;1.3 常用方法2. 代码示例1. 介绍 1.1 前言 NetworkX是复杂网络研究领域中的常用Python包。 1.2 图的类型&#xff08;G…

Linux高级命令之文件权限命令

文件权限命令学习目标能够使用chmod命令完成文件权限的修改1. chmod命令的介绍命令说明chmod修改文件权限chmod修改文件权限有两种方式:字母法数字法2. chmod 字母法的使用角色说明:角色说明uuser, 表示该文件的所有者ggroup, 表示用户组oother, 表示其他用户aall, 表示所有用户…

[carla]关于odometry坐标中的角度坐标系 以及 到地图的映射问题

1.获取车辆的Odometry原始信息 在carla中&#xff0c;通过订阅/carla/ego_vecle/odometry 可以查看车辆的全局位置信息,例如&#xff1a; > header: seq: 118872stamp: secs: 5946nsecs: 5720187frame_id: "map" child_frame_id: "ego_vehicle" pos…

替换子串得到平衡字符串[map计数+滑动窗口]

滑动窗口前言一、替换子串得到平衡字符串二、map计数滑动窗口总结参考文献前言 对于子串问题&#xff0c;确定左边界和有边界&#xff0c;就能确定一个子串&#xff0c;暴力取子串&#xff0c;时间复杂度O(n2)。有时挖掘内在规律的限定&#xff0c;或者问题所限定&#xff0c;…

Vue笔记(1)——数据代理与绑定

一、初始Vue 1.想让Vue工作&#xff0c;就必须创建一个Vue实例&#xff0c;且要传入一个配置对象&#xff1b; 2.root容器里的代码依然符合html规范&#xff0c;只不过混入了一些特殊的Vue语法&#xff1b; 3.root容器里的代码被称为【Vue模板】&#xff1b; 4.Vue实例和容器是…