~AsmodeuS~ писал(а):попробуйте без FLOWTOOLS_IP_AGGREGATION=1 запустить команду и сообщите результат
Добрый день! Разобрались в чем проблема. У нас практически всем Юридическим лицам выдан не один IP а подсеть. Код соотнесения netflow строки под клиента у которого заведена подсеть работает весьма медленно. У вас заполняется хэш %ip_range который представляет из себя структуру типа {UID}=>pack('N4N4', $ip, $count). По которому путем полного перебора в функции traffic_agregate_users происходит поиск соответствия строки netflow и пользователя:
- while (my ($uid, $ip_count) = each %ip_range) {
- my ($ip, $count) = unpack('N4N4', $ip_count);
- my $last_ip = $ip + $count;
-
- if ($ip <= $DATA->{DST_IP} && $DATA->{DST_IP} <= $last_ip) {
Причем поиск происходит два раза по SRC_IP и по DST_IP. Т.е. если мы имеем 500 пользователей 2 направления и ~810000 строк netflow за 5 мин. то в худщем случае это соответствует 8,1e8 операций.
Добавили еще один хеш вида IP->UID и переписали соотнесения строки netflow. Теперь наш netflow обрабатывается приблизительно за 2 мин. Учитывая не очень быструю машину и диски, это вполне приемлемо.
Полный patch в приложении. Пока еще проводим тестирование. Но вроде все ок.
P.S.
Чет не могу прекрепить файл.
Вот текст патча:
Index: Ipn_Collector.pm
===================================================================
--- Ipn_Collector.pm (old)
+++ Ipn_Collector.pm (new)
@@ -43,6 +43,7 @@
my %intervals = ();
my %tp_interval = ();
my %ip_range = ();
+my %ip_user_hash = ();
my @zoneids;
my %ip_class_tables = ();
@@ -193,8 +194,12 @@
#Get IP/mask
if ($line->{netmask} && $line->{netmask} < 4294967295) {
my $count = 4294967295 - $line->{netmask};
+ my $ip2hash = $ip;
$ip = pack('N4N4', $ip, $count);
$ip_range{ $line->{uid} } = $ip;
+ for (my $i =0; $i <= $count; $i++) {
+ $ip_user_hash{$ip2hash+$i} = $line->{uid};
+ }
}
$ips{$ip} = $line->{uid};
@@ -229,7 +234,6 @@
$users_info{BILL_ID}{ $line->{uid} } = $line->{bill_id};
$users_info{JOIN_SERVICE}{ $line->{uid} } = $line->{join_service} if ( $line->{join_service} );
}
-
$self->{USERS_IPS} = \%ips;
$self->{USERS_INFO} = \%users_info;
$self->{SESSIONS_ID} = \%session_ids;
@@ -273,17 +277,13 @@
$y++;
}
else {
- while (my ($uid, $ip_count) = each %ip_range) {
- my ($ip, $count) = unpack('N4N4', $ip_count);
- my $last_ip = $ip + $count;
-
- if ($ip <= $DATA->{SRC_IP} && $DATA->{SRC_IP} <= $last_ip) {
+
+ if ($ip_user_hash{$DATA->{SRC_IP}}) {
+ my $uid = $ip_user_hash{$DATA->{SRC_IP}};
push @{ $self->{AGREGATE_USERS}{$uid}{OUT} }, {%$DATA};
$DATA->{UID} = $uid;
$y++;
- last;
}
- }
}
if (defined($users_ips->{ $DATA->{DST_IP} })) {
@@ -298,18 +298,13 @@
$y++;
}
else {
- while (my ($uid, $ip_count) = each %ip_range) {
- my ($ip, $count) = unpack('N4N4', $ip_count);
- my $last_ip = $ip + $count;
-
- if ($ip <= $DATA->{DST_IP} && $DATA->{DST_IP} <= $last_ip) {
+ if (defined($ip_user_hash{$DATA->{DST_IP}})) {
+ my $uid = $ip_user_hash{$DATA->{DST_IP}};
push @{ $self->{AGREGATE_USERS}{$uid}{IN} }, {%$DATA};
$DATA->{UID} = $uid;
$y++;
- last;
}
- }
-
+
#Unknown Ips
if ($y < 1) {
$DATA->{UID} = 0;