2015-08-08 11 views
9

Mam zaprojektowane poniższą tabelę do alarmów serwera sklep:modelowanie Cassandra stoły do ​​upsert i kwerendy wybierającej

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) 
); 

Niech podać dane:

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'); 

Zapytanie moja aplikacja zostanie uruchomiony to:

//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'; 

Nie wiem, czy powinienem przygotować więcej przykładu tabeli: host_alerts_by_hostname lub host_alerts_by_cleartime i tak dalej lub po prostu dodać indeks klastrowania. jako unikatowy identyfikator jest tylko unikalna kolumna ale muszę sprowadzaniu dane z drugiej kolumny

nierozliczany Alarmy: „1970-01-01 00: 00: 00 + 0530” zdarzenie zdaje się ma jakąś datę wartość.

host_id jest nazwa serwera

occur_time jest, gdy zdarzenie wystąpiło.

last_occur to czas, kiedy wydarzenie ponownie się powtórzyło.

nazwa alarmu to, co się stało z systemem.

Jak mogę modelować moją tabelę, aby wykonać te zapytania i aktualizować na podstawie unique_id? Z tym, co próbowałem, wybierz nie jest możliwe i podczas upsert nowy wiersz jest tworzony dla tego samego unikalnego klucza.

Odpowiedz

5

Myślę, że prawdopodobnie potrzebujesz trzech tabel do obsługi trzech typów zapytań.

Pierwsza tabela będzie wspierać przedziale czasowym pytania dotyczące historii, kiedy ostrzega się dla każdego hosta:

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'; 

Druga tabela będzie śledzić nierozliczonych alarmów dla każdego hosta:

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'; 

Ostatnia tabela będzie śledzić, kiedy alerty zostały wyczyszczone dla każdego hosta:

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'; 

Gdy nowy zdarzenie alarmowe przybywa, można wykonać tę partię:

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; 

Zauważ, że wkładka do nierozliczonych tabeli jest upsert, ponieważ znacznik czasu nie jest częścią klucza. Ta tabela będzie miała tylko jeden wpis dla każdej nazwy alarmu ze znacznikiem czasu ostatniego wystąpienia.

Gdy alarm jasne wydarzenie przybywa, można wykonać tę partię:

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; 

naprawdę nie zrozumieć, co „unique_key” jest albo skąd pochodzi. Nie jestem pewien, czy jest to potrzebne, ponieważ połączenie host_id i nazwa_hosta powinno być poziomem ziarnistości, z którym chcesz pracować. Dodanie kolejnego unikalnego klucza do miksu może spowodować powstanie wielu niedopasowanych zdarzeń alert/clear. Jeśli unikalny klucz jest identyfikatorem alarmu, użyj go jako klucza w miejsce nazwa_hosta w moim przykładzie i nazwa_aluminu jako kolumna danych.

Aby zapobiec zapełnianiu tabel za pomocą starych danych, można użyć funkcji TTL, aby automatycznie usuwać wiersze po kilku dniach.

+0

dzięki za naprawdę fajną odpowiedź unique_key to losowy klucz generowany w rdbms. czy Kasandra ma funkcję automatycznego replikowania danych między tabelami? Za każdym razem muszę sprawdzać pole clear_time, czy nie spowolni to wydajności? Trzeci, myślę, że masz na myśli wystąpienie czasu? – kinkajou

+0

Jak to zrobić dla 100-1000 alarmów na sekundę? – kinkajou

+0

Cassandra 3.0 będzie obsługiwać zmaterializowane widoki w celu propagowania danych z jednej tabeli do drugiej, ale ta wersja nie będzie dostępna przez pewien czas. Nie rozumiem, co masz na myśli, sprawdzając za każdym razem "clear_time". Chcesz uniknąć czytania przed napisaniem w Cassandrze, ponieważ znacznie zmniejszy to wydajność transakcji. –