Войдите в файл через PHP или войдите в базу данных MySQL - что быстрее?

У меня есть сайт с базой данных, обслуживающий около 50 000 страниц.

Я хочу отслеживать каждый веб-сайт/запись. Я сделаю это, создав журналы, а затем пакетную обработку журналов один раз в день. Меня не интересует, как я буду выполнять пакетный процесс, только с самым быстрым способом регистрации.

Как бы вы регистрировались, что, по вашему мнению, быстрее:

a) Используйте PHP для добавления в конец текстового файла журнала.

b) Использовать MySQL для INSERT IN в неиндексированной таблице журналов.

Ответ 1

  • Пишите в файл. Поворот журналов.

  • Пакетная загрузка файла в базу данных на плановой основе.

Существует множество причин выбора этой архитектуры - простота масштабирования (запись во многие журналы, загрузка их на db), отсутствие уверенности в SPOF в базе данных (если что-то пойдет не так, вы просто накапливаете журналы для некоторое время), умение выполнять очистку и нетривиальное разборе во время загрузки без нагрузки на ваши серверы производства и т.д.

Ответ 2

Вы можете попробовать оба способа, используя log4php, который поддерживает:

  • Конфигурация через xml и файл свойств (такая же структура, как log4j).
  • Файл, RollingFile, DailyFile, Echo, Console, Mail, PEAR:: Db, ошибка PHP, события Syslog или NT и приложения Socket.
  • Простые, TTCC, Pattern, Html и Xml Layouts.
  • Вложенные (NDC) и сопоставленные (MDC) диагностические контексты.
  • Отключаемая внутренняя отладка.

Что касается входа в файл, вы можете повысить производительность, буферизируя запросы на запись.

Ответ 3

Я бы использовал Delayed Insert в MySQL. Таким образом, вам не нужно ждать завершения вставки.

Ответ 4

Использовать базу данных - это единственный разумный вариант. Даже если это займет немного больше времени. После того, как вы начнете с файлов журналов, вы окажетесь на дорожке, где это приведет к боли. перемещение серверов, разрешения файлов, исключает балансировку нагрузки и т.д.

Если у вас открыта база данных, я полагаю, что, вероятно, быстрее вставить одну строку.

Однако с учетом всей этой производительности единственный способ убедиться в том, что нужно написать простой тест и измерить его.

Обновление: я сделал быстрый тест - и, конечно же, если вам нужно открыть и закрыть файл с той же скоростью или медленнее, используя тест из 10 000 строк:

Однако, когда вы начинаете выполнять несколько процессов, это замедляется, как показано ниже. Это с 10 параллельными процессами (все тайминги в секундах)

DB time: 2.1695
DB time: 2.3869
DB time: 2.4305
DB time: 2.5864
DB time: 2.7465
DB time: 3.0182
DB time: 3.1451
DB time: 3.3298
DB time: 3.4483
DB time: 3.7812
File open time: 0.1538
File open time: 0.5478
File open time: 0.7252
File open time: 3.0453
File open time: 4.2661
File open time: 4.4247
File open time: 4.5484
File open time: 4.6319
File open time: 4.6501
File open time: 4.6646
Open close file time: 11.3647
Open close file time: 12.2849
Open close file time: 18.4093
Open close file time: 18.4202
Open close file time: 21.2621
Open close file time: 22.7267
Open close file time: 23.4597
Open close file time: 25.6293
Open close file time: 26.1119
Open close file time: 29.1471

function debug($d)
{
    static $start_time = NULL;
    static $start_code_line = 0;

    if( $start_time === NULL )
    {
        $start_time = time() + microtime();
        $start_code_line = $code_line;
        return 0;
    }

    printf("$d time: %.4f\n", (time() + microtime() - $start_time));
    $fp = @fopen('dbg.txt','a');
    fprintf($fp,"$d time: %.4f\n", (time() + microtime() - $start_time));
    fclose($fp);

    $start_time = time() + microtime();
    $start_code_line = $code_line;
}

function tfile()
{
    $fp = @fopen('t1.txt','a');
    for ($i=0;$i<10000;$i++)
    {
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        fwrite($fp,$txt);
    }
    fclose($fp);
}
function tfile_openclose()
{
    for ($i=0;$i<10000;$i++)
    {
        $fp = @fopen('t1.txt','a');
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        fwrite($fp,$txt);
        fclose($fp);
    }
}

function tdb()
{
    $db = mysql_connect('localhost','tremweb','zzxxcc');

    $select_db = mysql_select_db('scratch');

    if (!$select_db) 
        die('Error selecting database.');

    for ($i=0;$i<10000;$i++)
    {
        $txt = $i."How would you log, which do you think is quicker:How would you log, which do you think is quicker:";
        mysql_query("INSERT INTO tlog values('".$txt."')");
    }
}

debug("");

tfile();
debug("File open");

tfile_openclose();
debug("Open close file");

tdb();
debug("DB");

Ответ 5

Я бы поверил, что плоский файл будет быстрее писать.

Ответ 7

Я сделал что-то подобное. Я записываю каждую запись в отдельный файл, затем у меня есть пакетный процесс, который захватывает файлы, помещает их в файл tar и загружает их на центральный сервер журнала (в моем случае S3:)).

Я генерирую случайные имена файлов для каждой записи журнала. Я делаю это, чтобы избежать блокировки файлов для вращения. Это очень легко архивировать/удалять таким образом.

Я использую json как свой формат журнала вместо типичных файлов журнала с ограниченным пробелом. Это упрощает анализ и добавление полей в будущем. Это также означает, что мне легче писать запись на файл, чем добавлять несколько записей на файл.

Я также использовал log4php + syslog-ng для централизации ведения журнала в реальном времени. У меня есть log4php log to syslog, который затем пересылается в журналы на мой центральный сервер. Это действительно полезно для больших кластеров. Одно из предостережений заключается в том, что существует ограничение длины для сообщений syslog, поэтому вы рискуете усечь более длинные сообщения.

Ответ 8

Я прочитал статью в журнале пользователей С++, много лет назад, о производительности loggin. Независимо от того, используете ли вы DB или файлы, лучше всего писать неформатированные данные, которые могут быть "завышены" в значимые данные, когда (и, более вероятно, если) вам нужно просмотреть журналы. Подавляющая часть затрат на регистрацию - это информация о строках, которые записываются в пункт назначения, и большую часть времени, затраченных на затраты, журналы никогда не читаются.

Я могу выкопать ссылку на статью, если она вам полезна.

Ответ 9

Если вы используете ведение журнала на основе файлов или ведение журнала на базе базы данных, самым большим достижением производительности будет блокировка файлов и таблиц. В принципе, если клиент A и клиент B подключаются в течение относительно небольшого периода времени, клиент B застрял, ожидая, когда блокировка будет выпущена в файле/таблице хитов, прежде чем продолжить.

Проблема с файловым механизмом заключается в том, что блокировка файлов необходима для обеспечения того, чтобы ваши образы не повреждались. Единственный способ - это реализовать очередь для записи в файл с задержкой.

С ведением журнала базы данных вы можете, по крайней мере, сделать следующее [MySQL, используя MyISAM]:

INSERT DELAYED INTO `hits` ...

См. 12.2.5.2. INSERT DELAYED Синтаксис для получения дополнительной информации.

Ответ 10

В файл будет быстрее, но в БД будет лучше.

Ответ 11

Я бы порекомендовал вам протестировать оба теста с несколькими тестовыми примерами.

Я бы предположил, что плоский файл будет быстрее, b/c, что действительно делает БД - он просто записывает его в файл. Единственное преимущество, о котором я могу думать, - это если база данных может работать одновременно, вы можете получить лучшие результаты.

Ответ 12

Все зависит от вашей инфраструктуры и ограничений. Если диск медленный, запись будет медленной. Если SQL-сервер отстает от запросов, вставка будет медленной. Плоский файл, вероятно, лучший способ, но я бы написал ваш код или использовал существующий код (PEAR:: Log), чтобы вы могли по желанию изменить метод провайдера и хранения.

Ответ 13

Несколько соображений:

  • Как вы думаете, вы хотите объединить данные журнала с другими данными в базе данных? Если это так, накладные расходы на вкладку db, вероятно, оправданы, поэтому существующие отношения могут быть легко использованы.
  • Будет ли ведение журнала данных в базе данных позволит вам значительно сократить объем данных, которые вы регистрируете (из-за существующих отношений в db)? Например, журнал в базе данных активности пользователя может быть просто таблицей, содержащей идентификатор пользователя, activityid и временную метку. Файл журнала, в котором этот пост в файле не был бы доступен для чтения. В зависимости от ваших потребностей вам нужно будет захватить хотя бы некоторые из пользовательских данных в файле журнала, чтобы убедиться, что он может быть полезен и доступен для чтения человеком самостоятельно.
  • Есть ли вероятность, что вы захотите использовать данные журнала в интерфейсе или через административный инструмент по дороге? Если это так, запись DB, вероятно, предпочтительнее.

Ответ 14

Как уже упоминалось, это зависит от множества вещей, таких как трафик, скорость диска и т.д. Вам придется протестировать оба сценария.

Во время тестирования MySQL попробуйте как MyISAM, так и INNODB. Теоретически Innodb будет работать лучше, поскольку он имеет блокировку на уровне строк.

Ответ 15

Если это для сайта, управляемого базой данных, почему бы вам не использовать встроенные возможности ведения журнала Apache или IIS и подходящий инструмент для ведения отчетов, такой как AWStats и, кроме того, всегда Google Analytics

AWStats и ведение журнала веб-серверов - это мое предпочтение - вы по существу получаете его бесплатно в любом случае - даже если вы не после анализа трафика, вы все равно можете сами проанализировать файл журнала доступа Apache для любой пакетной обработки, которую вам нужно выполнить.