Sistema di notifica dei social network


10

sfondo

Sto lavorando su un'app per un client che include alcune funzionalità di social network. Inizialmente stavo sviluppando il front-end mobile, ma le circostanze mi hanno lasciato incaricato di sviluppare anche il back-end.

Come sfondo generale, il nostro sistema consente agli utenti di seguire altri utenti e ricevere notifiche su quelli che stanno seguendo, come ci si aspetterebbe da un social network. Un avvertimento è che solo un piccolo sottoinsieme (al massimo poche centinaia) di utenti sarà seguibile, con l'aspettativa che la maggior parte della base di utenti seguirà almeno una di queste persone.

Sul lato dell'interfaccia utente, avremo un pulsante di notifica con un numero su di esso e facendo clic sul pulsante si accederà alla schermata di notifica.

Il problema

Ho ricercato strategie per l'implementazione delle notifiche e la maggior parte delle risorse che ho trovato punta a creare una o più tabelle di notifica nel database. (Un esempio che mi piace è la risposta accettata qui: /programming/9735578/building-a-notification-system ).

La cosa che mi sta gettando è che la maggior parte delle strategie basate su database per le notifiche richiedono l'inserimento di una riga per ciascuna notifica per ciascun follower. Quindi se un migliaio di persone seguono Sally, inseriamo un migliaio di righe nella tabella corrispondente. È scalabile? Cosa succede se arriviamo al punto in cui decine o centinaia di migliaia di utenti stanno seguendo Sally e sta scrivendo qualche dozzina di post al giorno?

La mia idea originale era quella di gestire tutto con le query: il numero sul pulsante di notifica sarebbe stato ottenuto richiedendo il conteggio delle righe sui contenuti pubblicati più di recente rispetto all'ultima volta che hai visitato la schermata di notifica, mentre le singole notifiche sarebbero state generate da query più dettagliate quando hai visitato la schermata di notifica. Questo approccio non richiederebbe scritture o spazio di archiviazione aggiuntivo, ma non è flessibile e probabilmente martellerebbe il server piuttosto duramente.

IMPOSTARE

Il backend (come stabilito dallo sviluppatore precedente) utilizza CodeIgniter e un database MySQL . Attualmente è in esecuzione su un maledetto account di hosting condiviso GoDaddy, ma presumo (spero?) Che questo verrà aggiornato prima di andare in produzione e il pacchetto di hosting verrà ridimensionato con la crescita degli utenti.

Attualmente il nostro unico front-end è un'app mobile, ma prevediamo di costruire anche un sito Web in un secondo momento. Al momento non mi preoccupo di ottenere aggiornamenti push in tempo reale dal server sulle notifiche.

ADDENDUM

Non sono specializzato in backend e mi occupo di me in quel dipartimento. Il cliente lo sa, e ho fatto del mio meglio per cercare di spiegare la portata di un progetto di questa natura, ma hanno chiarito che a questo punto non si fideranno di nessun altro che lavori al progetto. Probabilmente abbiamo ancora un mese di lavoro da fare prima di poter iniziare ad aggiungere tester e posso ottenere qualsiasi tipo di metrica delle prestazioni. Non riesco davvero a stimare quanti utenti potremmo avere o su quale hardware potremmo essere nei prossimi 5 anni, ma penso che il client spera per centinaia di migliaia di utenti o più.

Spero che questo sia un problema abbastanza specifico da pubblicare qui; Posso perfezionarlo se necessario. Si prega di chiedere se avete domande o ho omesso dettagli importanti.

tl; dr

  • Un sistema di notifica basato su database ha implicazioni negative per la scalabilità a lungo termine quando tutti gli utenti seguono solo alcune delle stesse centinaia di persone?
  • Esiste un modo per rendere il database delle notifiche guidato senza la necessità di una riga di notifica separata per ciascuna notifica per ciascun follower?
  • Un sistema di notifica interamente basato su query sarebbe scalabile o avrebbe dei vantaggi oltre a non scrivere alcun dato nel DB?
  • Sto pensando troppo presto? Devo solo costruire qualcosa che funzioni per ora e possiamo preoccuparci di ottimizzarlo se diventa un problema, dato che il cliente ha un budget limitato e non sappiamo ancora se il prodotto finale sarà popolare?

Puoi scadere le notifiche? Ad esempio, elimina qualsiasi cosa di età superiore a 2 settimane. Ciò dovrebbe più o meno bilanciare le dimensioni della tabella utilizzata man mano che il sito matura.
GrandmasterB

Questo non sarà un problema, ero più preoccupato delle implicazioni sulle prestazioni del blocco del database scrivendo 50.000 voci nella tabella delle notifiche ogni volta che un utente popolare fa un post.
user45623,

Ho lavorato su un progetto con un sistema di notifica simile (ma più piccolo). Ho avuto un processo in background che ha esaminato una coda di nuovi post e gestito le notifiche (che in questo caso stava inserendo un'e-mail in una seconda coda per l'invio). Non era in tempo reale, ma in genere gestiva tutto in un paio di minuti.
GrandmasterB,

Risposte:


10

Quindi se un migliaio di persone seguono Sally, inseriamo un migliaio di righe nella tabella corrispondente. È scalabile?

Sì, a condizione che le tabelle del database siano indicizzate correttamente.

Cosa succede se arriviamo al punto in cui decine o centinaia di migliaia di utenti stanno seguendo Sally e sta scrivendo qualche dozzina di post al giorno?

Genererai una dozzina di decine o centinaia di migliaia di record di notifica al giorno per Sally, supponendo che tu voglia tenere traccia di ogni notifica per sempre. La percentuale di utenti come Sally con quel tipo di traffico è sempre molto piccola.

La mia idea originale era quella di gestire tutto con le query: il numero sul pulsante di notifica sarebbe stato ottenuto richiedendo il conteggio delle righe sui contenuti pubblicati più di recente rispetto all'ultima volta che hai visitato la schermata di notifica, mentre le singole notifiche sarebbero state generate da query più dettagliate quando hai visitato la schermata di notifica.

Questo sembra inutilmente complicato. Se hai bisogno di statistiche dettagliate sulle notifiche, archivia semplicemente le notifiche.

Un sistema di notifica basato su database ha implicazioni negative per la scalabilità a lungo termine quando tutti gli utenti seguono solo alcune delle stesse centinaia di persone?

Ecco perché funziona ... un piccolo numero di persone genera sempre la stragrande maggioranza del traffico.

Esiste un modo per rendere il database delle notifiche guidato senza la necessità di una riga di notifica separata per ciascuna notifica per ciascun follower?

Sì ... Non archiviare le notifiche; basta inviare le e-mail di notifica, in stile fire-and-forget. In alternativa, conservare le notifiche per un determinato periodo di tempo, quindi scartarle. Oppure, scarta ogni notifica dopo che è stata letta.

Un sistema di notifica interamente basato su query sarebbe scalabile o avrebbe dei vantaggi oltre a non scrivere alcun dato nel DB?

Non sono sicuro di cosa intendi con questo. Se si desidera interrogare le notifiche, è necessario memorizzarle nel database. Altrimenti, non c'è nulla da interrogare.

Sto pensando troppo presto?

Parla con qualcuno che può aiutarti a progettare un database indicizzato correttamente normalizzato con le tabelle corrette al suo interno. Non vedo alcun motivo per cui un tale database non sia in grado di gestire efficacemente gli scenari descritti.

Un esempio di vita reale

Per quanto ne so, Stack Exchange archivia tutto per sempre, comprese tutte le notifiche. Usano una tecnologia di database simile a MySql e alcune tecnologie di memorizzazione nella cache. Mentre il loro spazio hardware e di archiviazione è notevole, la quantità di traffico che ottengono è un buon problema.


Caspita, hai affrontato tutto alla grande! Grazie Robert! Il database è normalizzato ma non ho ancora esaminato l'indicizzazione. Sfortunatamente, non posso "parlare con qualcuno che può aiutarmi", in quanto i termini sono severi sul fatto che non posso discutere dettagli specifici del progetto con nessuno e il cliente è arrivato al punto da non fidarsi di nessuno ma io sul progetto ... Beh, dovrei essere in grado di fare qualche ricerca sull'indicizzazione. Grazie!
user45623,

1
Regole generali per l'indicizzazione: ogni chiave esterna deve essere indicizzata con duplicati possibili. Ogni chiave primaria dovrebbe già essere indicizzata. I campi su cui dovrai cercare o applicare una clausola WHERE dovrebbero essere indicizzati; quelli dovrebbero essere pochi.
Robert Harvey,

1
Questo non è corretto Questo NON è scalabile. Per ogni "Sally" stai generando N righe dove N è il tuo numero di utenti. Questo diventerà rapidamente un problema se hai un numero ragionevole di utenti. 100 post "Sallys" 10 volte su 10.000 utenti sono 10 milioni di righe al giorno - non suona troppo bene eh? Quello che vuoi veramente fare è invertire questo e creare una riga per post "Sally" e fare in modo che tutti gli utenti che seguono Sally li prendano invece della loro copia personale. Naturalmente questo causerà problemi se hai bisogno di una logica specifica dell'utente (ad es. Aggregazione) ...
Ben

1
... la spiegazione "evitare una riga per post" qui è ovviamente un uomo di paglia in quanto la maggior parte dei sistemi richiederà che questi post rimangano. Inoltre, non si evitano le query "perché sono complicate", si evitano perché causeranno sovraccarico insostenibile man mano che il sistema si ridimensiona.
Ben
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.