Подсчёт трафика в nginx: часть 2

Дальнейшие усовершенствования процесса

В статье "Подсчёт трафика в nginx" я приводил один из возможных вариантов живого подсчёта трафика в .

У прошлого решения есть недостатки:

  • используется три лишних процесса;
  • используется много файловых дескрипторов (зависит от количества виртуальных хостов).

Я на днях нашёл еще один вариант.

Будем использовать немного другую структуру таблицы:

[-]
View Code MySQL
CREATE TABLE `traf_stats` (
    `in` INTEGER UNSIGNED NOT NULL,
    `out` INTEGER UNSIGNED NOT NULL,
    `host` VARCHAR(64) NOT NULL,
    `dt` MEDIUMINT NOT NULL
);

Основное отличие — не используются поля, которые легко вычислить (`sum` = `in` + `out`, `ym` = EXTRACT(YEAR_MONTH FROM `dt`)) и отсутствуют индексы (ибо при высокой посещаемости сжимать таблицу на живую — это самоубийство чистой воды).

Переходим к магии.
Создаём лог:

[-]
View Code Bash
mkfifo --mode=0666 /var/log/nginx/traffic.log

А далее, если Вы хорошо знакомы с программированием под /, наверное, догадались: во все виртуальные хосты прописываем

[-]
View Code Text
access_log  /var/log/nginx/traffic.log  trafctr;

Формат trafctr определён следующим образом (извращение):

[-]
View Code Text
log_format trafctr 'INSERT DELAYED INTO traf_stats VALUES($request_length, $bytes_sent, "$server_name", UNIX_TIMESTAMP(STR_TO_DATE(SUBSTR("$time_local", 1, 20), CONCAT(CHAR(37), "d/", CHAR(37), "b/", CHAR(37), "Y:", CHAR(37), "H:", CHAR(37), "i:", CHAR(37), "s"))));';

Фактически, в pipe будет писаться такой запрос:

[-]
View Code MySQL
INSERT DELAYED INTO traf_stats VALUES
(
    123,
    456,
    "myserver.com",
    UNIX_TIMESTAMP(
        STR_TO_DATE(
            SUBSTR("18/Feb/2009:17:24:37 -0500", 1, 20),
            CONCAT(CHAR(37), "d/", CHAR(37), "b/", CHAR(37), "Y:", CHAR(37), "H:", CHAR(37), "i:", CHAR(37), "s")
        )
    )
);

SUBSTR() убирает хвост в виде часового пояса, STR_TO_DATE() используется для создания строки с временем, которую поймёт UNIX_TIMESTAMP(), а CONCAT()… Что же, CONCAT() нужен, чтобы не ругался на строки вида %d/%b/%Y:%H:%i:%s. Не любит знак процента.

Как данные попадают в базу? Всё просто:

[-]
View Code Bash
mysql -uuser -ppass -Ddatabase --batch --force < /var/log/nginx/traffic.log

Следующий этап (часть 3): написание демона, заменяющего (как процесс). Демон будет сжимать данные на лету и передавать их -серверу. Благодаря этому мы снизим нагрузку на (запросы будут передаваться в виде extended insert, а сами данные уже будут просуммированы).

Добавить в закладки

Связанные записи

Автор: Vladimir; опубликовано в: Linux, MySQL, Администрирование; метки: Linux, MySQL, nginx, UNIX, лог, трафик
21
Фев
2009

RSS Комментарии к статье «Подсчёт трафика в nginx: часть 2» (5)  »

  1. [...] Подсчёт трафика в nginx: часть 2. [...]

  2. Фермер

    С уводольствием пожал бы автору руку, благо, его блог – чудо.

  3. NoX

    Загуглил, попал на данный блог. Статьи очень инетересные, мне как начинающему веб-разработчику. А метод подсчёта трафика – и вовсе чудо ;) спасибо автору

  4. а не проще использовать LOAD DATA ,?

Оставить комментарий к записи «Подсчёт трафика в nginx: часть 2»

Вы можете использовать данные тэги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Изображения должны быть включены!

Оставляя комментарий, вы выражаете своё согласие с Правилами комментирования.

Подписаться, не комментируя