Усиление поиска grep с использованием параллелизма GNU

Я думаю, что мы определили, что некоторые промежуточные серверы кэширования (, например, сервер в моем домашнем маршрутизаторе ), неохотно возвращают RFC1918 («частные» )адреса. Таким образом, короткие запросы, которые выполняет большинство программ (браузеры и т. д. ), будут использовать эти кеши, но сервер возвращает количество «не найдено». Таким образом, локальный сервер systemdкэширует запись NODATA, потому что считает, что это правильно.

Запрос ANYне кэшируется промежуточными серверами, поэтому локальный сервер получает ответ от авторитетного сервера.

Или что-то в этом роде. Я пока оставлю вопрос без ответа на тот случай, если кто-то, кто действительно знает, как эти вещи работают, сможет лучше объяснить.

2
24.01.2021, 21:26
3 ответа

Гораздо более эффективный ответ, не использующий grep:

build_k_mers() {
    k="$1"
    slot="$2"
    perl -ne 'for $n (0..(length $_)-'"$k"') {                                                                                               
       $prefix = substr($_,$n,2);                                                                                                            
       $fh{$prefix} or open $fh{$prefix}, ">>", "tmp/kmer.$prefix.'"$slot"'";                                                                
       $fh = $fh{$prefix};                                                                                                                   
       print $fh substr($_,$n,'"$k"'),"\n"                                                                                                   
    }'
}
export -f build_k_mers

rm -rf tmp
mkdir tmp
export LC_ALL=C
# search strings must be sorted for comm                                                                                                     
parsort patterns.txt | awk '{print >>"tmp/patterns."substr($1,1,2)}' &

# make shorter lines: Insert \n(last 12 char before \n) for every 32k                                                                         
# This makes it easier for --pipepart to find a newline                                                                                      
# It will not change the kmers generated                                                                                                     
perl -pe 's/(.{32000})(.{12})/$1$2\n$2/g' large_strings.txt > large_lines.txt
# Build 12-mers                                                                                                                              
parallel --pipepart --block -1 -a large_lines.txt 'build_k_mers 12 {%}'
# -j10 and 20s may be adjusted depending on hardware
parallel -j10 --delay 20s 'parsort -u tmp/kmer.{}.* > tmp/kmer.{}; rm tmp/kmer.{}.*' ::: `perl -e 'map { printf "%02x ",$_ } 0..255'`
wait
parallel comm -23 {} {=s/patterns./kmer./=} ::: tmp/patterns.??

Я протестировал это на полной работе(patterns.txt:9 ГБ/725937231 строк,large_strings.txt:19 ГБ/184 строки )и на моей 64-ядерной -машине это завершилось за 3 часа.

1
18.03.2021, 22:34

Это должно работать:

parallel --pipepart --block -1 -a large_strings.txt grep -oFf patterns.txt |
  grep -vFf - patterns.txt > unmatched_patterns.txt

Если у вас есть ripgrep, используйте:

parallel --pipepart --block -1 -a large_strings.txt rg -oFf patterns.txt |
  rg -vFf - patterns.txt > unmatched_patterns.txt

Если patterns.txtтоже огромен, взгляните на:

https://www.gnu.org/software/parallel/man.html#EXAMPLE:-Grepping-n-lines-for-m-regular-expressions

Ваша ситуация также довольно близка к проблеме, которую решает BLAT, за исключением того, что BLAT построен для ДНК. Но я не вижу, чтобы вы не могли использовать BLAT для вашей ситуации -возможно, с некоторыми изменениями (ну, вы могли бы преобразовать каждое шестнадцатеричное значение в 2 буквы ДНК и использовать их напрямую ). BLAT так же быстр, как поиск в базе данных, поэтому нет никакого сравнения с grep.http://genome.ucsc.edu/FAQ/FAQblat.html#blat3

3
18.03.2021, 22:34

Не знаю, сработает ли это...

while read line; 
do 
  grep -oF "$line" large_strings.txt & 
done <patterns.txt | grep -vFf - patterns.txt > unmatched_patterns.txt
0
18.03.2021, 22:34

Теги

Похожие вопросы