Bash: распаралельванне md5sum Кантрольная сума на шматлікіх файлах

дазваляе сказаць, у мяне ёсць 64-ядзерны сервер, і мне трэба вылічыць md5sum усе файлы ў /MNT/дадзеных і захаваць вынікі ў тэкставым файле:

find /mnt/data -type f -exec md5sum {} \; > md5.txt

Праблема з прыведзенымі вышэй камандамі ў тым, што толькі адзін працэс запускаецца ў любы момант часу. Я хацеў бы выкарыстаць усю моц маіх 64-ядраў. У ідэале, я хацеў бы пераконваецца, што ў любы момант часу, 64 паралельна md5 выкананых працэсаў (але не больш за 64).

Акрамя таго. Я павінен быў бы выхад з усіх працэсаў, якія будуць захоўвацца ў адным файле.

Заўвага: Я не шукаю спосаб, каб вылічыць md5sum аднаго файла паралельна. Я шукаю спосаб, каб вылічыць 64 md5sums з 64 розных файлаў паралельна, да таго часу, пакуль якія-небудзь файлы, якія паступаюць з знайсці .

13
Я зацікаўлены ў абагульненым адказ. Калі md5sum занадта хутка для вас (каля 90МБ/с), чым адчуваць сябе свабодна замяніць любы павольны алгарытм (ХГ выявы 5 МБ/с). Гэта не нерэальна выказаць здагадку, што хуткасць чытання з/MNT/дадзеныя могуць быць 500Mb/s (г.зн. доля NFS па сетцы 10Gb або SSD-дыск)
дададзена аўтар user1968963, крыніца
Я зацікаўлены ў абагульненым адказ. Калі md5sum занадта хутка для вас (каля 90МБ/с), чым адчуваць сябе свабодна замяніць любы павольны алгарытм (ХГ выявы 5 МБ/с). Гэта не нерэальна выказаць здагадку, што хуткасць чытання з/MNT/дадзеныя могуць быць 500Mb/s (г.зн. доля NFS па сетцы 10Gb або SSD-дыск)
дададзена аўтар user1968963, крыніца
@Alfe: ядро ​​ўсё роўна прыйдзецца атрымліваць дадзеныя <�я> у RAM, таму вузкае месца застаецца.
дададзена аўтар Fred Foo, крыніца
@Alfe: ядро ​​ўсё роўна прыйдзецца атрымліваць дадзеныя <�я> у RAM, таму вузкае месца застаецца.
дададзена аўтар Fred Foo, крыніца
Я не ўпэўнены, што гэта будзе добра. Я мог сабе ўявіць, што матэрыял становіцца IO звязаны вельмі хутка, і што з дапамогай 64 працэсаў прывядзе да slooow IO, маючы шмат ядраў бяздзейнічаць, тым не менш.
дададзена аўтар glglgl, крыніца
Я не ўпэўнены, што гэта будзе добра. Я мог сабе ўявіць, што матэрыял становіцца IO звязаны вельмі хутка, і што з дапамогай 64 працэсаў прывядзе да slooow IO, маючы шмат ядраў бяздзейнічаць, тым не менш.
дададзена аўтар glglgl, крыніца
У выпадку, калі дадзеныя ўжо знаходзіцца ў аператыўнай памяці (лічаць буйныя серверы з 96 ГБ, напрыклад АЗП), якія, магчыма, ужо адбылося.
дададзена аўтар Alfe, крыніца
У выпадку, калі дадзеныя ўжо знаходзіцца ў аператыўнай памяці (лічаць буйныя серверы з 96 ГБ, напрыклад АЗП), якія, магчыма, ужо адбылося.
дададзена аўтар Alfe, крыніца
Але з іншага боку, сучасныя файлавыя сістэмы кэшуюцца шмат у аператыўнай памяці, таму выкарыстанне больш чым адзін у той час, мае сэнс.
дададзена аўтар Alfe, крыніца
Але з іншага боку, сучасныя файлавыя сістэмы кэшуюцца шмат у аператыўнай памяці, таму выкарыстанне больш чым адзін у той час, мае сэнс.
дададзена аўтар Alfe, крыніца
Калі ОП патрабуецца рашэнне для паралельнай працы, чаму хто-то пачаць казаць пра «няправільнай ідэі»? Можа быць, ён проста хоча праверыць I/O-вузкім месцам ці нешта ... Проста не разумею тых, <�я> ведае ўсё лепш карыстальнікаў ... ( urbandictionary.com/… )
дададзена аўтар novacik, крыніца
Калі ОП патрабуецца рашэнне для паралельнай працы, чаму хто-то пачаць казаць пра «няправільнай ідэі»? Можа быць, ён проста хоча праверыць I/O-вузкім месцам ці нешта ... Проста не разумею тых, <�я> ведае ўсё лепш карыстальнікаў ... ( urbandictionary.com/… )
дададзена аўтар novacik, крыніца

8 адказы

Выкарыстоўвайце GNU паралельны . І вы можаце знайсці яшчэ некалькі прыкладаў пра тое, як рэалізаваць гэта .

find /mnt/data -type f | parallel -j 64 md5sum > md5.txt
17
дададзена
Я не ведаю, GNU паралельна. Дзякуй за любое яго. Я павінен убачыць, калі гэта карысна ў маім выпадку, хоць. На дадзены момант Час пошуку/мнт/дадзеныя тыпу F | паралельнае -j 16 md5sum> md5.txt складае каля 3 раз павольней, чым звычайныя знаходкі час пошуку/USR/акцыю тыпу F -exec md5sum {} \; > Md5.txt .
дададзена аўтар user1968963, крыніца

Выкарыстоўвайце GNU паралельны . І вы можаце знайсці яшчэ некалькі прыкладаў пра тое, як рэалізаваць гэта .

find /mnt/data -type f | parallel -j 64 md5sum > md5.txt
17
дададзена
Я не ведаю, GNU паралельна. Дзякуй за любое яго. Я павінен убачыць, калі гэта карысна ў маім выпадку, хоць. На дадзены момант Час пошуку/мнт/дадзеныя тыпу F | паралельнае -j 16 md5sum> md5.txt складае каля 3 раз павольней, чым звычайныя знаходкі час пошуку/USR/акцыю тыпу F -exec md5sum {} \; > Md5.txt .
дададзена аўтар user1968963, крыніца

Калі вы хочаце паэксперыментаваць паспрабаваць ўсталяваць md5deep . ( http://md5deep.sourceforge.net )

Here is the manual where you can read:

<�Р> -jnn кіравання шматструменнасць. Па змаўчанні праграма стварае адзін вытворца нітку для сканавання файлавай сістэмы і адзін хэшавання паток на CPU   ядро. Шматструменнасць выклікае выходныя імёны файлаў, каб быць у   недетерминирована парадак, бо файлы, якія займаюць больш часу, каб хэш будзе   затрымліваецца, пакуль яны хэшируются. Калі патрабуецца дэтэрмінаваных парадак,   пазначыць -j0 адключыць шматструменнасць

Калі гэта не дапамагае, то ёсць вузкія месцы ўводу/высновы.

6
дададзена

Калі вы хочаце паэксперыментаваць паспрабаваць ўсталяваць md5deep . ( http://md5deep.sourceforge.net )

Here is the manual where you can read:

<�Р> -jnn кіравання шматструменнасць. Па змаўчанні праграма стварае адзін вытворца нітку для сканавання файлавай сістэмы і адзін хэшавання паток на CPU   ядро. Шматструменнасць выклікае выходныя імёны файлаў, каб быць у   недетерминирована парадак, бо файлы, якія займаюць больш часу, каб хэш будзе   затрымліваецца, пакуль яны хэшируются. Калі патрабуецца дэтэрмінаваных парадак,   пазначыць -j0 адключыць шматструменнасць

Калі гэта не дапамагае, то ёсць вузкія месцы ўводу/высновы.

6
дададзена

Вы можаце выкарыстоўваць xargs, а, можа быць больш даступным, чым паралелі на некаторых дыстрыбутывах.

-P кантралюе колькасць працэсу спарадзіў.

find /mnt/data -type f | xargs -L1 -P24  md5sum > /tmp/result.txt
6
дададзена
Цяпер гэты адказ атрымаў так шмат увагі: давайце вярнуць каментар ад іншага аддаленага адказу тут: «Гэта будзе FAIL пісаць адначасова з многіх патокаў у адзін файл будзе генераваць пашкоджаны файл Калі ласка, не выкарыстоўвайце яго ў мяне дакладна праблема! (!) .. у маім выпадку -. ******** 21 '14 сакавіка ў 06:49 "
дададзена аўтар Tensibai, крыніца
Вы можаце выявіць, што пры выкарыстанні больш высокіх значэнняў на -L паляпшае прадукцыйнасць разгалінавання менш працэсаў (md5sum можа заняць некалькі файлаў з каманднага радка). Дарэчы, шматразовы працэс можа напісаць той жа (лакальны) файл, калі ўсе яны выкарыстоўваюць конкатенирующий рэжым і разважны схема буферызацыі (напрыклад, лінейны буфер). Паняцця не мае, калі md5 [сума] з'яўляецца такім працэсам. У якасці альтэрнатывы запіс некалькіх файлаў і аб'яднаць у канцы.
дададзена аўтар John Hascall, крыніца
@OlafM я ўсталяваў гэтае пытанне ўжо, як вы можаце бачыць.
дададзена аўтар Braiam, крыніца
@OlafM так, я казаў пра амартызуемага сцягу. Я хацеў захаваць функцыянальнасць мудры той жа адказ. Паводзіны знаходкі б гэтая праблема да таго, як сцяг быў амартызуецца, тым не менш.
дададзена аўтар Braiam, крыніца
@Braiam гэта яшчэ не будзе працаваць з імёнамі файлаў, якія змяшчаюць прабелы. Тыя, у прыватнасці, неабходна «-print0» і «-0», каб падзяліць выхад не ў адпаведнасці з прабеламі (патэнцыйна ў межах імёнаў файлаў), але ў адпаведнасці з нулявымі Гольца.
дададзена аўтар FarO, крыніца
Прадастаўлены адказ не з'яўляецца на працы, калі імёны файлаў ўтрымліваюць прабелы. Правільны адзін заключаецца ў наступным, а таксама з выкарыстаннем POSIX перамыкачоў: «знайсці/мнт/дадзеныя тыпу F -print0 | xargs -L1 -P24 -0 md5> /tmp/result.txt» Вы таксама можаце выкарыстоўваць опцыю - г для md5 для зваротнага вываду і атрымаць кантрольную суму дО шляху, так што вы можаце замовіць па кантрольнай суме і лёгка знаходзіць дублікаты.
дададзена аўтар FarO, крыніца

Вы можаце выкарыстоўваць xargs, а, можа быць больш даступным, чым паралелі на некаторых дыстрыбутывах.

-P кантралюе колькасць працэсу спарадзіў.

find /mnt/data -type f | xargs -L1 -P24  md5sum > /tmp/result.txt
6
дададзена
Цяпер гэты адказ атрымаў так шмат увагі: давайце вярнуць каментар ад іншага аддаленага адказу тут: «Гэта будзе FAIL пісаць адначасова з многіх патокаў у адзін файл будзе генераваць пашкоджаны файл Калі ласка, не выкарыстоўвайце яго ў мяне дакладна праблема! (!) .. у маім выпадку -. ******** 21 '14 сакавіка ў 06:49 "
дададзена аўтар Tensibai, крыніца
Вы можаце выявіць, што пры выкарыстанні больш высокіх значэнняў на -L паляпшае прадукцыйнасць разгалінавання менш працэсаў (md5sum можа заняць некалькі файлаў з каманднага радка). Дарэчы, шматразовы працэс можа напісаць той жа (лакальны) файл, калі ўсе яны выкарыстоўваюць конкатенирующий рэжым і разважны схема буферызацыі (напрыклад, лінейны буфер). Паняцця не мае, калі md5 [сума] з'яўляецца такім працэсам. У якасці альтэрнатывы запіс некалькіх файлаў і аб'яднаць у канцы.
дададзена аўтар John Hascall, крыніца
@OlafM я ўсталяваў гэтае пытанне ўжо, як вы можаце бачыць.
дададзена аўтар Braiam, крыніца
@OlafM так, я казаў пра амартызуемага сцягу. Я хацеў захаваць функцыянальнасць мудры той жа адказ. Паводзіны знаходкі б гэтая праблема да таго, як сцяг быў амартызуецца, тым не менш.
дададзена аўтар Braiam, крыніца
@Braiam гэта яшчэ не будзе працаваць з імёнамі файлаў, якія змяшчаюць прабелы. Тыя, у прыватнасці, неабходна «-print0» і «-0», каб падзяліць выхад не ў адпаведнасці з прабеламі (патэнцыйна ў межах імёнаў файлаў), але ў адпаведнасці з нулявымі Гольца.
дададзена аўтар FarO, крыніца
Прадастаўлены адказ не з'яўляецца на працы, калі імёны файлаў ўтрымліваюць прабелы. Правільны адзін заключаецца ў наступным, а таксама з выкарыстаннем POSIX перамыкачоў: «знайсці/мнт/дадзеныя тыпу F -print0 | xargs -L1 -P24 -0 md5> /tmp/result.txt» Вы таксама можаце выкарыстоўваць опцыю - г для md5 для зваротнага вываду і атрымаць кантрольную суму дО шляху, так што вы можаце замовіць па кантрольнай суме і лёгка знаходзіць дублікаты.
дададзена аўтар FarO, крыніца

<�Моцны> АБНОЎЛЕНА

Калі Вы не хочаце выкарыстоўваць дадатковыя пакеты можна паспрабаваць SG, як гэта:

#!/usr/bin/bash

max=5;
cpid=()

# Enable job control to receive SIGCHLD
set -m
remove() {
  for i in ${!cpid[*]}; do
    [ ! -d /proc/$i ] && echo UNSET $i && unset cpid[$i] && break
  done
}
trap remove SIGCHLD

for x in $(find ./ -type f -name '*.sh'); do
  some_long_process $x&
  cpid[$!]="$x";
  while [ ${#cpid[*]} -ge $max ]; do
    echo DO SOMETHING && sleep 1;
  done
done
wait

Гэта першае дазваляе атрымаць SIGCHLD, калі Подпроцесса выхадаў. Калі SIGCHLD ён знаходзіць першы неіснуючы працэс і выдаляе з CPID масіў.

У для цыклу ён пачынае макс лік some_long_process працэсы асінхронна. Гэта тах дасягнуў яна апытвае ўсе ПИДы дададзеныя CPID масіў. Ён чакае, пакуль CPID даўжыня 's не менш тах і пачынае яшчэ некаторыя працэсы асінхронна.

Калі спіс сканчаецца, то ён чакае ўсіх дзяцей, каб скончыць.

<�Моцны> ADDED

Finally I have found a proper solution here.

1
дададзена
Дзякуй за сцэнар. На жаль, гэта не прыносіць ніякага паляпшэння. Сапраўды, час больш, чым проста знаходка. Акрамя таго, большасць з ядраў, здаецца незанятае. Я павінен буду эксперыментаваць, калі я магу Твік яго.
дададзена аўтар user1968963, крыніца
@ User1968963: Можа быць, сон 1 лінія можа быць выдаленая. Гэта будзе залішне нагрузіць адно ядро. Паспрабуйце гэты спосаб. Можа быць, вы маглі б палепшыць трохі, выкарыстоўваючы знайсці/MNT/-type дадзеных е -exec md5sum {} +> md5.txt . Майце на ўвазе канцавая + замест ! Гэта будзе выклікаць md5sum значна меншая колькасць разоў. (Глядзі -exec каманду {} + у знайсці (1) </а>).
дададзена аўтар TrueY, крыніца

<�Моцны> АБНОЎЛЕНА

Калі Вы не хочаце выкарыстоўваць дадатковыя пакеты можна паспрабаваць SG, як гэта:

#!/usr/bin/bash

max=5;
cpid=()

# Enable job control to receive SIGCHLD
set -m
remove() {
  for i in ${!cpid[*]}; do
    [ ! -d /proc/$i ] && echo UNSET $i && unset cpid[$i] && break
  done
}
trap remove SIGCHLD

for x in $(find ./ -type f -name '*.sh'); do
  some_long_process $x&
  cpid[$!]="$x";
  while [ ${#cpid[*]} -ge $max ]; do
    echo DO SOMETHING && sleep 1;
  done
done
wait

Гэта першае дазваляе атрымаць SIGCHLD, калі Подпроцесса выхадаў. Калі SIGCHLD ён знаходзіць першы неіснуючы працэс і выдаляе з CPID масіў.

У для цыклу ён пачынае макс лік some_long_process працэсы асінхронна. Гэта тах дасягнуў яна апытвае ўсе ПИДы дададзеныя CPID масіў. Ён чакае, пакуль CPID даўжыня 's не менш тах і пачынае яшчэ некаторыя працэсы асінхронна.

Калі спіс сканчаецца, то ён чакае ўсіх дзяцей, каб скончыць.

<�Моцны> ADDED

Finally I have found a proper solution here.

1
дададзена
Дзякуй за сцэнар. На жаль, гэта не прыносіць ніякага паляпшэння. Сапраўды, час больш, чым проста знаходка. Акрамя таго, большасць з ядраў, здаецца незанятае. Я павінен буду эксперыментаваць, калі я магу Твік яго.
дададзена аўтар user1968963, крыніца
@ User1968963: Можа быць, сон 1 лінія можа быць выдаленая. Гэта будзе залішне нагрузіць адно ядро. Паспрабуйце гэты спосаб. Можа быць, вы маглі б палепшыць трохі, выкарыстоўваючы знайсці/MNT/-type дадзеных е -exec md5sum {} +> md5.txt . Майце на ўвазе канцавая + замест ! Гэта будзе выклікаць md5sum значна меншая колькасць разоў. (Глядзі -exec каманду {} + у знайсці (1) </а>).
дададзена аўтар TrueY, крыніца