2015-08-08 14 views
9

Ho progettato seguente tabella per gli allarmi negozio di server:tavoli modellazione Cassandra per upsert e query di selezione

create table IF NOT EXISTS host_alerts(
    unique_key text, 
    host_id text, 
    occur_time timestamp, 
    clear_time timestamp, 
    last_occur timestamp, 
    alarm_name text, 
    primary key (unique_key,host_id,clear_time) 
); 

Entriamo alcuni dati:

truncate host_alerts; 

insert into host_alerts(unique_key,host_id,alarm_name, 
    clear_time,occur_time,last_occur 
) 
values('1','server-1','disk failure', 
'1970-01-01 00:00:00+0530','2015-07-01 00:00:00+0530','2015-07-01 00:01:00+0530'); 

insert into host_alerts(unique_key,host_id,alarm_name, 
    clear_time,occur_time,last_occur 
) 
values('1','server-1','disk failure', 
'1970-01-01 00:00:00+0530','2015-07-01 00:00:00+0530','2015-07-01 00:02:00+0530'); 

insert into host_alerts(unique_key,host_id,alarm_name, 
    clear_time,occur_time,last_occur 
) 
values('1','server-1','disk failure', 
'2015-07-01 00:02:00+0530','2015-07-01 00:00:00+0530','2015-07-01 00:02:00+0530'); 

La query mia applicazione sarà in esecuzione sono:

//All alarms which are **not cleared** for host_id 
select * from host_alerts where host_id = 'server-1' and clear_time = '1970-01-01 00:00:00+0530'; 

//All alarms which are cleared for host_id 
select * from host_alerts where host_id = 'server-1' and clear_time > '2015-07-01 00:00:00+0530'; 

//All alarms between first occurrence 
select * from host_alerts where host_id = 'server-1' 
and occur_time > '2015-07-01 00:02:00+0530'and occur_time < '2015-07-01 00:05:00+0530'; 

Non so se dovrei preparare altro esempio di tabella: host_alerts_by_hostname o host_alerts_by_cleartime e così via o semplicemente aggiungere indice di clustering. Come ID univoco è l'unica colonna unica, ma ho bisogno di retrive i dati da altra colonna

allarmi non compensati: '1970-01-01 00: 00: 00 + 0530' evento eliminato ha una data valore.

HOST_ID è il nome del server

occur_time è quando l'evento si è verificato.

last_occur è l'ora in cui l'evento si ripresenta nuovamente.

alarm_name è ciò che è successo con il sistema.

Come posso modellare la tabella in modo che sia possibile eseguire queste query e aggiornare in base a unique_id? Con quello che ho provato selezionare non è possibile e durante upsert viene creata una nuova riga per lo stesso unique_key.

risposta

5

Penso che probabilmente servano tre tabelle per supportare i tre tipi di query.

La prima tabella sarebbe a favore di un raggio d'azione di tempo sulla storia di quando avvisi accaduto per ogni host:

CREATE TABLE IF NOT EXISTS host_alerts_history (
    host_id text, 
    occur_time timestamp, 
    alarm_name text, 
    PRIMARY KEY (host_id, occur_time) 
); 

SELECT * FROM host_alerts_history WHERE host_id = 'server-1' AND occur_time > '2015-08-16 10:05:37-0400'; 

La seconda tabella sarebbe tenere traccia degli allarmi non liquidati per ogni host:

CREATE TABLE IF NOT EXISTS host_uncleared_alarms (
    host_id text, 
    occur_time timestamp, 
    alarm_name text, 
    PRIMARY KEY (host_id, alarm_name) 
); 

SELECT * FROM host_uncleared_alarms WHERE host_id = 'server-1'; 

L'ultima tabella tiene traccia di quando gli avvisi sono stati cancellati per ciascun host:

CREATE TABLE IF NOT EXISTS host_alerts_by_cleartime (
    host_id text, 
    clear_time timestamp, 
    alarm_name text, 
    PRIMARY KEY (host_id, clear_time) 
); 

SELECT * FROM host_alerts_by_cleartime WHERE host_id = 'server-1' AND clear_time > '2015-08-16 10:05:37-0400'; 

Quando un nuovo evento di allarme arriva, ci si esegue questo lotto:

BEGIN BATCH 
INSERT INTO host_alerts_history (host_id, occur_time, alarm_name) VALUES ('server-1', dateof(now()), 'disk full'); 
INSERT INTO host_uncleared_alarms (host_id, occur_time, alarm_name) VALUES ('server-1', dateof(now()), 'disk full'); 
APPLY BATCH; 

Nota che l'inserto nella tabella non liquidati è un upsert, dal momento che il timestamp non è parte della chiave. Quindi quella tabella avrà una sola voce per ogni nome di allarme con un timestamp dell'ultima occorrenza.

Quando un evento di allarme arriva chiara, che ci si esegue questo lotto:

BEGIN BATCH 
DELETE FROM host_uncleared_alarms WHERE host_id = 'server-1' AND alarm_name = 'disk full'; 
INSERT INTO host_alerts_by_cleartime (host_id, clear_time, alarm_name) VALUES ('server-1', dateof(now()), 'disk full'); 
APPLY BATCH; 

non ho davvero capire che cosa il vostro "unique_key" sia o da dove proviene. Non sono sicuro che sia necessario poiché la combinazione di host_id e alarm_name dovrebbe essere il livello di granularità con cui si desidera lavorare. L'aggiunta di un'altra chiave univoca al mix potrebbe dar luogo a molti eventi di allarme/cancellazione ineguagliati. Se unique_key è un ID di allarme, utilizzarlo come chiave al posto di alarm_name nel mio esempio e avere alarm_name come colonna di dati.

Per evitare che le tabelle si riempiano nel tempo di dati obsoleti, è possibile utilizzare la funzione TTL per eliminare automaticamente le righe dopo diversi giorni.

+0

grazie per la bella risposta unique_key è la chiave casuale generata in rdbms. cassandra ha funzionalità per replicare automaticamente i dati tra le tabelle? Devo controllare ogni volta il campo clear_time, non rallenterà le prestazioni? Inoltre, terzo penso che vuoi dire occurr_time ?? – kinkajou

+0

Come faccio questo per 100-1000 allarmi al secondo? – kinkajou

+0

Cassandra 3.0 supporta le visualizzazioni materializzate per propagare i dati da una tabella a un'altra, ma quella versione non sarà disponibile per un po 'di tempo. Non capisco cosa intendi per controllare ogni volta clear_time. Si vuole evitare di fare una lettura prima di scrivere in Cassandra poiché ridurrà notevolmente il throughput delle transazioni. –

Problemi correlati