Je développe mon propre réseau social, et je n’ai pas trouvé sur les web des exemples de mise en œuvre du flux des actions des utilisateurs... Par exemple, comment filtrer les actions pour chaque utilisateurs ? Comment stocker les événements d’action ? Quel modèle de données et le modèle d’objet puis-je utiliser pour le flux d’actions et pour l’itselves des actions ?
Réponses
Trop de publicités?J'utilise une bonne vieille table MySQL pour traiter environ 15 millions des activités.
Il ressemble à quelque chose comme ceci:
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
activity_type
me dit le type d'activité, en source_id
me dit que l'activité est liée. Donc, si le type d'activité signifie "ajout de favoris", puis je sais que le source_id fait référence à l'ID d'un favori record.
L' parent_id
/parent_type
sont utiles pour mon app - ils me dire ce que l'activité est liée. Si un livre a été ajoutés à vos favoris, puis parent_id/parent_type me dire que l'activité est liée à un ouvrage (type) avec une primary key (id)
Je l'index sur (user_id, time)
et de requête pour des activités user_id IN (...friends...) AND time > some-cutoff-point
. Amerrissage forcé de l'id et de choisir un autre index cluster pourrait être une bonne idée, je n'ai pas expérimenté cette.
De jolis trucs de base, mais ça fonctionne, c'est simple, et il est facile de travailler avec suivant vos besoins. Aussi, si vous n'êtes pas à l'aide de MySQL, vous pourriez être en mesure de faire un meilleur indice d'une montre.
Pour un accès plus rapide pour les activités les plus récentes, j'ai fait des expériences avec le Redis. Redis stocke toutes ses données en mémoire, de sorte que vous ne pouvez pas mettre l'ensemble de vos activités, mais vous pouvez stocker suffisamment pour la plupart des hit écrans sur votre site. La plus récente de 100 pour chaque utilisateur ou quelque chose comme ça. Avec Redis dans le mélange, il pourrait fonctionner comme ceci:
- Créez votre MySQL activité record
- Pour chaque ami de l'utilisateur qui a créé l'activité, pousser l'ID sur leur liste des activités dans le Redis.
- Garniture de chaque liste pour les X derniers articles
Redis est rapide et offre un moyen de pipeline commandes à travers une connexion afin de pousser une activité à 1000 amis ne prend que quelques millisecondes.
Pour une explication plus détaillée de ce que je suis en train de parler, voir Redis Twitter exemple: http://redis.io/topics/twitter-clone
Mise à jour février 2011 , j'ai obtenu 50 millions de dollars des activités actives à l'instant et je n'ai rien changé. Une bonne chose à propos de faire quelque chose de semblable à cela est qu'il utilise compact, les petites lignes. Je prévois de faire quelques changements qui nécessiterait beaucoup plus d'activités et plus de requêtes de ces activités, et je vais certainement utiliser Redis pour garder les choses rapides. Je suis en utilisant le Redis dans d'autres domaines et il fonctionne vraiment bien pour certains types de problèmes.
Mise à jour de juillet 2014 , Nous en sommes à environ 700K d'utilisateurs mensuels actifs. Pour les deux dernières années, j'ai été en utilisant Redis (comme décrit dans la liste à puces) pour stocker les 1000 dernières Id d'activité de chaque utilisateur. Il y a habituellement environ 100 millions d'enregistrements d'activité dans le système et ils sont toujours stockés dans MySQL et sont toujours la même mise en page. Ces enregistrements nous le laisser s'en tirer avec moins Redis mémoire, ils servent à l'enregistrement de données d'activité, et nous de les utiliser si les utilisateurs ont besoin pour page plus loin en arrière dans le temps pour trouver quelque chose.
Ce n'était pas un savant ou particulièrement solution intéressante, mais il m'a bien servi.
C'est ma mise en œuvre d'un flux d'activité, de l'utilisation de mysql. Il y a trois classes: Activité, ActivityFeed, l'Abonné.
L'activité représente une activité d'entrée, et sa table ressemble à ceci:
id
subject_id
object_id
type
verb
data
time
Subject_id
est l'id de l'objet l'exécution de l'action, object_id
l'id de l'objet qui reçoit l'action. type
et verb
décrit l'action elle-même (par exemple, si un utilisateur d'ajouter un commentaire à un article qu'ils seraient des "commentaires" et "créé", respectivement), de données contient des données supplémentaires afin d'éviter les jointures (par exemple, il peut contenir le nom du sujet et le nom, le titre de l'article et l'url, le commentaire du corps, etc.).
Chaque Activité appartient à un ou plusieurs ActivityFeeds, et ils sont liés par une table qui ressemble à ceci:
feed_name
activity_id
Dans mon application j'ai une alimentation pour chaque Utilisateur et un flux pour chaque Élément (généralement des articles de blog), mais ils peuvent être tout ce que vous voulez.
Un Abonné est généralement un utilisateur de votre site, mais il peut aussi être n'importe quel objet dans votre modèle d'objet (par exemple un article pourrait être souscrites à la feed_action de son créateur).
Chaque Abonné appartient à un ou plusieurs ActivityFeeds, et, comme ci-dessus, ils sont liés par un lien de ce genre:
feed_name
subscriber_id
reason
L' reason
champ ci-dessous explique pourquoi l'abonné a souscrit l'alimentation. Par exemple, si un utilisateur signet un billet de blog, la raison est "signet". Cela m'aide plus tard dans des actions de filtrage pour les notifications pour les utilisateurs.
Pour récupérer de l'activité pour l'abonné, je fais une simple jointure des trois tables. La jointure est rapide car j'ai quelques activités grâce à un WHERE
condition qui ressemble maintenant - time > some hours
. - Je éviter d'autres jointures grâce à des données de champ dans la table d'Activité.
De plus amples explications sur reason
champ. Si, par exemple, je veux les actions de filtrage pour les notifications par email de l'utilisateur, et l'utilisateur signet un post de blog (et si il adhère à la poste d'alimentation avec la raison "signet"), je ne veux pas que l'utilisateur reçoit des notifications par courrier électronique sur les actions sur cet article, alors que si il commente le post (et si il adhère à la poste d'alimentation avec raison, 'commentaire') je veux qu'il est avisé lorsque d'autres utilisateurs d'ajouter des commentaires pour le même poste. Le champ raison qui m'aide dans cette discrimination (j'ai mis en œuvre par l'intermédiaire d'un ActivityFilter classe), en collaboration avec les préférences de notifications de l'utilisateur.
Il y a une forme actuelle des flux de l'activité qui est en cours d'élaboration par un groupe de bien connaître les gens.
Fondamentalement, chaque activité a un acteur (qui exécute l'activité), un verbe (l'action de l'activité), un objet (sur lequel l'acteur joue sur), et une cible.
Par exemple: Max a posté un lien vers Adam mur.
Leur JSON de Spec a atteint la version 1.0 au moment de la rédaction, qui montre l'évolution de l'activité que vous pouvez appliquer.
Leur format a déjà été adopté par la BBC, Gnip, Google Buzz, Gowalla, IBM, MySpace, Opéra, Socialcast, Superfeedr, TypePad, Windows Live, YIID, et beaucoup d'autres.
Je pense qu'une explication sur la façon dont les notifications système fonctionne sur de grands sites internet peuvent être trouvés dans le débordement de la pile question de comment les sites de réseautage social calculer les amis des mises à jour?, dans la Jeremy Mur's réponse. Il suggère l'utilisation de Message Qeue et il indique deux open source, logiciels de mise en oeuvre:
Voir aussi la question" Quelle est la meilleure manière de mettre en œuvre une activité sociale stream?
Vous avez absolument besoin d'un performant & distributed file d'attente de messages. Mais il ne s'arrête pas là, vous aurez à prendre des décisions sur ce qu'il faut stocker que des données persistantes et ce qui est transitoire et etc.
De toute façon, il est vraiment une tâche difficile, mon ami, si vous êtes après une haute performance et un système évolutif. Mais, bien sûr, quelques généreux ingénieurs ont partagé leur expérience sur ce. LinkedIn récemment fait son message de la file d'attente du système de Kafka open source. Avant cela, Facebook a déjà fourni Scribe à la communauté open source. Kafka est écrit en Scala et au début, il faut un certain temps pour le faire fonctionner, mais j'ai testé avec un couple de serveurs virtuels. Il est vraiment rapide.
http://blog.linkedin.com/2011/01/11/open-source-linkedin-kafka/