Умный способ оценить URL-клики в час, не регистрируя каждый клик? - PullRequest
3 голосов
/ 09 октября 2009

У меня есть сайт с миллионами URL. Каждый раз, когда щелкают URL-адрес, строка базы данных, соответствующая этому URL-адресу, обновляется с указанием отметки времени этого клика. Я бы хотел, наверняка, используя дополнительные столбцы, но без необходимости вставлять отдельные строки для каждого клика, оцените количество кликов в час, которое получает этот URL. Некоторые идеи включают в себя хранение нескольких временных меток, которые выровнены по самым последним секундам, минутам, 15-минутным и часовым интервалам (но эта идея мне неясна, как это на самом деле получает то, что мы хотим), или более неприятное решение сериализации «Журнал» дельт времени в какой-то сериализованной строке.

В то время как наивный подход предлагает измерять время между текущим кликом и последним, чтобы определить частоту, это даст только полезную оценку, если щелкнуть ссылку с очень постоянной скоростью. На самом деле ссылка может получить поток кликов за одну минуту и ​​совсем ничего за 20.

причина, по которой я не хочу отчетливо регистрировать каждый клик, заключается в том, что база данных не отягощена тысячами дополнительных операторов INSERT в час (и соответствующими УДАЛЕНИЯМИ данных более часа назад) или, альтернативно, что мне не нужно запускать дополнительную систему хранения (токийский тиран, grepping apache logs и т. д.), чтобы регистрировать эти клики.

Ответы [ 6 ]

4 голосов
/ 09 октября 2009

Как насчет хранения счетчика в memcached, с ключом URL и last_counter_reset_time в БД?

Memcached имеет легкую атомарную операцию incr. Звоните по каждому запросу. Периодически сбрасывайте счетчик, обновляя last_counter_reset_time.

Я не ветеран memcached, но я думаю, что есть способы быть уверенными в том, что счетчики для всех ваших URL остаются в кэше Постоянства нет, поэтому вы можете потерять счетчик в любое время, но случайная потеря данных такого рода может быть приемлемой.

3 голосов
/ 09 октября 2009

Вы пробовали другой подход, например, службу внешней статистики? может быть Google Analitycs? Это может дать вам информацию, которую вы ищете, без какой-либо дополнительной нагрузки на ваши серверы.

1 голос
/ 09 октября 2009

Есть ли причина, по которой вы игнорировали обработку журналов доступа apache? Их преимущество заключается в том, что они помечаются временем и автоматически создаются сервером и довольно легки. Довольно простой скрипт на perl или awk может затем содержать текущую сводку журналов для простого анализа.

0 голосов
/ 10 октября 2009

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

Если вы хотите очень простой подход: просто отбросьте выборки непредвзято (например, log_request(foo) if rand(1) < 0.1 для выборки 10% трафика). Вы потеряете все сигналы на URL, к которым обращаетесь, меньше, чем коэффициент, к которому вы относитесь, но если вас больше всего интересуют URL-адреса с высоким уровнем доступа, это может быть очень просто и эффективно.

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

  • Edit:

Ах, извините, теперь я вижу по комментариям, что вы после курсов на какое-то время. Подход, который я использовал для этого, в основном такой же, как для выборки / счетчика, просто сохраняйте отдельные счетчики для некоторой временной шкалы (то есть ежечасно). Для хранения долговременных архивов есть дополнительные сводные таблицы для больших периодов времени (ежедневно, еженедельно), которые пакетное задание заполняет из мелкозернистой (почасовой) таблицы, что позволяет удалять старые данные из мелкозернистой таблицы.

RRDTool является более общей реализацией этой идеи, и некоторые решения для мониторинга OSS используют ее.

0 голосов
/ 10 октября 2009

Возможно, это не практическое решение, но, поскольку вы попросили «умный» способ, здесь - это некоторое академическое исследование по вопросу, который не совсем является вашей проблемой, но, вероятно, может быть адаптирован. Некоторые статьи в списке «Цитируются» могут быть еще ближе.

0 голосов
/ 09 октября 2009

Прежде всего, зачем вообще хранить временные метки? Вы можете сохранить точные значения, имея одну запись в базе данных для каждого URL-адреса и просто увеличивая счетчик при каждом нажатии.

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

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

Вы также хотели бы рассмотреть время суток. Если большинство ваших пользователей, скажем, в Калифорнии, то URL-адрес, который будет выбран в 16:00 по тихоокеанскому времени, скорее всего, получит гораздо большее количество посещений, чем если бы он был выбран в 4:00 утра. Таким образом, вы хотите циклически перебирать URL-адреса таким образом, чтобы при возвращении к заданному URL-адресу он находился в другое время суток, чем когда вы впервые его взяли. Если ваши пользователи равномерно распределены по всему миру, это не будет проблемой, но это маловероятно.

...