2009-04-12 14 views
8

L'azienda per cui lavoro crea applicazioni per la piattaforma Blackberry.Il modo migliore per progettare un sistema di analisi/analisi scalabile?

Abbiamo lavorato su un "sistema di analisi" proprietario che ci consente di incorporare il codice all'interno delle nostre applicazioni e che le applicazioni riportino alcune statistiche ai nostri server centrali ogni volta che vengono eseguite. Attualmente, il sistema funziona correttamente; tuttavia è solo in beta con 100-200 hit all'ora. Gli "hit" vengono inviati ai server senza problemi. Abbiamo costruito un'API molto solida per gestire l'accettazione e l'archiviazione degli hit (in un DB MySQL). Abbiamo testato il carico e dovremmo essere in grado di ospitare centinaia di migliaia di accessi all'ora senza problemi. Questo non è davvero un problema.

Il problema sta mostrando le statistiche. Abbiamo creato un pannello di visualizzazione simile a quello di Mint (haveamint.com), mostra gli hit su ogni ora, i giorni passati, i mesi, le settimane, gli anni ... ecc. La versione pugno eseguiva direttamente query che estraevano i dati dalla tabella degli hit e li interpretavano al volo. Questo non ha funzionato a lungo. La nostra soluzione attuale è che i successi sono "in coda" per l'elaborazione e abbiamo un cron ogni 5 minuti che prendono gli hit e li ordinano in "cache" per ogni ora, giorno, settimana, mese, anno ... ecc. Questo funziona incredibilmente ed è incredibilmente scalabile; tuttavia, funziona solo per 1 fuso orario. Poiché l'intera azienda ha accesso a questo, abbiamo a che fare con poche centinaia di utenti in vari fusi orari. Quello che definisco "Oggi" a San Jose è MOLTO diverso da quello che il mio collega di Londra definisce oggi. Poiché la soluzione corrente è memorizzata solo su 1 fuso orario, è un incubo per chiunque controlli i dati al di fuori del nostro fuso orario.

Il nostro piano attuale per risolvere questo problema è creare cache per ogni fuso orario (40 in totale); tuttavia, ciò significherebbe che stiamo moltiplicando la quantità di dati per 40 ... questo è terribile per me e dato che le cache possono essere molto grandi, moltiplicarle suona come una cattiva idea; Inoltre, quando andremo ad elaborare la coda, ci vorrà molto più tempo della CPU per metterli in 40 cache differenti.

Qualcun altro ha un'idea migliore di come risolvere questo problema?

(Ci scusiamo per un lungo question..it tale non è esattamente facile da spiegare. Grazie a tutti!)

+0

Per quanto specifica sia la tua domanda, in realtà sto progettando qualcosa di molto simile e stavo per venire qui per l'input. +1 –

+0

Sarebbe molto interessante vedere l'API di gestione degli errori/memorizzazione :) – Jacco

risposta

4

La soluzione che si propone ha troppa ridondanza. Ti suggerirei di archiviare i dati in bucket di almeno 30 minuti invece di ogni ora e il fuso orario essere normalizzato in UTC.

Con intervalli di 30 minuti, se un utente richiede dati orari per 1 - 2PM da -4,5 UTC è possibile recuperare i dati per 5:30 - 6:30 PM dal sistema e mostrarli. Se si memorizzano i dati in incrementi di un'ora, non è possibile soddisfare le richieste agli utenti in fusi orari con differenze di N + 0,5 ore.

Per i numeri giornalieri è necessario aggregare 48 intervalli di mezz'ora. Gli slot da selezionare sarebbero determinati dal fuso orario dell'utente.

Diventa interessante quando si arriva ai dati annuali perché si finisce per dover aggregare 17.520 secchi mezz'ora. Per semplificare tale calcolo, suggerisco di ottenere i dati annuali pre-aggregati per ora UTC e di sottrarre i dati aggregati per il primo per 4,5 ore all'anno e aggiungere dati aggregati per le prime 4,5 ore dell'anno successivo. Questo cambierà sostanzialmente l'intero anno di 4,5 ore e il lavoro non è molto. Lavorando da qui, puoi modificare ulteriormente il sistema.

MODIFICA: Si scopre che Kathmandu è +5.45 GMT, quindi è necessario archiviare i dati in bucket di 15 minuti anziché in secchi di 30 minuti.

MODIFICA 2: Un altro facile miglioramento riguarda l'aggregazione annuale, quindi non è necessario aggiungere 17,520 bucket ogni volta e senza richiedere un aggregato per paese. Aggrega i dati annuali dal 2 gennaio al 30 dicembre. Poiché la differenza massima di fuso orario tra due paesi è di 23 ore, ciò significa che puoi prendere i dati annuali (2 gennaio - 30 dicembre) e aggiungere alcuni secchi prima e dopo come appropriato. Ad esempio per un fuso orario di -5 UTC si aggiungeranno tutti i bucket il 01 gennaio dopo il 0500, tutti i bucket il 31 dicembre e il 01 gennaio dell'anno successivo fino alle 0500 ore.

+1

+1 per discussioni sulla dimensione della benna – lpfavreau

+1

Questa sembra l'opzione migliore. Secchi di 15 minuti potrebbero non valerne la pena visto che solo una piccolissima quantità di persone occuperà quei fusi orari. –

2

Quando si progetta un software che tocca più fusi orari, direi per memorizzare sempre la data/orari in UTC con un altro campo per il fuso orario originale e avere una funzione che impiega il tempo e la converte in e da UTC/fuso orario. Ti risparmierai un sacco di problemi per gestire i diversi casi di cambio di giorno, l'ora legale, le persone che guardano le statistiche da un paese dall'altra parte della terra e così via ...

Nel tuo caso, avere le cache in UTC e solo la regolazione delle richieste da convertire in UTC dovrebbe aiutare. Non memorizzare una statistica come "oggi", memorizzarla per ore 00: 00: 00UTC a 23: 59: 59UTC e quando qualcuno chiede le statistiche per oggi a New York, effettuare la conversione.

+0

Non vedo qui un motivo di upvote. In realtà non si tratta di come ottenere dati giornalieri per New York perché non è possibile spostare il giorno 5 ore. Hai bisogno dei dati per le precedenti 5 ore e devi sottrarre le ultime 5 ore come suggerito nella mia soluzione. – aleemb

+0

Non ho mai parlato della dimensione del secchio in questa soluzione. Sto solo dicendo di fare i bucket in UTC dalle 00:00 alle 23:59 invece in ora locale. Dato che non ci sono abbastanza dettagli su quali statistiche sono proposte nell'interfaccia utente, non è possibile proporre una dimensione del bucket definitivo. – lpfavreau

+0

@aleemb: Non c'è alcun motivo per downvote sia come si propone la stessa cosa ma ampliata la discussione sulla dimensione dei secchi, che è grande. – lpfavreau

0

Per quanto posso vedere, si sta cercando la parte di archiviazione di un sistema di data warehouse qui (i report sarebbero il front-end).

In realtà, il modo in cui i sistemi commerciali lo fanno, è la cache che hai descritto: Preaggrega le tue tabelle e crea loro delle cache. L'unico modo per accelerare le tue query è rendere il sistema di database meno utile per loro. Ciò significa meno dati, che a loro volta significano meno tempo speso per iterare i dati o meno dati negli indici.

Detto questo, vorrei proporre la "soluzione cache 40" (ci sono davvero più di 24 fusi orari). Dovresti essere in grado di parallelizzare banalmente la coda di ordinamento creando copie dei dati.

Un altro modo per eseguire questa operazione è la cache alla granularità dell'ora e quindi l'aggregazione delle ore in giorni (o 30 minuti se i tuoi fusi orari lo richiedono). Ciò significa che la cache è più granulare della cache giornaliera ma con una granularità più grossolana rispetto ai dati originali.

Problemi correlati