Работа с базой данных

 

Хотя в начале разработки база данных Berkeley DB была выбрана как инструмент управления статистиками, было решено реализовать отдельный модуль, предоставляющий интерфейс управления статистиками и инкапсулирующий работу с базой данных с тем, чтобы при необходимости можно было легко перейти на другую СУБД. К тому же, C++ API, включенный в стандартную поставку Berkeley DB, является лишь очень тонкой надстройкой над API на С. Игнорируются многие возможности, доступные в С++, такие как исключения, умные указатели, шаблоны, перегрузка операторов и т.д. Вся логика работы, присущая API на С (в том числе необходимость обработки «голых» указателей), осталась неизменной. Это чревато серьезными ошибками, особенно когда остальной код активно использует исключения. Поэтому интерфейс управления статистиками необходим также для сглаживания недостатков Berkeley DB C++ API. Речь не идет о реализации полноценного интерфейса для Berkeley DB, такая задача не ставилась. Были выбраны лишь те возможности, которые необходимы для работы со статистиками.

Вся работа со статистиками происходит через шаблонный класс DBController. Класс принимает четыре шаблонных параметра: тип ключа, тип данных, стратегия управления типом ключа и стратегия управления типом данных. Стратегия предоставляет функции сериализации и десериализации данных определенного типа. Была написана стратегия для встроенных типов (не указателей) и STL-строк под названием StdStrategy. Она используется по умолчанию для типов ключа и данных шаблона DBController.

Методы DBController позволяют записывать и считывать данные по ключу и проверять наличие ключа в базе данных. От реализации доступа к записям через итераторы решено было отказаться. Однако DBController имеет шаблонный метод template<T> foreach(T& op), получающий в качестве параметра функтор (указатель на функцию или экземпляр класса с перегруженным оператором вызова — operator()), который должен принимать два аргумента (ключ и значение) и будет вызван для каждой записи в базе данных.

Реализация шаблона DBController основана на идиоме скрытой реализации pimpl (pointer to implementation, [16]). Объявлен класс DBContRawImpl. Он ответственен за всю работу непосредственно с базой данных, его методы используются шаблоном DBController. Его определение и реализация находятся в отдельном файле. Таким образом, DBContRawImpl может быть изменен без перекомпиляции кода, использующего шаблон DBController. Это позволяет при необходимости изменить используемую СУБД, изменив лишь файл реализации DBContRawImpl или вообще подменив его другим файлом. Стратегия StdStrategy и интерфейс шаблона DBController приведены в приложении А.

 

Сбор статистики.

 

За сбор статистики отвечает компонент под названием коллектор. Он занимается перехватом пакетов и записью их в базу данных. Захват производится средствами популярной библиотеки pcap (Packet Capture [11], ее использует подавляющее большинство снифферов и им подобного ПО, в том числе широко распространенная утилита tcpdump [12]), а работа с базой данных ведется при помощи шаблона DBController.

Необходимость написания отдельной программы захвата пакетов, когда уже есть tcpdump, на первый взгляд кажется необоснованной. Однако это повышает удобство использования системы и увеличивает надежность кода сбора статистики. Tcpdump выводит информацию о пакетах в текстовом виде. При применении его для сбора статистики нужно собрать ее в текстовый файл, а затем перевести этот файл в базу данных. На начальных стадиях разработки проекта использовалась именно такая схема. Но из-за огромного количества соединений и множества избыточных данных текстовые файлы, содержащие статистики, получались очень большими (по несколько гигабайт или даже десятков гигабайт). Такие файлы трудно перемещать, а их конверсия в базу данных занимает слишком много времени.

Эту проблему, будь она единственной, можно решить, используя конвейеры Linux/UNIX [13]: запустить tcpdump и направить его вывод на вход утилиты конверсии. Но проблема, связанная с разбором текстового представления данных — остается. Алгоритм разбора был бы нетривиален и изобиловал ветвлениями. Обеспечить его надежность гораздо сложнее, чем использовать библиотеку pcap напрямую. Поэтому в данном случае самописный легковесный сниффер — лучшее решение.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: