有很多时候,处理一个大文件,常规命令并不能很好的利用多核
例如,一个1T的文本,百亿条数据,我想要:
1
|
|
或者
1
|
|
一般机器就会自觉进入一核有难,其它核点赞
的看戏模式。
我花钱配了这么多核,加了这么多内存,不是让大家来看戏的。于是祭出parallel
~
原理
parallel 是一个perl脚本,通过分割输入,并行处理的方式来加速执行命令。
例如:
1
|
|
简单想想就是用个for循环split文件,挨个wc,然后相加。parallel就是自动帮你把这类事情做掉而已。大道不过两三行,所谓外部排序,Map-Reduce莫不如是。
安装 (ubuntu 16.04LTS)
1
|
|
示例
最快的办法计算一个大文件的行数
1
|
|
非常的巧妙,先使用parallel命令‘mapping’出大量的wc -l调用,形成子计算,最后通过管道发送给awk进行汇总
SED, 想在一个巨大的文件里使用sed命令做大量的替换操作吗?
常规做法:
1
|
|
现在你可以:
1
|
|
GREP 一个非常大的文本文件
以前你可能会这样:
1
|
|
现在你可以这样:
1
|
|
或者这样:
1
|
|
这第二种用法使用了 –block 10M参数,这是说每个内核处理1千万行——你可以用这个参数来调整每个CUP内核处理多少行数据。
压缩一个非常大的文件
bzip2是比gzip更好的压缩工具,但它很慢!别折腾了,我们有办法解决这问题。
以前的做法:
1
|
|
现在这样:
1
|
|
扩展
作为一个Python党,经常写一些用过即弃
的边角料脚本
比如最近要把一个1T的文件汉字全部转换为拼音,初版当然是这样的:
版本1
1 2 3 |
|
lazy_pinyin的效率奇慢无比,这回陷入了一核有难,其它核+内存+磁盘全部看戏模式
作为一个初级合格的Python开发人员,你当然说要用process,于是我们有了第二版:
版本2
1 2 3 4 5 6 |
|
嗯,很好,16个核都跑起来了;但是你有很快尴尬的发现,map把文件一把load进来,内存有难了
~~~~
作为一个初级合格的Python开发人员,你当然说不要一把读进来,要用chunk_read,一次读一块,或者更高级一点,直接用mmap映射进内存巴拉巴拉
少年,这还是那个边角料脚本吗,你已经在它上面操心一个小时了,还能不能愉快的玩耍了
让 parallel来拯救你
版本3
1 2 3 4 5 |
|
然后执行:
1
|
|
享受所有CPU满负荷运载的工头压榨工人的快感吧
一些扩展
- 为啥所有的parallel都带有一个奇怪的–no-notice?
嗯,虽然这个作者非常非常好,但是他总是在命令前面输出一些捐助提示;当然我并不是讨厌这种做法,但看多了总有些疲劳,你懂的~~
- 我有一些参数想传给程序,怎么办?
1
|
|
- 这个命令很好,但是语法好像啰嗦了一些,还有其它的替代命令吗?
嗯~ o( ̄▽ ̄)o,还是有的,xargs有个-n参数,类似的效果,不过功能弱化很多,基本上是鸡肋
参考:
手册:
https://www.gnu.org/software/parallel/parallel_tutorial.html
资料:
http://www.freeoa.net/osuport/sysadmin/use-gnu-parallel-multi-core-speed-up-cmd_2343.html
我的博客即将搬运同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1bnzu1pmog27t