Quale archivio dati è migliore per il mio scenario?

10

Sto lavorando a un'applicazione che implica l'esecuzione molto alta di query di aggiornamento / selezione nel database.

Ho una tabella di base (A) che avrà circa 500 record per un'entità per un giorno. E per ogni utente nel sistema, una variazione di questa entità viene creata in base ad alcune delle preferenze dell'utente e sono memorizzate in un'altra tabella (B). Questo viene fatto da un cron job che viene eseguito a mezzanotte tutti i giorni.

Quindi se ci sono 10.000 utenti e 500 record nella tabella A, ci saranno 5 milioni di record nella tabella B per quel giorno. Conservo sempre i dati per un giorno in queste tabelle ea mezzanotte archivo i dati storici su HBase. Questa configurazione funziona correttamente e non ho problemi di prestazioni fino ad ora.

Ultimamente sono stati apportati alcuni cambiamenti ai requisiti aziendali e ora alcuni attributi nella tabella di base A (per 15-20 record) cambieranno ogni 20 secondi e in base a ciò devo ricalcolare alcuni valori per tutti quei record di variazione in tabella B per tutti gli utenti. Anche se cambiano solo 20 record master, devo eseguire il ricalcolo e aggiornare 200.000 record utente che impiegano più di 20 secondi e, a quel punto, si verificherà il prossimo aggiornamento, con il risultato che tutte le query Select vengono accodate. Sto ricevendo circa 3 richieste di ottenere / 5 secondi dagli utenti online che si traducono in 6-9 richieste di selezione. Per rispondere a una richiesta API, utilizzo sempre i campi nella tabella B.

Posso acquistare più potenza di elaborazione e risolvere questa situazione, ma sono interessato ad avere un sistema correttamente dimensionato in grado di gestire anche un milione di utenti.

Qualcuno qui può suggerire un'alternativa migliore? Il database relazionale nosql + mi aiuta qui? Ci sono piattaforme / datastore che mi permettono di aggiornare i dati frequentemente senza bloccare e allo stesso tempo mi danno la flessibilità di eseguire query selezionate su vari campi di un'entità?

    
posta Jugs 02.11.2015 - 09:33
fonte

3 risposte

1

Sembra che la tabella B sia una sorta di cache. Ma quel tipo di cache che riduce la produttività ..

Anche se hai 25 query al secondo potresti rifiutare l'utilizzo della tabella B e calcolare la risposta per ogni richiesta.

Ad ogni modo , se hai un ritardo di 30 secondi sull'aggiornamento di 20 record - è un errore in un'architettura software (ho torto, se il tuo DB calcola i primi 10 ^ 100 segni di PI per ogni record ).

Come noto, il DB relazionale senza brutte query SQL, con indici e con meno di 1 000 000 di record funzionerà perfettamente per quasi tutte le query.

Prova a rifiutare l'uso della tabella B e aggiungi indici appropriati alla tua tabella A (la maggior parte dei database moderni ha uno strumento di supporto). Successivo: prova ad ottimizzare la struttura dei dati (tabella A ) e una query (utilizzando l'analizzatore di query o con esperti SQL) per accelerare il calcolo. Se aggiorna solo 20 record - l'esistenza di indici non danneggerà la produttività di un aggiornamento processo, ma migliora significativamente seleziona velocità.

    
risposta data 21.11.2015 - 02:10
fonte
1

La domanda è in realtà quale sistema calcola il record da inserire in B e la dimensione dei dati B.

Qualsiasi database (ad es. MSSQL) dovrebbe essere in grado di gestire il volume degli inserti di cui si sta parlando senza problemi, assumendo che l'oggetto non sia enorme.

Gli aggiornamenti possono essere causati da un problema più difficile, ma con l'indicizzazione e il blocco corretti, di nuovo non dovrebbe esserci un grosso problema.

Il 99% del tempo in cui vedo un problema come questo è dovuto al fatto che il record B viene calcolato da un proc memorizzato. Questo mette tutto il carico sul server db

Se questo è il caso, la soluzione è spostare questo codice su un servizio offline che può essere chiamato tramite un sistema di accodamento.

Quindi il tuo messaggio di aggiornamento A attiverà un processo di lavoro che passerà in loop tra gli utenti e creerà un messaggio di aggiornamento B per ciascun utente

Un secondo processo di lavoro B raccoglierà l'utente X di aggiornamento con i dati Un evento crea il record B e aggiorna il DB

Questo può essere ridimensionato aggiungendo più caselle con i lavoratori della coda, in modo da avere sempre più potenza di elaborazione dietro il calcolo, lasciando il db libero di concentrarsi sugli aggiornamenti e selezionare.

puoi ottimizzare ulteriormente separando i selezioni dall'aggiornamento / inserti. avere un nuovo DB che ottiene tutte le richieste selezionate come slave di replica del vecchio DB che riceve tutti gli aggiornamenti.

    
risposta data 15.01.2016 - 11:51
fonte
0

Se stai usando Amazon, prenderei in considerazione DynamoDB. Si basa sulla memoria flash. Ecco un link: link .

Che tipo di RDBMS stai usando? Potrebbe essere possibile aumentare le prestazioni utilizzando una UDF o un campo calcolato in una vista. Stai eseguendo il calcolo nel database tramite una singola query di aggiornamento, o selezioni i dati dal database, esegui i calcoli in un altro processo e poi li carichi di nuovo?

Oracle è configurato per impostazione predefinita per utilizzare l'esecuzione della modalità snapshot, ovvero le righe non vengono bloccate durante l'aggiornamento e i selettori simultanei ottengono il valore originale. SQL Server è configurato per impostazione predefinita con una concorrenza pessimistica, pertanto le selezioni simultanee verranno bloccate fino al completamento dell'aggiornamento. Alcune versioni di SQL Server possono essere messe in modalità snapshot, tuttavia aumenta notevolmente lo stress sulla tabella temporanea.

In che tipo di ambiente stai correndo? Se si tratta di un RDBMS su un'istanza EC2 in Amazon, provare a inserire i file di dati DB sul disco flash locale. Ho notato una differenza di ordine di grandezza nello spostamento dei file da EBS al disco locale.

    
risposta data 09.12.2015 - 18:15
fonte

Leggi altre domande sui tag