2015-08-08 193 views
9

我設計下表來存儲服務器警報:造型卡桑德拉表

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

讓我們輸入一些數據:

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

查詢我的應用程序將運行是:

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

我不知道我是否應該準備更多的表格示例:host_alerts_by_hostname 或host_alerts_by_cleartime等等,或者乾脆添加集羣索引。 作爲唯一的ID是唯一的獨特列,但我需要從另一列retrive數據

不清零報警:「1970-01-01 00:00:00 + 0530」清除事件有一定的日期值。

HOST_ID是服務器名稱

occur_time是當事件已發生。

last_occur是當事件再次reoccured時間。

alarm_name是什麼與系統happend。

如何建模我的表,以便我可以執行這些查詢和基於unique_id更新?與我已經嘗試選擇是不可能的,並在upsert期間爲同一個unique_key創建新行。

回答

5

我想你可能需要三張表來支持你的三種查詢類型。

第一個表將支持約當警報發生的每個主機的歷史時間範圍查詢:

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

第二個表將跟蹤未清除告警的每個主機:

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

最後一個表格將跟蹤每個主機清除警報的時間:

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

當一個新的報警事件到來時,你會執行此批:

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; 

注意,INSERT INTO未清除的表是一個UPSERT,因爲時間戳是不是關鍵的一部分。因此,該表格只會爲每個具有最後發生時間戳的警報名稱輸入一個條目。

當報警清除事件到來時,你會執行此批:

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; 

我真的不明白你的「unique_key」是什麼,或者它從何而來。我不確定這是否需要,因爲host_id和alarm_name的組合應該是您要使用的粒度級別。在混音中添加另一個獨特的關鍵可能會產生許多無法比擬的警報/清除事件。如果unique_key是一個警報ID,那麼在我的示例中使用它作爲alarm_name的鍵,並將alarm_name作爲數據列。

爲防止您的表隨着時間的推移被舊數據填滿,您可以使用TTL功能在幾天後自動刪除行。

+0

非常感謝你的回答unique_key是在rdbms中生成的隨機密鑰。 cassandra是否具有自動複製表間數據的功能?我需要每次檢查clear_time字段,它是否會減慢性能?另外,第三個我認爲你的意思是happen_time? – kinkajou

+0

我該如何爲每秒100-1000次報警? – kinkajou

+0

Cassandra 3.0將支持物化視圖,以將數據從一個表傳播到另一個表,但該版本暫時不可用。我不明白你每次檢查clear_time的意思。您希望避免在Cassandra中寫入之前進行讀取,因爲它會大大降低事務吞吐量。 –