2010-09-21 3 views
0

J'essaye de construire un mécanisme de suivi de type Twitter. L'utilisateur prend une action. Nous dressons une liste de tous les abonnés de ces utilisateurs, puis remplissons tous leurs flux avec des informations. Comme cela peut prendre un certain temps (si vous avez 10 000 abonnés, c'est-à-dire 10 000 flux pour insérer des informations, par exemple 10 000 appels SQL), je veux m'assurer que cela se fasse en arrière-plan, alors que l'utilisateur avec sa vie.Suivre le mécanisme avec php: quelle stratégie utiliser?

Ainsi, la stratégie que je considère est la suivante:

  • utilisateur prend des mesures. Php script ouvre un autre script PHP qui fera tout le travail et cela pourrait prendre une seconde ou deux.
  • pendant ce temps, l'utilisateur qui a pris l'action peut continuer sa vie, son script continue et c'est rapide.

Pensées? J'ai également joué avec l'utilisation d'une file d'attente, quelque chose comme SQS, mais cette approche semble fonctionner aussi? De plus, il a l'avantage (pour moi) qu'il est plus facile de tester localement et plus facilement sur des hôtes non ec2.

Et si c'est une bonne approche, comment pourrais-je ouvrir un script php à partir d'un script PHP? Pourrait-il être aussi simple que (si le script PHP vit à une URL) faire un get sur une URL où ce script vit?

Répondre

3

La façon dont cela est décrit ressemble à ce que vous voulez reproduire/dupliquer le message du premier utilisateur pour tous ceux qui suivent cet utilisateur? Cela va être un cauchemar de stockage de données.

Vous devriez le regarder d'un autre point de vue. Considérez le modèle suivant:

L'utilisateur A écrit ce qu'il a mangé au petit-déjeuner. Ceci est stocké une fois dans une table avec son identifiant utilisateur.

L'utilisateur B regarde son "flux". Ceci est une liste de posts créée dynamiquement. À ce stade, l'utilisateur B suit 50 personnes.

Avec ce modèle, vous n'avez jamais plus d'un message par utilisateur par mise à jour de petit-déjeuner frivole. De plus, le nombre de suiveurs n'augmente pas le temps de traitement nécessaire pour publier le twit. Je veux dire tweet.

Précision

Vous aurez juste besoin de faire une normalisation. Vous aurez donc une table users, une table users_following et une table posts. La requête ressemblerait à:

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

L'utilisateur B se connecte. L'utilisateur B suit 200 personnes. Maintenant, nous devons lancer une requête qui dit "select * from content où authorid ({tous les identifiants de ces 200 personnes}) order by date_created desc". Ou 1000 personnes. Cela ne va pas du tout, cette requête va devenir très lente. Le stockage de données que vous mentionnez n'est pas réellement un problème, je ne vais pas dupliquer les données pour chaque suiveur, je vais juste dupliquer un pointeur vers les données (un identifiant) pour chaque suiveur, et c'est une quantité triviale de stockage. Alors nous faisons juste 2 requêtes rapides pour montrer votre flux: obtenir la liste des identifiants de contenu, et obtenir le contenu. Pensées? – PeterV

+0

Je suppose que j'essaie d'éviter cette requête "SELECT * FROM contenu où authorid IN (une liste vraiment longue)", parce que je soupçonne que ce sera assez lent, surtout si vous suivez beaucoup de gens. – PeterV

+0

Droite. Je ne fais pas un IN. IN est très lent, comme vous l'avez dit. Consultez ma requête – Stephen

0

Si vous souhaitez que votre site à l'échelle à tous.

  • Vous devez d'abord utiliser une file d'attente de messages comme par exemple Redis/beanstalkd/gearmand.
  • Deuxièmement vous devez faire vos opérations dans mémoire en utilisant par exemple redis/memcached. Assurez-vous que vous avez suffisamment de mémoire pour conserver l'ensemble de données actif dans mémoire.

(si vous avez 10.000 adeptes qui est 10 000 cours d'eau pour insérer des informations dans , par exemple. 10000 SQL appelle peut-être)

10.000 appels SQL a baleine d'échouer écrit sur elle. Je n'utiliserais pas MySQL (ou au moins l'utiliser avec memcached) pour une telle application mais j'utiliserais redis. Conserver le jeu de données actif en mémoire. Gardez datamodel aussi simple que possible.

Et si cela est une bonne approche, comment pourrais-je ouvrir un script PHP à partir un script php?

Ne faites pas cela. Ajoutez des messages à blocking list de redis via lpush et lisez-les via blpop (processus daemon). Je voudrais d'abord remplir la liste des utilisateurs en ligne et la prochaine liste de remplissage des utilisateurs hors ligne. Les utilisateurs hors ligne ne sont pas dérangés parce qu'ils ne sont pas en ligne. Vous devez mettre une référence à la clé sur la liste de tous les utilisateurs qui suivent cette personne et obtenir toutes les clés via mget.

Pourrait-il être aussi simple que (si le php vit script à une URL) faire un get sur une url où vit ce script?

Encore une fois, n'appelez pas d'URL mais utilisez une file d'attente de messages. L'appel de l'URL vous donnera des frais généraux non souhaités.

Impressionnant. Retour à SQL :) Ce sera rapide même si vous suivez 500 personnes? -

SQL vous donnera des baleines échouent un grand temps à forte charge. Au moins, vous aurez besoin de memcached! Mais j'utiliserais redis à la place.

Questions connexes