Résumé : Pour environ 1 million d'utilisateurs actifs et 150 millions d'activités stockées, je reste simple:
- Utilisez une base de données relationnelle pour le stockage des activités uniques (1 enregistrement par activité / "chose qui s'est produite") Rendez les enregistrements aussi compacts que possible. Structure afin que vous puissiez rapidement saisir un lot d'activités par ID d'activité ou en utilisant un ensemble d'ID d'amis avec des contraintes de temps.
- Publiez les ID d'activité sur Redis chaque fois qu'un enregistrement d'activité est créé, en ajoutant l'ID à une liste de "flux d'activité" pour chaque utilisateur qui est un ami / abonné qui devrait voir l'activité.
Interrogez Redis pour obtenir le flux d'activité de n'importe quel utilisateur, puis récupérez les données associées de la base de données si nécessaire. Revenez à l'interrogation de la base de données par heure si l'utilisateur a besoin de naviguer très loin dans le temps (si vous offrez même cela)
J'utilise une vieille table MySQL pour traiter environ 15 millions d'activités.
Cela 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é, source_id
me dit le record auquel l'activité est liée. Donc, si le type d'activité signifie "favori ajouté", je sais que le source_id fait référence à l'ID d'un enregistrement favori.
Le parent_id
/parent_type
sont utiles pour mon application - ils me disent à quoi l'activité est liée. Si un livre a été ajouté aux favoris, alors parent_id / parent_type me dirait que l'activité se rapporte à un livre (type) avec une clé primaire (id) donnée
J'indexe (user_id, time)
et interroge les activités qui le sont user_id IN (...friends...) AND time > some-cutoff-point
. Abandonner l'identifiant et choisir un autre index clusterisé pourrait être une bonne idée - je n'ai pas expérimenté cela.
Des trucs assez basiques, mais cela fonctionne, c'est simple et il est facile de travailler avec lorsque vos besoins changent. De plus, si vous n'utilisez pas MySQL, vous pourrez peut-être faire mieux en termes d'index.
Pour accéder plus rapidement aux activités les plus récentes, j'ai expérimenté Redis . Redis stocke toutes ses données en mémoire, vous ne pouvez donc pas y placer toutes vos activités, mais vous pouvez en stocker suffisamment pour la plupart des écrans les plus fréquemment consultés sur votre site. Les 100 plus récents pour chaque utilisateur ou quelque chose comme ça. Avec Redis dans le mix, cela pourrait fonctionner comme ceci:
- Créez votre enregistrement d'activité MySQL
- Pour chaque ami de l'utilisateur qui a créé l'activité, poussez l'ID sur sa liste d'activités dans Redis.
- Coupez chaque liste aux X derniers éléments
Redis est rapide et offre un moyen de canaliser les commandes sur une seule connexion - donc, pousser une activité à 1000 amis prend des millisecondes.
Pour une explication plus détaillée de ce dont je parle, voir l'exemple Twitter de Redis: http://redis.io/topics/twitter-clone
Mise à jour Février 2011 J'ai actuellement 50 millions d'activités actives et je n'ai rien changé. Une bonne chose à propos de faire quelque chose de similaire est qu'il utilise de petites lignes compactes. Je prévois d'apporter des changements qui impliqueraient beaucoup plus d'activités et plus de requêtes sur ces activités et j'utiliserai certainement Redis pour accélérer les choses. J'utilise Redis dans d'autres domaines et cela fonctionne vraiment bien pour certains types de problèmes.
Mise à jour juillet 2014 Nous sommes jusqu'à environ 700 000 utilisateurs actifs par mois. Depuis quelques années, j'utilise Redis (comme décrit dans la liste à puces) pour stocker les 1000 derniers identifiants d'activité de chaque utilisateur. Il y a généralement environ 100 millions d'enregistrements d'activité dans le système et ils sont toujours stockés dans MySQL et ont toujours la même disposition. Ces enregistrements nous permettent de nous en sortir avec moins de mémoire Redis, ils servent d'enregistrement des données d'activité et nous les utilisons si les utilisateurs ont besoin de reculer dans le temps pour trouver quelque chose.
Ce n'était pas une solution intelligente ou particulièrement intéressante, mais cela m'a bien servi.