Riepilogo : per circa 1 milione di utenti attivi e 150 milioni di attività memorizzate, lo mantengo semplice:
- Utilizzare un database relazionale per l'archiviazione di attività uniche (1 record per attività / "cosa accaduta") Rendere i record il più compatti possibile. Struttura in modo da poter afferrare rapidamente un gruppo di attività in base all'ID attività o utilizzando un set di ID amico con vincoli temporali.
- Pubblica gli ID attività su Redis ogni volta che viene creato un record di attività, aggiungendo l'ID a un elenco di "flussi di attività" per ogni utente amico / abbonato che dovrebbe vedere l'attività.
Eseguire una query su Redis per ottenere il flusso di attività per qualsiasi utente, quindi acquisire i dati correlati dal database in base alle esigenze. Torna a interrogare il db per tempo se l'utente deve navigare molto indietro nel tempo (se lo offri anche tu)
Uso una semplice vecchia tabella MySQL per gestire circa 15 milioni di attività.
Sembra qualcosa del genere:
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
mi dice il tipo di attività, source_id
mi dice il record a cui l'attività è correlata. Quindi, se il tipo di attività significa "preferito aggiunto", allora so che source_id si riferisce all'ID di un record preferito.
I parent_id
/ parent_type
sono utili per la mia app: mi dicono a cosa è correlata l'attività. Se un libro fosse preferito, parent_id / parent_type mi direbbe che l'attività si riferisce a un libro (tipo) con una determinata chiave primaria (id)
Indico (user_id, time)
e cerco le attività che sono user_id IN (...friends...) AND time > some-cutoff-point
. Abbandonare l'id e scegliere un diverso indice cluster potrebbe essere una buona idea - non l'ho mai provato.
Roba piuttosto semplice, ma funziona, è semplice ed è facile lavorare con il cambiamento delle tue esigenze. Inoltre, se non si utilizza MySQL, si potrebbe essere in grado di eseguire meglio l'indice.
Per un accesso più veloce alle attività più recenti, ho sperimentato Redis . Redis memorizza tutti i suoi dati in memoria, quindi non puoi mettere tutte le tue attività lì dentro, ma puoi archiviare abbastanza per la maggior parte delle schermate più colpite sul tuo sito. I 100 più recenti per ogni utente o qualcosa del genere. Con Redis nel mix, potrebbe funzionare così:
- Crea il tuo record di attività MySQL
- Per ogni amico dell'utente che ha creato l'attività, inserisci l'ID nel loro elenco di attività in Redis.
- Taglia ogni elenco con gli ultimi X elementi
Redis è veloce e offre un modo per eseguire il pipeline dei comandi attraverso una connessione, quindi inviare un'attività a 1000 amici richiede millisecondi.
Per una spiegazione più dettagliata di ciò di cui sto parlando, vedi l'esempio Twitter di Redis: http://redis.io/topics/twitter-clone
Aggiornamento febbraio 2011 Al momento ho 50 milioni di attività attive e non ho cambiato nulla. Una cosa bella del fare qualcosa di simile è che usa file compatte e piccole. Sto programmando di apportare alcune modifiche che implicherebbero molte più attività e più domande su quelle attività e userò sicuramente Redis per mantenere le cose veloci. Sto usando Redis in altre aree e funziona davvero bene per alcuni tipi di problemi.
Aggiornamento luglio 2014 Siamo attivi per circa 700.000 utenti mensili attivi. Negli ultimi due anni ho usato Redis (come descritto nell'elenco puntato) per memorizzare gli ultimi 1000 ID attività per ciascun utente. Di solito ci sono circa 100 milioni di record di attività nel sistema e sono ancora memorizzati in MySQL e hanno ancora lo stesso layout. Questi record ci permettono di liberare meno memoria Redis, servono come record di dati di attività e li usiamo se gli utenti devono tornare indietro nel tempo per trovare qualcosa.
Questa non era una soluzione intelligente o particolarmente interessante, ma mi ha servito bene.