Я пытаюсь отслеживать просмотры страниц в БД MySQL, используя следующий запрос:
"UPDATE $table SET pageviews = pageviews + 1 WHERE page_id = 1"
Это нормально для трафика с низким или средним уровнем. Однако при высоком трафике постоянная запись в БД приведет к высокой конкуренции чтения / записи и, в конечном счете, приведет к снижению БД.
Я прочитал несколько QA здесь, в Stackoverflow и в других местах, где MongoDB предлагается в качестве альтернативы. Однако этот выбор недоступен, и я должен придерживаться MySQL. Кроме того, у меня нет контроля над двигателем – MyISAM или InnoDB (InnoDB работает лучше из-за блокировки на основе строк вместо таблицы, как в случае с MyISAM).
Учитывая описанный выше сценарий, каков наилучший возможный метод отслеживания просмотров страниц без измельчения БД (в БД или что-то еще)? Я бы очень признателен за ответ, который предоставляет фрагменты кода в качестве отправной точки (если это возможно).
Кстати, я использую PHP.
Обновление: у @fire есть хорошее решение здесь. Однако для этого требуется использование memcache. Я, глядя на то, что может быть легко реализовано, не требуя особого внимания. Это для модуля, который может быть практически использован в разных средах хостинга. С другой стороны, мне кажется, что некоторые идеи, основанные на файлах cookie или файлов, основаны на моем представлении. Я не уверен, как такая реализация будет работать на практике. Любые дополнительные материалы действительно приветствуются.
Я бы использовал memcached для хранения счета, а затем синхронизировал его с базой данных на cron …
// Increment $page_id = 1; $memcache = new Memcache(); $memcache->connect('localhost', 11211); if (!$memcache->get('page_' . $page_id)) { $memcache->set('page_' . $page_id, 1); } else { $memcache->increment('page_' . $page_id, 1); } // Cron if ($pageviews = $memcache->get('page_' . $page_id)) { $sql = "UPDATE pages SET pageviews = pageviews + " . $pageviews . " WHERE page_id = " . $page_id; mysql_query($sql); $memcache->delete('page_' . $page_id); }
Я бы подумал о сборе сырых хитов с самым быстрым механизмом записи, который у вас есть:
INSERT INTO hits (page_id, hit_date) VALUES (:page_id, CURRENT_TIMESTAMP)
… и затем запустить периодический процесс, возможно, скрипт командной строки cron, который будет подсчитывать и хранить сводку счетчика страниц, в которой вы нуждаетесь, ежечасно или ежедневно:
INSERT INTO daily_stats (page_id, num_hits, day) SELECT page_id, SUM(hit_id) FROM hits WHERE hit_date='2012-11-29' GROUP BY page_id
(Запросы – это просто примеры, настройки для ваших нужд)
Другим типичным решением является хороший старый синтаксический анализ журналов, который подает скрипт, похожий на AWStats, на журналы вашего веб-сервера.
Уточнение: мое первое предложение довольно похоже на @ fire, но я не попал в подробности хранения. Ключевым моментом является отсрочка тяжелой обработки и минимальное количество необработанной информации самым быстрым способом.
Рассматривали ли вы использование Google Analytics?
Вы не указали скорость чтения или записи в эту таблицу. MySQL, как правило, хорошо справляется, если вы держите индексирование до абсолютного минимума и размер строки мал. Таблица с идентификатором страницы и столбцом счетчика должна быть очень быстрой в большинстве случаев.
InnoDB также должен быть в порядке. MyISAM может взорваться самым худшим образом, если система выйдет из строя или теряет мощность во время тяжелой записи, она не регистрируется и не всегда может быть восстановлена. InnoDB гораздо более надежный.
Чтобы получить максимальную производительность от InnoDB, вы захотите настроить ваш сервер в соответствии со стандартными рекомендациями и провести его агрессивно, чтобы быть уверенным, что вы правильно поняли. У каждой ОС есть свои причуды. Иногда вы можете упускать два фактора увеличения производительности, не имея правильной настройки.
Если ваша база данных отслеживания мала, вам может потребоваться создать экземпляр, поддерживаемый RAM-диском, и реплицировать его на другой сервер с помощью обычного HD. Поскольку вы ожидаете чрезвычайно высокой активности записи, если вы можете переносить небольшую потерю данных в худшую возможную ситуацию, например, сбой системы, вы можете просто mysqldump
эту базу данных периодически снижать ее. Сброс базы данных с поддержкой памяти с даже миллионом строк займет всего минуту и не будет прерывать записи из-за MVCC.