Подтвердить что ты не робот

Лучшая практика записи большого количества запросов в базу данных MySQL

Ну, вот что. Скажем, что моя будущая PHP CMS должна ежедневно ездить на 500 000 посетителей, и мне нужно записать их все в базе данных MySQL (referrer, ip-адрес, время и т.д.). Таким образом, мне нужно вставить 300-500 строк в минуту и ​​обновить еще 50. Основная проблема заключается в том, что script будет вызывать базу данных каждый раз, когда я хочу вставить новую строку, которая каждый раз, когда кто-то нажимает на страницу.

Мой вопрос: есть ли способ локально кэшировать входящие образы в первую очередь (и что это лучшее решение для этого apc, csv...?) и периодически отправлять их в базу данных каждые 10 минут, например? Является ли это хорошим решением и какова наилучшая практика для этой ситуации?

4b9b3361

Ответ 1

500k ежедневно это всего 5-7 запросов в секунду. Если каждый запрос будет подан в течение 0,2 секунды, тогда у вас будет почти 0 одновременных запросов, поэтому беспокоиться не о чем. Даже если у вас будет в 5 раз больше пользователей - все должно работать нормально.
Вы можете просто использовать INSERT DELAYED и настроить ваш mysql.
О настройке: http://www.day32.com/MySQL/ - есть очень полезный script (ничего не изменит, просто покажу вам советы по оптимизации настроек).

Вы можете использовать memcache или APC для записи журнала там сначала, но с использованием INSERT DELAYED MySQL будет выполнять почти ту же самую работу и будет делать это лучше:)

Не используйте файлы для этого. DB будет лучше блокировать блокировки, чем PHP. Это не так тривиально писать эффективные мьютексы, поэтому пусть это делает DB (или memcache, APC).

Ответ 2

Часто используемое решение:

Вы можете реализовать счетчик в memcached, который вы увеличиваете при посещении, и нажимайте обновление базы данных каждые 100 (или 1000).

Ответ 3

Мы делаем это, сохраняя локально на каждом сервере в CSV, а затем выполняем мелкое задание cron для ввода записей в базу данных. Это делается для того, чтобы избежать необходимости иметь доступную базу данных MySQL больше всего на свете - база данных должна иметь возможность справиться с этим объемом вставок без проблем.

Ответ 4

Сохраните их в базе данных на основе каталогов (или плоском файле, в зависимости от) где-нибудь и в определенное время используйте PHP-код для вставки/обновления их в вашу базу данных MySQL. Ваш php-код может выполняться периодически с использованием Cron, поэтому проверьте, есть ли у вашего сервера Cron, чтобы вы могли установить расписание для этого, скажем каждые 10 минут.

Посмотрите на эту страницу: http://damonparker.org/blog/2006/05/10/php-cron-script-to-run-automated-jobs/. Некоторые коды были написаны в облаке и готовы к использованию:)

Ответ 5

Один из способов - использовать Apache access.log. Вы можете получить довольно точный журнал, используя утилиту cronolog с apache. Cronolog будет обрабатывать хранение большого количества строк в файлах и может вращать его на основе объема, года и т.д. Использование этой утилиты предотвратит потерю Apache от записи журнала.

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

Вы можете подумать об использовании выделенной базы данных (или даже сервера базы данных) для приложений с интенсивной записью с конкретными настройками. Например, вам может не понадобиться хранилище InnoDB и хранить простой MyIsam. И вы даже можете подумать о другом хранилище баз данных (как сказал @Riccardo Galli)

Ответ 6

Если вам абсолютно необходимо напрямую подключиться к MySQL, рассмотрите возможность использования двух баз данных. Один оптимизирован для быстрых вставок, что означает отсутствие ключей, кроме, возможно, первичного ключа auto_increment. И еще с ключами на все, на что вы будете запрашивать, оптимизированы для быстрого поиска. Временная работа будет копировать обращения из вставки только в базу данных только для чтения на регулярной основе, и вы получите лучшее из обоих миров. Единственный недостаток заключается в том, что ваша доступная статистика будет только такой же свежей, как и предыдущая работа "копирование".

Ответ 7

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

Это, по-видимому, преобладающее решение для оптимизации; ваше веб-приложение остается доступным, если база данных аудита не работает, и пользователи не страдают низкой производительностью, если база данных по какой-либо причине медленная.

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

Ответ 8

Для большого количества операций записи и таких данных вы можете найти более подходящие mongodb или couchdb

Ответ 9

Поскольку INSERT DELAYED поддерживается только MyISAM, это не вариант для многих пользователей.

Мы используем MySQL Proxy для отсрочки выполнения запросов, соответствующих определенной сигнатуре.

Для этого потребуется пользовательский Lua script; примеры скриптов здесь, и некоторые обучающие программы здесь.

script будет реализовывать структуру данных очереди для хранения строк запроса и сопоставление образцов, чтобы определить, какие запросы отложить. Когда очередь достигает определенного размера или истекает определенное количество времени или происходит какое-либо событие X, очередь запросов освобождается, поскольку каждый запрос отправляется на сервер.

Ответ 10

вы можете использовать стратегию очереди с использованием beanstalk или IronQ