2013-07-04 43 views
0

我是Cassandra的新手,我想集中討論在Cassandra中存儲加權圖的時間序列,其中邊權重每次增加,但也隨時間而變化。例如,在Cassandra中存儲加權圖時間序列

w_ij(t+1) = w_ij(t)*exp(-dt/tau) + 1 

我的第一槍涉及兩個CQL V3表:

首先,我通過連接圖的ID創建一個分區鍵和兩個節點入射在特定邊緣,例如G-V1-V2。我這樣做是爲了能夠在下面描述的組合鍵的第二個組件上使用「ORDER BY」指令,它是類型的時間戳。將此字符串稱爲EID,用於「邊緣ID」。

 
TABLE 1 
- a time series of edge updates 
- PRIMARY KEY: EID, time, weight 


TABLE 2 
- values of "last update time" and "last weight" 
- PRIMARY KEY: EID 
- COLUMNS: time, weight 

在每個刻度,我獲取和更新存儲的時間和權重值在表2予使用這些值來計算時間增量和新的重量。然後我在表1中插入這些值。

此策略中是否存在可怕的低效率? 應該如何做?我已經知道表2的更新過程不是冪等的,可能會導致不一致,但我可以暫時接受。

編輯:我可以做的一件事是將兩個表合併成一個時間序列表。

回答

0

當涉及到Cassandra(以及任何其他無法進行寫操作的比較和交換操作的數據庫)時,您應該避免任何類型的先讀後寫操作。

0

首先:你的應用程序有哪些查詢和查詢模式? 此外,我會感興趣多長時間每個邊緣的新權重將被計算和存儲。每秒鐘,每小時,每一天?

是否有可能將每條邊的最後一個重量保存在內存中?所以你可以在寫作前避免閱讀?可能某種延遲加載機制的這個值是可行的。

如果您的查詢將允許此數據模型,我會嘗試使用單個列族構建解決方案。

0

在卡桑德拉寫作之前,我會避免閱讀,因爲它確實不太合適。讀取比寫入要昂貴得多,爲了保持性能,您需要大量節點來進行相對較少的查詢。你提出的建議並不適合Cassandra,因爲在寫作之前似乎沒有任何方法可以避免閱讀。即使您使用單個表格,您仍然需要獲取上次更新條目來執行寫入操作。雖然這當然可以完成,但我認爲有更好的工具可以完成這項工作。話雖如此,如果您可以將表2中的所有數據保留在內存中,並且可能使用行緩存,這將是完全可行的。只要表2不太大以至於它可以適應內存中的大部分行,則讀取速度將顯着加快,這可能會彌補每次寫入時需要執行的讀取操作。然而,這將是一個相當大的挑戰,你需要確保每行的「最後更新時間」保存在內存中,並且很少需要磁盤被觸摸。

無論如何,你可能想要看的另一個設計是一個實現,它不僅使用Cassandra,而且還使用Cassandra前面的緩存來存儲上次更新的時間。這可以與Cassandra一起運行,也可以在單獨的節點上運行,但可能只是最後一次更新時間的內存存儲,而當您需要更新一行時查詢緩存並將整行寫入Cassandra(甚至可以寫入如果你願意,最後的更新時間)。你可以使用像Redis這樣的東西來執行這個功能,這樣你就不用擔心墓碑或者強制所有東西存儲在內存中等等。