2016-07-06 91 views
0

關於使用cassandra存儲時間序列有很多問題,但沒有人適合我們的問題,因爲它們都假設固定的數據源和已知的列名。Cassandra:帶有動態列/時間序列的時間序列

關於我們的問題: 我們正在開發一個流數據引擎,它可以連接到不同的數據源,引擎將數據作爲連續流接收。 因此,我們有兩個數據源,分別叫做energyweather。每個輸入流(或數據源)具有其自己的唯一的密鑰,並且通常其自己的模式,例如:

ID 1用模式energy可能具有此流:

timestamp | volts | amps | watts | state 
1467795743173 | 210.4 | 2.3 | 290 | "up" 
1467795744173 | 212.1 | 2.1 | 287 | "up" 
1467795745173 | 213.1 | 2.2 | 242 | "up" 
... 

ID 2用模式weather可能具有此流:

ts | condition | temp 
1467795740632 | "cloudy" | 33.1 
1467795741381 | "cloudy" | 33.4 
... 

現在我們想給存儲流進卡桑德拉的可能性,這樣他們就可以在以後使用「重放」錄製流,獲取歷史結果s(例如用於分析),並用特定的存儲數據值(例如,顯示/比較當前能量值與一週前記錄的值)來豐富/加入輸入流。總之,我們基本上需要這些東西:

  • 讀取順序爲一個certian源ID
  • 搶範圍爲某個源ID

    (例如,從2016年7月6日從設備ID 2提取所有10:00之間11:00)
  • 保存任意列(除了固定的時間戳列),因爲我們不提前知道該架構。

由於我們是cassandra的新手,目前我們不知道模型表和列的最佳方式是什麼。

大多數類似問題的答案都不會面臨有未知模式(他們都假設有時間戳,deviceId和double值)並且只面臨主/部分鍵問題的可能性。

我們讀到兩個選項:

  1. 我們應該有一個單一的表,例如datapoints,其中包含source-ID + day的所有數據作爲分區鍵?但是,我們如何處理這裏的動態列?我們是否需要將整個元組序列化爲一個單一的公共列,例如將energyydata以及天氣數據全部放在一個名爲value的列中。

所以我們有這個表:

CREATE TABLE datapoints (
sourceid bigint, 
date text, 
time timestamp, 
value text, 
    PRIMARY KEY ((sourceid, date), time) 
) 

顯然,我們不能用在原始值aggreate或其他功能(例如瓦,安培或臨時)。

另一種可能性是爲每個數據源創建一個表,例如,使用當天作爲分區鍵:

CREATE TABLE energy_1 ( 
date text, 
time timestamp, 
volts double, 
amps double, 
watts double, 
state text, 
    PRIMARY KEY (date, time) 
) 

CREATE TABLE weather_2 (
date text, 
time timestamp, 
condition text, 
temp double, 
    PRIMARY KEY (date, time) 
) 

由於數據將使用日期進行分區,因此有可能獲取一個星期還是這不可能?雖然可能有多個具有相同模式的數據源(例如兩個能源數據源),但我們不知道它,這很少。因此使用device-id作爲分區密鑰是沒有意義的,因爲每個模式大多隻有一個設備密鑰。

但第二種解決方案看起來不太合適。

我們希望有人也解決了類似的問題,並有一些建議?!

備註:我們不希望使用其他的時間序列數據庫:)

回答

1

考慮使用的地圖爲您的數據值:

CREATE TABLE datapoints (
    sourceid bigint, 
    date text, 
    time timestamp, 
    values map<text, text>, 
    PRIMARY KEY ((sourceid, date), time) 
) 

您也可以使用地圖不同的數據類型:

CREATE TABLE datapoints (
    sourceid bigint, 
    date text, 
    time timestamp, 
    strvalues map<text, text>, 
    intvalues map<text, int>, 
    decvalues map<text, decimal>, 
    PRIMARY KEY ((sourceid, date), time) 
) 
0

也許你可以使用兩種解決方案的組合:

您可以創建一個表像所有信息:

CREATE TABLE datapoints (
    sourceid bigint, 
    date text, 
    time timestamp, 
    value text, 
    volts double, 
    amps double, 
    watts double, 
    state text, 
    condition text, 
    temp double, 
    PRIMARY KEY ((sourceid, date), time) 
); 

插入數據時,可能沒有指定許多列。但無論如何,cassandra都不會在磁盤上存儲NULL值。因此,這個表格中列出了conditionstemp,並且在您的示例中將其作爲表格weather_2

如果使用卡桑德拉> = 3.0,yopu可以創建materialized視圖來創建特定的表(如energy_1weather_2)或創建其它的方式來讀出的數據(對於爲例respecify分區鍵)。

希望這可以幫助你。

+0

您好,感謝。但問題是:我不提前知道列(名稱,列數及其數據類型)。只有在傳感器連接到流引擎後,引擎才知道存在例如一個名爲伏特或溫度(或其他)的列。所以創建這樣的桌子是不可能的...... – Indivon

+0

好的,我已經忘記了這件事。新傳感器連接時,你可以改變表格嗎?所以在初始狀態下,你的表只包含sourceid,日期,時間(使用分區鍵規範)。你可以動態添加alter列。在cassandra中,即使表包含已有數據(cassandra不存儲NULL,因此不需要爲每個現有行創建附加列),也不會花費任何時間。 –