Near analytics in tempo reale da Cassandra con frequenti aggiornamenti

0

Abbiamo una pagina delle metriche di attività in cui gli utenti possono selezionare un periodo di date e vedere l'attività aggregata di altri utenti (per azione) e opzionalmente filtrare tutto con 4 o 5 campi. Le azioni avvengono in sequenza, ma uno dei campi è "Tag" e l'utente può modificare i tag della vecchia azione in qualsiasi momento. I dati sono in una Cassandra 3.7 con la chiave di partizione che è company_id, action_year, action_week. Per ogni settimana abbiamo circa 70.000 azioni (ci sono 20 colonne con dati long o int per ogni azione, ogni azione con la chiave di partizione più action_timestamp e action_key come chiave di riga).

PRIMARY KEY ((company_id, action_year, action_week), action_date, action_key) ) WITH CLUSTERING ORDER BY (action_date ASC, action_key ASC)

Con una prima versione stiamo interrogando le azioni complete per un periodo e facendo tutte le aggregazioni e il filtraggio in memoria. Quando l'utente seleziona un paio di settimane, l'intera richiesta richiede 10 o 15 secondi. E ci aspettiamo di scalare a migliaia di utenti che richiedono queste analisi che dovrebbero funzionare come analisi quasi in tempo reale.

Abbiamo pensato di spostare il filtro su C * usando "allow filtering", ma la clausola WHERE sembra molto limitata. E siamo anche preoccupati per i frequenti aggiornamenti delle etichette.

Quali altre opzioni abbiamo? Abbiamo pensato a Druid, ma forse è troppo per quello di cui abbiamo bisogno. Spark forse? Non stiamo usando C * giusto e potremmo aver bisogno di memorizzare le settimane intere altrove?

    
posta Federico Pugnali 27.10.2016 - 21:55
fonte

1 risposta

1

Prima di tutto ti consiglio vivamente di prendere questo corso di modellazione dati da Datastax . Sostengono che occorrono 12 ore, ma a seconda della tua esperienza precedente potrebbe richiedere meno. Vale la pena dedicare il tuo tempo se stai lottando con problemi come questo.

In secondo luogo, ALLOW FILTERING è quasi sempre una cattiva idea. È utile in un numero limitato di casi d'uso, ma magicamente rendere le query già lente più velocemente non è una di quelle.

Quando ho insegnato la modellazione dei dati in Cassandra, i programmatori di problemi hanno difficoltà a sopportare il fatto che Cassandra scambia spazio per la velocità. Se vuoi una velocità decente, hai bisogno di tabelle personalizzate per ogni query e finirai con diversi duplicati di ogni record. Questo è particolarmente difficile da comprendere per i programmatori abituati ai database relazionali, in cui si cerca di evitare la duplicazione il più possibile.

Ciò significa che l'aggiunta di un tag a un record dovrebbe in genere finire con la creazione di una nuovissima partizione con dati duplicati in una tabella separata con una chiave primaria come:

PRIMARY KEY ((company_id, action_year, action_week, tag), action_date, action_key)
) WITH CLUSTERING ORDER BY (action_date ASC, action_key ASC)

Se hai altre colonne comuni filtrate, come forse action_key , quelle colonne dovrebbero essere nella chiave di partizione in una tabella quasi duplicata. Stai scambiando scritture extra per letture efficienti. Lo stesso per gli aggregati. Fatelo al momento della scrittura, se possibile. Se non puoi evitare di filtrare in memoria, fai tutto il possibile per rendere le tue partizioni il più vicino possibile al tuo risultato finale.

Buona fortuna. Cambiare la tua mentalità di modellazione dei dati in quella di Cassandra può essere inizialmente un problema, ma ne vale la pena.

    
risposta data 27.10.2016 - 23:59
fonte

Leggi altre domande sui tag