Для организации записи и хранения flow статистики v9 был выбран nfdump версии 1.6.13, сконфигурированный с параметром --nsel, что бы можно было учитывать IP адреса, через которые натируется серый ip.
Была необходимость делать backup'ы файлов, но файлов было много, очень много и весило и размер суммарный этих файлов был большим.
Решено было делать backup'ы в postgresql на другой сервер.
Софт используемый в текущей конфигурации:
nfdump 1.6.13 --nsel
debian 8/9
php7.0
postgresql9.6
Заранее прошу прощения за стыдоподобный код, т.к скрипт был реализован на 5-й день изучения мной php и то при помощи людей.
Скрипт был написан на php с учетом нужных функций мне, а именно:
Между серверами копирование файлов происходило по средствам rsync
После копирования запускался php скрипт из консоли на backup сервере
Скрипт создает массив из списка файлов в директории и разделяет на элементы
Потом в цикле берет последний файл, выводит его содержимое в текстовый файл
Текстовый файл разбивает на массив и запихивает в базу
Удаляет исходный файл
Удаляет текстовый файл
Ниже привожу пример самого скрипта.
<?php
//Создаем переменную подключения к базе
$connflow= "host=127.0.0.1 port=5432 dbname=dbname user=user password=password";
$dbflowconn=pg_connect($connflow);
//Директория,где лежат файлы
$dir = '/mnt/raid127/flow/stockflow/';
//Функция массива из списка файлов
function getSortFiles($dir) {
$files = array();
$yesDir = opendir($dir); // открываем директорию
if (!$yesDir)
die('Невозможно получить файлы из директории ' . $dir);
// идем по элементам директории
while (false !== ($filename = readdir($yesDir))) {
// пропускаем вложенные папки
if ($filename == '.' || $filename == '..')
continue;
// получаем время последнего изменения файла, заносим в массивы
$lastModified = filemtime("$dir/$filename");
$lm[] = $lastModified;
$fn[] = $filename;
}
// сортируем массивы имен файлов и времен изменения по возрастанию последнего
$files = array_multisort($lm,SORT_NUMERIC,SORT_ASC,$fn);
$last_index = count($lm)-1;
// форматируем дату и время изменения файла с учетом текущей локали
$lastTime = strftime ("%k:%M:%S %e %B %Y",$lm[$last_index]);
//echo "Последний файл: ".$fn[$last_index]." ".$lastTime."г.";
return($fn);
}
$filmass = (getSortFiles($dir));
//print_r (getSortFile($dir));
foreach ($filmass as $valuefilemass)
{
$temptxt = ("temp.txt");
//Выводим в файл флоу
shell_exec ('nfdump -o "fmt:%ts*%te*%td*%pr*%flg*%in*%out*%pkt*%byt*%fl*%tos*%bps*%pps*%bpp*%sa*%sp*%xsa*%xsp*%da*%dp*%xda*%xdp" -r /mnt/raid127/flow/stockflow/'.$valuefilemass.' > /mnt/raid127/flow/stockflow/'.$temptxt);
$i = 0;
//Открываем файл в массив
$fileop = file('/mnt/raid127/flow/stockflow/'.$temptxt);
$string = ($fileop);
$mass = array();
//Разбиваем массив по строкам
foreach ($fileop as $value)
//Делим данные в строке через разделитель
{
$temp = explode ("*", $value );
array_push($mass,$temp);
}
//Разбиваем строчный массив на элементный массив
foreach ($mass as $value)
{
//Проверяем кол-во даных в с элементном массиве
$countvalue = count($value);
if (count($value) == 22)
{
for ($i = 2; $i <= 21; $i++) {
$tvalue[$i] = trim($value[$i]);
}
//Формируем запросы в PG для записи
$insertflow="INSERT INTO flow
( datefirstseen, datelastseen, duration, protocol, flags, input, output, packets, bytes, flows, tos, bps, pps, bpp, srcip, srcport, xsrcip, xsrcport, dstip, dstport, xdstip, xdstport )
VALUES
( '".$value[0]."', '".$value[1]."', '".$tvalue[2]."', '".$tvalue[3]."', '".$tvalue[4]."', '".$tvalue[5]."', '".$tvalue[6]."', '".$tvalue[7]."', '".$tvalue[8]."', '".$tvalue[9]."',
'".$tvalue[10]."', '".$tvalue[11]."', '".$tvalue[12]."', '".$tvalue[13]."', '".$tvalue[14]."', '".$tvalue[15]."', '".$tvalue[16]."', '".$tvalue[17]."', '".$tvalue[18]."', '".$tvalue[19]."', '".$tvalue[20]."' , '".$tvalue[21]."' )";
//Подключаемся к базе и выполняем запросы
pg_query($dbflowconn, $insertflow );
}
}
//Удаляем исходные файлы
shell_exec ('rm /mnt/raid127/flow/stockflow/'.$valuefilemass);
shell_exec ('rm /mnt/raid127/flow/stockflow/'.$temptxt);
}
?>
Перед запуском скрипта необходимо создать базу и поля в базе в порядке очередности указанном в создаваемом запросе php файла. Я создавал все поля с типом text.
Параметры сервера
xeon e5
8gb ddr
debian 9
mdadm raid-level=6
7hdd
Скорость отработки одного файла = ~1млн строк в минуту.
Что бы добиться подобного результата, нужно будет затюнить сервер postgresql на свой вкус и цвет.
Автор: Командир судна