McZim
|
|
« : 10-12-2008 09:23 » |
|
Написал небольшой скрипт, который сверяет реально поступившие данные с оборудования по netflow потоку и тех которые смогли обработаться. По поводу обработки и выборки из базы можете не обращать на это внимания, так как процесс узконаправленный. Меня интересует то, как можно увеличить скорость обработки файлов. При общем объеме файлов 19 гигов в формате raw, скрипт справляется примерно за 1,5 часа. Хотелось бы увеличить скорость обработки. Кто что может посоветовать? #!/usr/bin/perl
use File::stat; use DBI;
$user = "логин"; $password = "пароль"; $source = "dbi:Oracle:host=хост;sid=экземпляр;port=1521";
#----------------------------------------------------------------------- $pattern = "какойто IP адрес, по которому делаем выборку"; $service = "какой то номер услуги для выборки из БД"; #-----------------------------------------------------------------------
$cat = "/usr/local/flow-tools/bin/flow-cat"; $prt = "/usr/local/flow-tools/bin/flow-print";
$dirname = $ARGV[0];
opendir (DIR, $dirname) || die "Error in opening dir $dirname\n"; @files=readdir(DIR); @sortfiles = sort(@files);
$month = substr("$dirname/$_", -3,2); $year = substr("$dirname/$_", -7,4);
print "##########################################\n"; print "Pattern: $pattern\n"; print "Service: $service\n";
foreach (@sortfiles) { unless ($_ eq '..' || $_ eq '.') { if (-d "$dirname/$_") { break; } else { $buff = stat("$dirname/$_"); $mfile = scalar localtime $buff->mtime; $modify = substr($mfile,-16,2);
for($k=1; $k<31; $k++) { if($modify == $k) { $buff_sum[$k] += work(); } } } } }
sub work { my $total = `$cat $dirname/$_ | $prt | awk '{print "h:"\$6 "B:"\$2}' | grep -e '$pattern' | awk 'BEGIN {sum=0; cnt=0} {split(\$1,h,":"); sum += h[2];cnt++} END {print "Sum:" sum}'`;
print ".";
return($total); }
print "\n";
for($i=1; $i<31; $i++) { print "$i - day. Byte: $buff_sum[$i]\n"; $sumall += $buff_sum[$i]; }
$dbh=DBI->connect($source, $user, $password,{PrintError=>0,AutoCommit=>0,RaiseError=>1}) or die "Couldnot connect to Oracle:$DBI::errstr\n";
$sth = $dbh->prepare("SELECT SUM(traffic) FROM bm_report_traffic WHERE service_id = $service AND year = $year AND mon = $month AND is_incoming = '1' GROUP BY DAY");
$sth->execute();
my @row = $sth->fetchrow_array;
print "\n"; print "Total sum byte from raw file: $sumall\n"; print "Total sum byte from database: $row[0]\n"; print "##########################################\n";
$sth->finish(); closedir(DIR); exit(0);
Добавлено через 21 секунду:Ну собственно вот и решение $filter = "/usr/local/flow-tools/bin/flow-filter";
...
sub work { my $total = `$cat $dirname/$_ | $filter -f ./birabis.acl -D Skaent | $prt | awk '{print "h:"\$6}' | awk 'BEGIN {sum=0} {split(\$1,h,":"); sum += h[2]} END {print sum}'`;
print ".";
return($total); }
а вот и birabis.acl ip access-list standard Skaent permit 62.148.2.5 ip access-list standard Skaent deny any
соответственно аклы можно создавать какие угодно и сколько угодно. ИТОГО: время сократилось с одного часа 30-ти минут, до 18-ти минут, не плохо да что сделали: заменили "распечатываение" всего и поиска в этом нужного (grep), и дальнейшего вычисления суммы, на "распечатываение" нужного и вычисления суммы. Система: Linux 2.6.9-42.ELsmp #1 SMP Wed Jul 12 23:27:17 EDT 2006 i686 i686 i386 GNU/Linux Red Hat Enterprise Linux ES release 4 MemTotal: 4147792 kB Intel(R) Xeon(R) CPU X5450 @ 3.00GHz -- 7 ядер.
|
|
« Последнее редактирование: 10-12-2008 11:31 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #1 : 10-12-2008 17:05 » |
|
McZim, знаешь, а нифига не понятно... Это очень загадочно и не понятно: реально поступившие данные с оборудования по netflow потоку и тех которые смогли обработаться Это к вопросу о исходных данных. Использовать awk в замен perl - ты потеряешь порядка 2 в производительности. В свое время я начал изучать perl именно потому, что большие объемы awk обрабатывает крайне медленно. Если опишешь вводную понятно и если оно тебе еще надо, то можно попробовать найти решение. С netflow работал, но реализовывал на C.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #2 : 15-12-2008 21:24 » |
|
ок, вводная. Есть некий объем пришедшей информации с сетевого оборудования по netflow, о потреблении трафика. Эти все файлы лежат в "сыром" виде (raw). Вся работа с такими данными, от принятия на стороне сервера до обработки оных, делается с помощью flow-tools. Наши тарификаторы (считалки трафика), по пришествию таких данных преобразуют эти данные во внутренный формат биллинга, для дальнейшей работы и "сырые" данные складывают в хранилище. Так вот иногда у заказчика возникает такое желание проверить а верно ли насчитал биллинг по сравнению с тем что пришло с оборудования. В связи с чем я и написал такой скрипт, который по шаблону (диапазон ip адресов), ищет записи в "сырых" данных, суммирует байты по дням и выводит их, ну и за месяц суммарная циферка. Потом этот же скрипт лезе в базу и там суммирует данные за указанный месяц, для указанного клиента (по дням разбивку еще сделаю), после 18 минут работы скрипта наглядно видно где, что и как. В сило того что разработчики flow-tools этот проект закинули уже давно, есть некоторые подводные камни, в частности с flow-filter и "аклами" указывающими подсети. С Perl'ом я еще пока что не на ты, поэтому у меня в переменную $total, ложится результат полученный после некоторого, так сказать, каскада фильтров. Пока что так, скорость в полне устраивает. Может чего придумаю З.Ы.: Пробовал в консоле обойтись без awk, скорость такаяже 18 минут 20 гигов. Так что я вижу смысл в скрипте избавится от awk, только из за красоты, прироста в производительности это не даст, так как все сильно завязано на flow-tools.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #3 : 16-12-2008 18:49 » |
|
Что за "сырой" формат? Насколько помню, данные приходят в пакетах UDP, в формате: заголовок пакета и несколько блоков (сколько влезает в пакет) полезной нагрузки. Кроме того, есть разные версии netflow - у них разный формат блоков. И так... Файлы - коллекция чего - блоков, пакетов или это вообще типа формата pcap?
awk не может работать с бинарными данными. У perl есть для этого функции pack и unpack - безопасно извлечет данные в твои переменные и можно дальше работать как обычно.
Не могу найти исходники своей проги. Боюсь, все на прошлой работе осталось.
В атаче дока, где есть описание форматов v1, v5 и v7. Я работал с v5: принимал пакеты, разбирал на блоки, выбирал нужные поля и помещал в базу. Раз в сутки накопленные данные обрабатывались и суммировались по часам - так компактнее.
Добавлено через 1 минуту и 1 секунду: Еще у меня есть описание v9 - rfc3954.
|
|
« Последнее редактирование: 16-12-2008 19:04 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #4 : 16-12-2008 19:52 » |
|
Ты не понял. Сырые данные это те что пришли от Cisco например, но могут и другое оборудование слать, которое понимает netflow v5. На стороне сервера демон flow-capture ловит эти данне и складывает в виде бинарных файлов. Дальше идет работа над этими данными описанная више. AWK не умеет работать с бинарными данными, так она и не работает, она работает с тем что вывела flow-cat.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #5 : 16-12-2008 20:02 » |
|
Макс, сам же знаешь - о сути надо говорить, а не из далека заходить: никто не знает, что ты знаешь. Покажи примеры того, что выдает flow-cat.
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #6 : 16-12-2008 20:08 » |
|
Сейчас под рукой нет, но flow-cat просто так в чистом виде не используют, потому как в ее выводе ничего не понять и как правило применяют в связке с различными фильтрами, типа flow-print, flow-filter, flow-nfilter, flow-stat. Добавлено через 16 минут и 50 секунд:В той связке которая у меня, примерно получится следующее srcIP dstIP prot srcPort dstPort octets packets 212.162.137.27 195.12.66.1 6 1646 25 598 12 192.93.0.4 195.12.66.1 17 53 2666 133 1 194.187.251.2 195.12.66.1 17 64217 53 60 1 81.84.242.5 195.12.66.1 17 53 2666 128 1 72.36.190.2 195.12.66.1 17 58155 53 74 1 |
т.е. с помощью flow-cat мы достаем информацию из сырых файлов, с помощью flow-filter мы выводим только строки с адресом назначения 195.12.66.1, а с помощью flow-print выводим эту информацию на стандартный вывод, но реально ничего не выводим, а перехватываем очередным фильтром awk.
|
|
« Последнее редактирование: 16-12-2008 20:25 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #7 : 16-12-2008 20:35 » |
|
Жду реальный пример (желательно пару десятков записей или больше).
Не понимаю, зачем ты гонишь эти гигабайты (а в текстовом виде это же еще больше) через столько процессов - огромные потери на коммуникации. Фрагмент твоей строки: awk '{print "h:"\$6 "B:"\$2}' | grep -e '$pattern' | awk 'BEGIN {sum=0; cnt=0} {split(\$1,h,":"); sum += h[2];cnt++} END {print "Sum:" sum}'
Эквивалентный однострочник perl (из расчета запуска из под shell): perl -nae '($F[2] eq "'"$patern"'") && $sum += $F[6]; END { print "Sum: $sum\n"; }'
Я правильно понял, что в поле $2 - IP, а $6 - счетчик байт? Я бы не стал делать cat $file | command -- быстрее будет command <$file. Еще вопрос: переполнения 32-битного целого не опасаешься?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #8 : 16-12-2008 20:39 » |
|
Да ты правильно понял, но сейчас рабочая строка вот эта. my $total = `$cat $dirname/$_ | $filter -f ./birabis.acl -D Skaent | $prt | awk '{print "h:"\$6}' | awk 'BEGIN {sum=0} {split(\$1,h,":"); sum += h[2]} END {print sum}'`;
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #9 : 16-12-2008 20:48 » |
|
Макс, еще совет: если есть возможность, увеличьте размер кеша netflow в сетевыз устройствах - они реже будут сбрасывать пакеты и объем файлов уменьшится. За это придется заплатить небольшим понижением точности данных netflow по времени - т.е. данные дольше будут накапливаться перед сбросом на сборщик.
Я все же считаю, что самое эффективное - самостоятельно разбирать файлы дампов: меньше посредников, меньше ненужных обработок, меньше межпроцессного трафика.
Протестируй на скорость твою и мою строки - интересный момент. awk - чисто интерпретируемый язык, perl - с предкомпиляцией в байт-код.
|
|
« Последнее редактирование: 16-12-2008 20:50 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #10 : 16-12-2008 20:52 » |
|
RXL, настройку оборудования контролируем не мы. Сразу разбирать данные я не имею право. Я просто пишу скрипт для себя по большей степени, ну еще несколько инженеров пользуется. Этот скрипт нужен только для того что бы подсчитать те данные что в архиве (сырые) и те данные что в архиве (обработанные), чтобы так сказать проконтролировать биллинг (путем сравнения данных).
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #11 : 16-12-2008 20:53 » |
|
Был вопрос про 32-битное переполнение - что думаешь?
|
|
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #12 : 16-12-2008 21:03 » |
|
RXL, а сколько в перле максимум 32 бита для целого? т.е. сколько цифр влезет?
Добавлено через 6 минут и 19 секунд: Вообще когда большое число в переменной насколько я успел увидеть, оно преобразуется к экспонентному виду.
|
|
« Последнее редактирование: 16-12-2008 21:09 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #13 : 16-12-2008 21:55 » |
|
McZim, в perl по необходимости расширяет внутренний формат переменной.
perl -e 'for $i (0...80) { printf "$i: %30.0f\n", 2**$i; }'
А вот как считает awk - я не знаю - надо проверять. Проверил - тоже расширяет.
awk -- 'BEGIN { printf("%30.0f\n", 2**64); }'
Значит тут бояться нечего.
|
|
« Последнее редактирование: 16-12-2008 22:01 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #14 : 17-12-2008 07:39 » |
|
perl -nae '($F[2] eq "'"$patern"'") && $sum += $F[6]; END { print "Sum: $sum\n"; }'
Я правильно понял, что в поле $2 - IP, а $6 - счетчик байт? Небольшая ошибочка у тебя, нужно не $F[6] а $F[5] вот результат двух команд: [root@bmnf 1]# time /usr/local/flow-tools/bin/flow-cat ft* | /usr/local/flow-tools/bin/flow-filter -f ./birabis.acl -D lavalin | /usr/local/flow-tools/bin/flow-print | awk '{print "h:"$6}' | awk 'BEGIN {sum=0} {split($1,h,":"); sum += h[2]} END {print sum}' 1641922
real 0m1.971s user 0m1.860s sys 0m0.119s
[root@bmnf 1]# time /usr/local/flow-tools/bin/flow-cat ft* | /usr/local/flow-tools/bin/flow-filter -f ./birabis.acl -D lavalin | /usr/local/flow-tools/bin/flow-print | perl -nae '$sum += $F[5]; END { print "Sum: $sum\n"; }' Sum: 1641922
real 0m2.036s user 0m1.915s sys 0m0.127s
Схему с awk можно упростить конечно, но мне лениво как-то Объем на котором проводился тест ~40Мб Добавлено через 11 минут и 22 секунды:А вот так строки отработали объем информации в ~715Мб. файлы за один день. [root@bmnf 1]# time /usr/local/flow-tools/bin/flow-cat ft* | /usr/local/flow-tools/bin/flow-filter -f ./birabis.acl -D lavalin | /usr/local/flow-tools/bin/flow-print | perl -nae '$sum += $F[5]; END { print "Sum: $sum\n"; }' Sum: 5612467
real 0m35.266s user 0m32.528s sys 0m2.425s
[root@bmnf 1]# time /usr/local/flow-tools/bin/flow-cat ft* | /usr/local/flow-tools/bin/flow-filter -f ./birabis.acl -D lavalin | /usr/local/flow-tools/bin/flow-print | awk '{print "h:"$6}' | awk 'BEGIN {sum=0} {split($1,h,":"); sum += h[2]} END {print sum}' 5612467
real 0m34.255s user 0m31.592s sys 0m2.337s
|
|
« Последнее редактирование: 17-12-2008 07:51 от McZim »
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
RXL
Технический
Администратор
Offline
Пол:
|
|
« Ответ #15 : 17-12-2008 17:12 » |
|
Небольшая ошибочка у тебя, нужно не $F[6] а $F[5]
Ага. И не $F[2], а $F[1]. Тормознул - в awk $0 означает всю строку ввода, а тут @F содержит только разрезанные части. В общем, мне видится, что основное время съедают flow-команды. Еще видно, что на однострочнике разницы практически нет.
|
|
« Последнее редактирование: 17-12-2008 17:16 от RXL »
|
Записан
|
... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
|
|
|
McZim
|
|
« Ответ #16 : 17-12-2008 18:03 » |
|
RXL, аха именно так.
|
|
|
Записан
|
The CBO without stats is like a morning without coffee. (c) T.Kyte.
|
|
|
|