我有大量文件,每个文件将被解码,排序/最小化,然后放入数据库。每个操作都有自己的bash脚本。这些文件被分类到每日文件中,这些文件位于连续的每月文件夹中。问题是只有一个数据库,只有一个表(SQLite),所以数据库脚本当时只能在一个文件上运行,而解码和排序可以同时在大约四个文件上完成。
对于要排序的文件,必须通过解码过程,要将文件放入数据库,必须对其进行解码和排序。这些脚本的运行时间不一样,我相信解码是空腹,然后是输入然后是排序。
每个bash脚本decode.sh
sort.sh
saveintodb.sh
遍历文件夹中的所有文件并完成其工作。
最初我认为有一个执行decode.sh
- >的masterscript。 sort.sh
- > saveintodb.sh
对于每个文件夹(月份)。
然而,由于预计这需要几天时间,我想到了这样的事情:
1: decode.sh January
2: sort.sh January, decode.sh February
3: saveintodb.sh January sort.sh February decode.sh March
4: saveintodb.sh February sort.sh March decode.sh April
等到12月。
然而,我不知道我是如何设置它的,这是一个好方法。我知道我可以在2:
并行运行脚本,但是我不太确定如何运行脚本3:2:完成后自动运行。
我也不确定这是否是最好的方法。理想情况下,有一个解码脚本,一个排序脚本和一个始终运行的saveintodb脚本。甚至可能是几个解码和排序脚本(不知道如果这会加快这个过程,我很遗憾地在外部HD上工作)。
数据量: 1.3 TB
数据类型:文本文件
背景:位置报告(纬度/经度,时间)
对不起这篇长文,有什么建议吗?
答案 0 :(得分:5)
在Linux上,使用crontab(5)来安排各种shell脚本。它们可以并行运行。
您也可以查看GNU parallel,但我猜您不需要它。
最后,shell脚本可以使用at或batch
安排另一个脚本。例如,decode.sh
可能以batch -f sort.sh
或at -f sort.sh now + 10 minutes
您可以使用更强大的脚本语言,例如Python,Guile,Perl,....
BTW;,一定要测试每个脚本(甚至是其中的部分)的成功。使用logger(1)发出日志消息(可能在每个步骤或命令之后持续超过半小时,以及每个脚本的开始和结束)。每天检查日志!
最后,我不明白为什么一次只能运行一个数据库脚本。大多数真正的DBMS(PostGreSQL,MonGoDB,MariaDB等) - 但不是sqlite - 可以运行(或配置为运行)多个数据库客户端同时访问同一个数据库(当然还有不同的数据库)。阅读有关ACID属性的更多信息。
在某些外部USB硬盘上执行此操作是恕我直言,因为此类硬件的可靠性有限(而且通常很慢)。你应该考虑使用一些服务器(也许一个好的桌面可能有这样的角色)。您可能需要UPS来避免电源故障。
如果这个复杂的处理和处理过的数据对你有一些价值,你应该升级两个硬件(获得一台服务器机器,可能带有UPS和ECC RAM,如果数据适合,则{{3和软件(使用真正的DBMS,关心失败)。估算失败和/或数据丢失的成本(记住要考虑到你的时间)。也许租用一些云计算或存储可能很有意思(或者只是一个带有备份的SSD托管Linux系统,你可以每月获得一个大约两十几美元或欧元:VPS,{{3} },kimsufi,ovh,...)...
答案 1 :(得分:2)
您可以拥有两个脚本,一个具有for循环并进行解码和排序,并创建一个由另一个脚本用作标志的文件。 另一个脚本将在while循环中检查这些文件,并在它们到来时将它们放入数据库中。 脚本1
function decodeAndSort{
decode.sh $1
sort.sh $1
touch ./tmpDir/$1
}
for month in months
do
decodeAndSort $month & # the ampersand is to run in the background
done
脚本2
array=bla #with names of files
while [[ $count -lt 12 ]]
do
if [[ -e ./tmpDir/${array[$count]} ]] #test file exists
saveintodb.sh ${array[$count]}
rm ./tmpDir/${array[$count]} # clear the flag
(( count++ ))
else
sleep 1 # adjust this as necesary
fi
done
答案 2 :(得分:1)
使用GNU Parallel看起来像这样:
doit() {
sem --id decode decode.sh $1
sem --id sort sort.sh $1
sem --id dbsave saveintodb.sh $1
}
export -f doit
parallel -j4 doit {} ::: Jan Feb Mar ...
这将确保您一次运行单个解码,排序和saveintodb。如果您只想保护saveintodb:
doit() {
decode.sh $1
sort.sh $1
sem --id dbsave saveintodb.sh $1
}
export -f doit
parallel -j4 doit {} ::: Jan Feb Mar ...
在这里,您将运行4个解码/排序但只有一个saveintodb。
sem
是GNU Parallel的一部分。
GNU Parallel是一个通用的并行程序,可以很容易地在同一台机器上或在你有ssh访问权限的多台机器上并行运行作业。它通常可以替换for
循环。
如果要在4个CPU上运行32个不同的作业,并行化的直接方法是在每个CPU上运行8个作业:
GNU Parallel会在完成后生成一个新进程 - 保持CPU处于活动状态,从而节省时间:
<强>安装强>
如果没有为您的发行版打包GNU Parallel,您可以进行个人安装,不需要root访问权限。这可以在10秒内完成:
(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash
有关其他安装选项,请参阅http://git.savannah.gnu.org/cgit/parallel.git/tree/README
了解详情
查看更多示例:http://www.gnu.org/software/parallel/man.html
观看介绍视频:https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
完成教程:http://www.gnu.org/software/parallel/parallel_tutorial.html
注册电子邮件列表以获得支持:https://lists.gnu.org/mailman/listinfo/parallel