Оптимизировать получение корма - PullRequest
1 голос
/ 02 декабря 2008

Сейчас я работаю над сайтом, который должен получать фиды пользователей. Но как мне лучше оптимизировать выборку, если у меня есть база данных, скажем, с 300 фидами. Я собираюсь настроить cron-задание, на которое выбираются каналы, но делать ли мне это как 5 каждую секунду или что-то в этом роде?

Есть идеи, как сделать это наилучшим образом в PHP?

Ответы [ 4 ]

3 голосов
/ 02 декабря 2008

Если я понимаю ваш вопрос, вы в основном работаете над сайтом агрегатора каналов?

Вы можете сделать следующее; начните с обновления каждые 1 час (например). Если у вас достаточно записей из какого-либо канала - подсчитайте средний интервал между записями. Затем используйте этот интервал в качестве интервала для получения этого канала.

Например, если сайт опубликовал 7 статей за последние 7 дней - вы можете получать с него фиды каждые 24 часа (1 день).

Я использую этот алгоритм с небольшими изменениями, когда я вычисляю этот средний интервал, я делю его на 2 (чтобы не вызывать слишком редко). Если результат составляет менее 60 минут - я устанавливаю интервал в 1 час, или он больше 24, я устанавливаю его в 24 часа.

Например, что-то вроде этого:

    public function updateRefreshInterval() {
            $sql = 'select count(*) _count ' .
                    'from article ' .
                    'where created>adddate(now(), interval -7 day) and feed_id = ' . (int) $this->getId();
            $array = Db::loadArray( $sql );

            $count = $array[ '_count' ];

            $interval = 7 * 24 * 60 * 60 / ( $count + 1 );
            $interval = $interval / 2;
            if( $interval < self::MIN_REFRESH_INTERVAL ) {
                    $interval = self::MIN_REFRESH_INTERVAL;
            }
            if( $interval > self::MAX_REFRESH_INTERVAL ) {
                    $interval = self::MAX_REFRESH_INTERVAL;
            }

            Db::execute( 'update feed set refresh_interval = ' . $interval . ' where id = ' . (int) $this->getId() );
    }

Таблица «feed», «refreshed» - это отметка времени, когда канал был обновлен в последний раз, а «refresh_interval» - желаемый интервал времени между двумя выборками одного и того же канала.

2 голосов
/ 02 декабря 2008

На основании новой информации, я думаю, я бы сделал что-то вроде этого:

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

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

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

0 голосов
/ 02 декабря 2008

Я написал pfetch , чтобы сделать это для меня. Он небольшой, но имеет несколько действительно важных аспектов:

  1. Он написан в витой форме и может обрабатывать большой параллелизм даже при медленной сети.
  2. Для этого не требуется жулик или что-то в этом роде.

Я действительно написал это, потому что мои сборщики на основе cron становились проблемой. Теперь он настроен на выборку случайных вещей, которые я хочу, по Интернету, а затем запускает сценарии всякий раз, когда что-то меняется, для обновления частей моего собственного веб-сайта.

0 голосов
/ 02 декабря 2008

Лучшее, что нужно сделать, - это быть «милым» и не перегружать фиды множеством ненужных запросов. Я остановился на одном часе обновления одного из моих веб-приложений, который следит за обновлениями около 150 блогов. Я храню время их последней проверки в базе данных и использую это, чтобы решить, когда их обновить. Фиды добавлялись в случайное время, поэтому они не обновляются одновременно.

...