Quale archivio dati è il migliore per il mio scenario?


10

Sto lavorando su un'applicazione che prevede l'esecuzione molto elevata 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 ogni giorno a mezzanotte.

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 e a mezzanotte archivio i dati storici su HBase. Questa configurazione funziona bene e finora non ho riscontrato problemi di prestazioni.

Di recente 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 nella tabella B per tutti gli utenti. Anche se cambiano solo 20 record master, devo eseguire il ricalcolo e aggiornare 200.000 record utente che richiedono più di 20 secondi e, a quel punto, si verifica il successivo aggiornamento che alla fine fa sì che tutte le query Select vengano messe in coda. Ricevo circa 3 richieste di ricezione / 5 secondi dagli utenti online, che si traducono in 6-9 Seleziona query. 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 adeguatamente ridimensionato in grado di gestire anche un milione di utenti.

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


Hai davvero bisogno di archiviare tutti quei dati? Questo suona in qualche modo come se fosse meglio calcolare su richiesta. Se riesci a calcolare 200.000 record in poco più di 20 secondi, dovrebbe essere possibile calcolare quei 20 record * 3 utenti = 60 record in pochissimo tempo. Forse potresti vedere quali utenti sono online in quel momento e ottimizzare ancora di più? Sembra che tu stia generando tonnellate di dati che nessuno usa mai (durante il periodo in cui i dati sono ancora validi almeno)
thorsten müller

Generare solo per gli utenti che hanno effettuato l'accesso è un'ottima opzione. Ci ho pensato anche io, ma non è ancora un approccio abbastanza scalabile. La mia piattaforma verrà utilizzata solo durante il giorno e quindi durante tale periodo la maggior parte degli utenti sarà attiva. Qualche altro suggerimento amico?
Brocche

@Jugs - Ciò lascia ancora la questione se puoi semplicemente calcolare al volo. Non si deve aggiornare i record, o fa l'applicazione solo bisogno dei dati di essere lì?
Bobson,

Temo di non poter calcolare al volo poiché la tabella delle voci B è classificata per un utente (da 5 stelle a 1 stella) e dopo aver fatto questi calcoli, facciamo di nuovo la classifica per l'utente. L'intero processo per un utente richiede 500 msec e, se lo faccio al volo, influirà sui tempi di risposta dell'API
Brocche

Stavo pensando se ha senso archiviare i punteggi e le classifiche al di fuori di RDBMS potrebbero trovarsi in un db nosql in modo che le istruzioni selezionate continuino a funzionare senza alcun singhiozzo, tuttavia a volte ho bisogno di interrogare su punteggi e classifiche. Quindi al momento mi sento un po 'perso ed è per questo che sto cercando consigli da alcuni esperti come voi ragazzi
Brocche

Risposte:


1

Sembra che la tabella Bsia una specie di cache. Ma quel tipo di cache che riduce la produttività ..

Anche se hai 25 query al secondo, puoi rifiutare l'utilizzo della tabellaB e calcolare la risposta per ogni richiesta.

Ad ogni modo , se si ha un ritardo di 30 secondi sull'aggiornamento di 20 record - si tratta di un errore in un'architettura software (sbaglio, se il DB calcola i primi 10 ^ 100 segni di PI per ogni record).

Come so, 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 Be aggiungi gli indici appropriati alla tabella A(la maggior parte dei database moderni ha uno strumento di supporto). Successivamente: prova a ottimizzare la struttura dei dati (tabella A) e una query (utilizzando l'analizzatore di query o con esperti SQL) per accelerare il calcolo. Se aggiornerai solo 20 record, l'esistenza di indici non danneggerà la produttività di un processo di aggiornamento , ma migliorerà significativamente la velocità di selezione .


1

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

Qualsiasi database (ad esempio MSSQL) dovrebbe essere in grado di gestire il volume di inserti di cui stai parlando senza problemi, supponendo che l'oggetto non sia enorme.

Gli aggiornamenti possono presentare un problema più difficile, ma con l'indicizzazione e il blocco corretti, non dovrebbe essere un grosso problema.

Il 99% delle volte quando 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

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

Quindi il tuo messaggio di aggiornamento A attiverebbe un processo di lavoro che attraverserebbe gli utenti e creerebbe un messaggio di aggiornamento B per ciascun utente

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

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

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


0

Se si esegue su Amazon, prenderei in considerazione DynamoDB. È basato sulla memoria flash. Ecco un link ad esso: https://aws.amazon.com/dynamodb/ .

Che tipo di RDBMS stai usando? È possibile aumentare le prestazioni utilizzando un 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 l'utilizzo dell'esecuzione in modalità snapshot, il che significa che le righe non sono bloccate durante l'aggiornamento e le selezioni simultanee ottengono il valore originale. SQL Server è configurato per impostazione predefinita con concorrenza pessimistica, quindi 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, prova a mettere i file di dati DB sul disco flash locale. Ho visto un ordine di differenza di grandezza nel spostare i file da EBS sul disco locale.

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.