В связи с тем, что на современных машинах стоят многоядерные камни и в linux есть прекрасная возможность использовать контейнеры lxc или systemd-nspawn, - можно значительно ускорить решение трудоёмких задач. Например - стендовая модель ниже! Есть задача - найти какие-то текстовые данные в другом большом массиве текстовых данных, т.е. найти позиции из файла search.txt в файле catalogue.txt По простому это аналогично: grep -f search.txt catalogue.txt Но долго. Мы будем делать быстро. Для этого сделаем такой алгоритм с помощью "gnu parallel": 1. (Уже) Будем иметь настроенными несколько нод - узлов: физических или виртуальных. 2. Разобъем файл search.txt на столько частей, сколько у нас нод (или больше) 3. На каждую ноду автоматически положим каталог catalogue.txt и ту часть файла search.txt, которую требуется "найти" 4. Запустим параллельный поиск и после его окончания - автоматически соберём результаты в один файл на "центральной" ноде. Итого у нас будет 5 файлов bash: s0-tash.sh - главный скрипт, который мы запускаем на "главной" машине. s1-split.sh - скрипт, который делит файл задачу search.txt на части s2-send.sh - скрипт, который параллельно отправляет части search.txt на ноды s3-job.sh - скрипт, который запускается параллельно на каждой ноде и выполняет поиск s4-receive.sh - скрипт, который параллельно забирает результаты с нод и собирает в один файл Дальше - коды. ------------------------------------------------- # s0-task.sh # Центральный блок управления всем # У нас 2 контейнера: .0.2 и .0.3 ------------------------------------------------- #!/bin/bash srv_cnt=2 srv="-S test@192.168.0.2 -S test@192.168.0.3" echo SPLIT ./s1-split.sh echo SEND TASK parallel -j2 ./s2-send.sh '{%}' '{}' ::: prt-* echo RUN NODE TASKS seq $srv_cnt | parallel -n0 -j2 $srv ./s3-job.sh '{%}' echo RECEIVE RESULT seq $srv_cnt | parallel -j2 ./s4-receive.sh '{%}' echo CLEAN seq $srv_cnt | parallel -n0 -j2 $srv 'rm res-*' seq $srv_cnt | parallel -n0 -j2 $srv 'rm prt-*' cat res-* > result.txt rm res-* rm prt-* ------------------------------------------------- # s1-split.sh # Разбиваем файл на части по 1000 строк ------------------------------------------------- #!/bin/bash split -l 1000 search.txt prt- ------------------------------------------------- # s2-send.sh # Отправляем каталог, скрипт-искатель и какую-то часть search.txt на ноды # Номер ноды и часть для отправки - приходят на входе ------------------------------------------------- #!/bin/bash n="$1" f="$2" s1="192.168.0.2" s2="192.168.0.3" if [ "$n" != "" ] then echo "send: $n" if [ $n -ge 1 ] && [ $n -le 2 ] then eval srv=\${s$n} scp catalogue.txt test@$srv:~ scp s3-job.sh test@$srv:~ scp "$f" test@$srv:~ fi fi ------------------------------------------------- # s3-job.sh # Скрипт - выполнитель кусочка задачи на ноде # - копируется на ноду вместе с заданием ------------------------------------------------- #!/bin/bash ls prt-* > list while read wc do echo "NODE: $HOSTNAME $wc" while read -r a do printf -v x "%q" "$a" agrep -n -B "$x" catalogue.txt | head -n 1 >> res-$wc done < $wc done < list rm list ------------------------------------------------- # s4-receive.sh # Скрипт, собирающий результаты с нод # Номер ноды приходит на вход ------------------------------------------------- #!/bin/bash n="$1" s1="192.168.0.2" s2="192.168.0.3" if [ "$n" != "" ] then echo "receive: $n" if [ $n -ge 1 ] && [ $n -le 2 ] then eval srv=\${s$n} scp test@$srv:~/res-* . fi fi ------------------------------------------------- Для того, чтобы эта задача работала - конечно нужно настроить ноды (LXC) и разрешить к ним доступ по ключам (RSA) с помощью "ssh-copy-id" Главный фокус состоит в том, что с помощью lxc-copy мы в один момент можем наклонировать столько нод, сколько нам нужно, раскидать их по всем доступным серверам и по всем доступным ядрам - и за 10 минут сделать хоть 100 нод, решающих большие задачи параллельно - а значит быстро, очень быстро. #eof
Linux/Windows Справочник v0.05 © 2007-2024 Igor Salnikov aka SunDoctor