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

В статье "Подсчёт трафика в nginx" я приводил один из возможных вариантов живого подсчёта трафика в 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

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

[-]
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() нужен, чтобы nginx не ругался на строки вида %d/%b/%Y:%H:%i:%s. Не любит nginx знак процента.

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

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

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

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

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

21
Фев
2009

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

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

  2. Фермер says:

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

  3. NoX says:

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

Подписаться на RSS-ленту комментариев к статье «Подсчёт трафика в nginx: часть 2» Trackback URL: http://blog.sjinks.org.ua/mysql/502-counting-traffic-for-nginx-part-2/trackback/

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

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

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

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