Progetta un sistema basato sul pubblico

2

Sfondo

Ho progettato un'applicazione per social media (come Facebook) in cui è presente questo concetto strong di contenuti basati sul pubblico .

Ad esempio, supponiamo che questo utente A possa creare post (pubblici, privati o solo gruppi), in base a tale configurazione, il post sarà disponibile solo per quel pubblico.

Soluzione

Quello che ho fatto, è solo per costruire relazioni utenti-post, e quindi possiamo cercare quelle relazioni e vedere se quel contenuto è o meno disponibile. Tuttavia, questo ha funzionato bene per piccoli sottoinsiemi di utenti, perché nel tempo, i gruppi sono diventati più grandi (500 utenti o più) e quindi si desidera interrogare i post disponibili per un sottoinsieme di gruppi e facendo questi si unisce dura per sempre E sì, abbiamo il database correttamente indicizzato, ma sembra che abbiamo un grosso problema qui, forse un problema di progettazione?

Configurazione

Abbiamo pensato che all'inizio un database SQL sarebbe stato il migliore, alcune persone hanno parlato di Neo4js ma, onestamente, all'epoca sembrava troppo complicato per l'MVP, quindi lo scartiamo, sto pensando ora che un DB grafico può risolvere il nostro problema, o forse no, è per questo che ho bisogno di qualcuno che abbia vissuto una situazione simile come questa.

IL Problema

Come ho detto prima, questa soluzione ha funzionato bene, ma alla fine la community sta crescendo così velocemente, ora gli utenti hanno più gruppi e per calcolare il pubblico per un determinato post è un compito pesante, poiché i post possono avere più pubblico:

  • Privato
  • Pubblico (pubblico attuale dell'utente)
  • Solo gruppi
  • Pubblico dell'amico

E, per un dato utente, cosa è visibile per lui?

Quindi, qual è l'approccio migliore per rendere questo sistema completamente scalabile per un sistema ad alto traffico?

    
posta Marcelo Dañares 16.03.2018 - 16:15
fonte

2 risposte

1

Potresti scoprire che questa è una risorsa utile:

Progettazione di applicazioni ad alta intensità di dati: le grandi idee dietro sistemi affidabili, scalabili e manutenibili

link

Discute ad alto livello su come Twitter ha affrontato un problema simile.

È una buona lettura. Nel frattempo, spero che il seguito possa aiutarti nel tuo viaggio:

Vedo che questo è taggato con OOP. Questa è più una questione di tecnologia / design di database. Un database RDBMS ben sintonizzato può probabilmente portarti lontano, ma dovresti prendere in considerazione una combinazione di elaborazione batch e aggiornamenti db in tempo reale. Ciò richiederà trade off che sono unici per la tua applicazione: un post di un amico può essere posticipato di secondi, minuti o ore? mantieni i dati che gli utenti scoprono che i dati di valore elevato scorrono rapidamente e rallentano i dati di valore inferiore.

What I did, is just to build relationships users-posts, and then we can look up those relationships and see if that content is or not available.

Questo deve evolversi come base utente & l'uso cresce

Alcune cose da considerare:

Hai de-normalizzato la tua relazione post-utente. questo è destinato a causare problemi di scala. Anche gli utenti che si registrano, ma non visualizzano i contenuti, ti costano spazio, perf e $$. come relazioni utente tra gruppi, & gli amici cambiano, la necessità di modificare i dati nella tabella di Thins potrebbe essere complicata.

Considera l'archiviazione dei dati in un modo che rappresenti il modo in cui hai descritto il tuo modello di dominio:

  • Post pubblici (post-id - post-data)
  • Post utente (user-id post-id, post-data)
  • Post di amici (id utente post-id, post-data)
  • Post di gruppo (id-id di gruppo, post-data)

In questo modo la relazione di un utente con amici e gruppi avrà un impatto su ciò che vedono. (che è probabilmente ciò che gli utenti si aspettano). Inoltre, considera ciò che una tabella dei post pubblici significherebbe per la riduzione dei dati e la necessità di scrivere e scrivere nel database.

Fai del caching un problema di prima classe.

Hai esaurito le opportunità di memorizzazione nella cache sul server, sul client e su tutti i livelli dell'applicazione. Se lo hai, esauriscile ulteriormente. Un modo efficace per ridurre il problema del DB-come-bottleneck consiste nel licenziare il DB il più possibile.

  • Puoi memorizzare nella cache dei post "pubblici" recenti?
  • Puoi memorizzare nella cache recenti & post popolari di "gruppi" in memoria?
  • Puoi identificare gruppi comuni con alti tassi di lettura?

Se il tuo sistema può acquisire dati da una combinazione di dati memorizzati nella cache e risultati SQL, sarai molto più in forma. Ancora meglio se si combinano i dati con i dati memorizzati nella cache nel browser.

Considerare i modi in cui il sistema può raccogliere rapidamente i dati memorizzati nella cache e aumentare il lato client con il db più lento. ex: - Carica post comuni (operazione sincrona) dalla cache. - Inizia a raccogliere post personalizzati (gruppi / amici), - esegue il rendering dell'interfaccia utente - L'interfaccia utente riceve i post personalizzati e aggiorna l'interfaccia utente. - L'interfaccia utente può memorizzare nella cache post personalizzati per richieste future.

Può aiutare ad aumentare la sensazione di un tempo di caricamento veloce e a ridurre la necessità di recuperare i dati di dame dal database attraverso le richieste,

Un altro suggerimento: assicurati di conoscere i modelli di utilizzo dei tuoi utenti. Alcuni di questi suggerimenti non hanno senso se si considera la frequenza con cui vengono pubblicati i post.

Considera di memorizzare quali operazioni di lettura e scrittura è necessario eseguire, per cercare modelli comuni.

Verifica come si stanno formando le amicizie

  • Se la maggior parte delle persone ha 10 amici, e progetti e collaudi per questo, ma i valori anomali hanno 100.000 cose brutte potrebbero accadere.

  • Può anche avere un impatto sulla cache e regole che impediscono agli utenti di incasinare la cache per tutti gli altri. Oppure, magari provvedendo a quei valori anomali

Infine, consiglierei di raccogliere dati sulle prestazioni reali.

  • Benchmark
  • Migliora
  • Benchmark
  • Migliorare

Quando un grande sistema che ha esigenze specifiche di rendimento, solo le modifiche che puoi dimostrare hanno un impatto dimostrabile. Renderà il tuo codice più complicato. Assicurati di introdurre complessità (e costi di manutenzione) per i benefici per i tuoi utenti. Lanciare la complessità di un problema che potrebbe aiutare gli utenti è un modo sicuro per creare un sistema che preferiresti non mantenere.

    
risposta data 15.04.2018 - 22:54
fonte
0

Il problema è intrinsecamente non scalabile a meno che non si limiti il numero di gruppi di destinatari.

Se ho solo 10 utenti ci sono fino a 3628800 diversi possibili gruppi di destinatari.

Ogni post sarà in un singolo gruppo di destinatari

Ogni utente sarà membro di più gruppi di destinatari.

Nel tempo gli utenti si conoscono e si disimpegnano a vicenda creando sempre più gruppi di destinatari anche se la base utente rimane statica.

Per vedere il loro feed l'utente deve interrogare tutti i gruppi di destinatari di cui sono membri. Che è effettivamente illimitato.

La tua unica speranza è limitare il numero totale di gruppi, ma ciò richiede la collaborazione di tutti gli utenti. Semplicemente non funziona con il concetto di 'friending'

Ad esempio. Dire che posso essere un massimo di 2 gruppi (che già sono) e un nuovo utente mi amici. Questo creerebbe un nuovo gruppo di tutti i loro amici + me. A meno che tutti i loro amici non siano già miei amici, non posso essere questo amico di persone in quanto mi metterebbe in 3 gruppi.

Puoi consentire ai nuovi "amici" di vedere tutti i vecchi post di un utente, limitando essenzialmente ogni utente a un gruppo di destinatari. Ma posso ancora essere amico di tutti e controllare tutti i gruppi di destinatari per i nuovi post

Potresti pre-definire i gruppi, dire che ogni città ottiene un gruppo. puoi postare in una città, ma chiunque entri a far parte della città potrà vedere tutti i post pubblicati su quel gruppo di città.

Puoi mettere offline il processo di pubblicazione dei post agli utenti (come email), invece di interrogare i loro gruppi un utente interroga il loro feed e un processo di backend scorre tra i nuovi post, ottiene i gruppi di destinatari e copia il post in ogni feed. Ciò accelera il caricamento della pagina degli utenti, ma non è scalabile, in quanto ritarda la consegna dei messaggi. Inoltre memorizza più copie dello stesso post.

Essenzialmente Facebook è l'e-mail, dove ognuno ha un server e-mail e tu esegui tutti i server

    
risposta data 16.03.2018 - 16:44
fonte

Leggi altre domande sui tag