nfdump export postgresql средствами php

в 18:17, , рубрики: nix, Администрирование баз данных, резервное копирование, метки: , , , , , ,

Для организации записи и хранения 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 на свой вкус и цвет.

Автор: Командир судна

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js