2010-09-21 4 views
0

Я пытаюсь построить твитер-подобный механизм следования. Пользователь принимает меры. Мы составляем список всех подписчиков пользователей, а затем заполняем все их потоки некоторой информацией. Поскольку это может занять некоторое время (если у вас есть 10 000 подписчиков, то есть 10 000 потоков для вставки информации, например, 10 000 вызовов SQL), я хочу убедиться, что это делается в фоновом режиме, в то время как пользователь, который принимает действие, может пойти с его жизнью.Следуйте механизму с php: какую стратегию использовать?

Итак, стратегия я рассматриваю это:

  • пользователь принимает меры.
  • php script открывает еще один php-скрипт, который будет выполнять всю работу, и это может занять секунду или два.
  • Между тем, пользователь, который принял действие, может продолжать свою жизнь, их сценарий продолжается, и это быстро.

Мысли? Я также играл с использованием очереди, что-то вроде SQS, но этот подход звучит так, как будто он тоже может работать? Плюс у него есть преимущество (для меня), что легче тестировать локально и проще работать на хостах non ec2.

И если это хороший подход, как мне открыть php-скрипт из PHP-скрипта? Может ли быть так просто, как (если скрипт php живет на URL-адресе), чтобы получить URL-адрес, где живет этот сценарий?

ответ

3

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

Вы должны посмотреть на это с другой точки зрения. Рассмотрим следующую модель:

Пользователь A пишет, что он ел на завтрак. Это сохраняется один раз в таблице с его идентификатором пользователя.

Пользователь B смотрит на свой «поток». Это динамически созданный список сообщений. На данный момент пользователь B находится на 50 человек. Сценарий пользователя B будет получать первые 50 последних сообщений о том, кто он последует, и отображать их для него в его «потоке»

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

Разъяснение

Вам просто нужно сделать некоторые нормализации. Таким образом, у вас будет таблица пользователей, таблица users_following и таблица сообщений. Запрос будет выглядеть схожестью:

SELECT posts.* FROM users_following 
     LEFT JOIN posts ON posts.user_id = users_following.followed 
     WHERE users_following.follower = $idOfUserB 
     ORDER BY posts.created LIMIT 50; 
+0

Пользователь B входит в систему. Пользователь B следит за 200 человек. Теперь нам нужно запустить запрос, который говорит «select * from content, где authorid в ({all the id of the 200 people}) order by date_created desc». Или 1000 человек. Это совсем не значит, что этот запрос будет очень медленным. Вы не упомянули о том, что хранилище данных на самом деле не проблема, я не буду дублировать данные для каждого последователя, я просто дублирую указатель на данные (идентификатор) для каждого последователя, и это тривиальный объем памяти. Итак, мы просто делаем 2 быстрых запроса, чтобы показать ваш поток: получить список идентификаторов контента и получить контент. Мысли? – PeterV

+0

Я предполагаю, что я пытаюсь избежать этого запроса «SELECT * FROM content WHERE authorid IN (действительно длинный список)», потому что я подозреваю, что это будет довольно медленно, особенно если вы следите за множеством людей. – PeterV

+0

Право. Я не делаю IN. IN очень медленно, как вы сказали. Проверьте мой запрос. – Stephen

0

Если вы хотите, чтобы ваш сайт был на масштабе.

  • Прежде всего, необходимо использовать очереди сообщений, как, например Redis/beanstalkd/gearmand.
  • Второе, что вам нужно сделать в памяти, используя, например, redis/memcached. Убедитесь, что у вас достаточно памяти для хранения активного набора данных в памяти .

(если у вас есть 10000 последователей, что это 10000 потоков для вставки информации в, то есть. 10000 SQL требует, возможно)

10000 SQL вызовов имеет Fail Whale написанный над ним. Я бы не использовал MySQL (или хотя бы использовать его с memcached) для такого приложения, но использовал redis. Храните активный набор данных в памяти. Держите datamodel как можно более простым.

И если это хороший подход, как я бы открыть PHP скрипт внутри сценария РНР?

Не делайте этого. Добавьте сообщения в redis's blocking list через lpush и прочитайте их через blpop (процесс daemon). Сначала я бы заполнил список онлайн-пользователей и следующий список пользователей офлайн-пользователей. Авторизованные пользователи не возражают против задержки, потому что они не в сети. Вы должны поместить ссылку на ключ в список всех пользователей, следующих за этим человеком, и получить все ключи через mget.

Может быть так просто, как (если PHP скрипт живет в URL) делает получить на URL, где живет этот сценарий?

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

Удивительный. Вернуться к SQL :) Это будет быстро, даже если вы следите за 500 людьми? -

SQL предоставит вам отказ от китов большое время на высокой нагрузке. По крайней мере, вам понадобится memcached! Но вместо этого я использовал бы redis.