2011-09-25 45 views
1

在網絡服務器內存中積累數據達到數據庫寫入數據庫的特定時間限制是否是一種很好的策略&在每個指定時間間隔後或在數據增長到大於閾值大小後,將其作爲批量更新發送。收集批量更新數據並在通過閾值限制或超時後發送數據?

這種類型的數據非常小,就像在兩個實體之間添加關係一樣,這意味着只需在行中添加一組ID。

(當然,延遲的數據應該是預期不會立即可見的)。

這種方法有什麼缺點嗎?


使用方法:卡桑德拉DB,與Java & JSF構建Web應用程序。

+0

延遲可能足夠小,以至於顯示爲「立即」,因爲不會添加延遲。即它不可能具有零延遲,但也不可能讓人看到小的延遲。 –

回答

1

簡答:這是一個壞主意。

卡桑德拉的批處理操作(例如http://pycassa.github.com/pycassa/api/pycassa/batch.html)可讓您在冪等單位中對更新進行分組。這允許您將批處理作爲一個單元重試,因此其目的與關係數據庫中的事務大致相似。

然而,與交易類比不同的是,對績效的影響可以忽略不計,事實上人爲地將負荷「突發」通常會適得其反。

+0

謝謝喬納森!對於Hector提供的批處理操作,有沒有類似於'queue_size'的方法(在閾值大小後自動發送批處理) –

+0

你的意思是這是一個糟糕的主意,因爲客戶端庫已經通過批處理突變提供了這個選項,對! –

+0

不,我的意思是,如果你想批量作爲優化,而不是因爲一組操作在邏輯上屬於一起,那麼你做錯了。 (如果他們在邏輯上屬於你在一起,你不需要擔心隊列大小等......) – jbellis

1

主要缺點是它需要另一個線程來實現超時(少量的複雜度),但好處可能會更大。

實現一個簡單的方法是使用等待/通知(似乎沒有被使用併發庫一個很好的解決方案)

private final List<T> buffered = new ArrayList<T>(); 
private final int notifySize = ... 
private final int timeoutMS = ... 

public synchronized void add(T t) { 
    buffered.add(t); 
    if (buffered.size() >= notifySize) 
     notifyAll(); 
} 

public synchronized void drain(List<T> drained) throws InterruptedException { 
    while(buffered.isEmpty()) 
     wait(timeoutMS); 
    drained.addAll(buffered); 
    buffered.clear(); 
} 

add和排水可由任意數量的被稱爲的線程,但我想你只會有一個線程耗盡,直到它被中斷。

+0

因此,因爲我使用的是JSF,那麼在Web服務器上的應用程序作用域託管bean中累積數據是否好,然後在跨越閾值後傳遞該數據?你能否澄清你認爲可以接受多少時間? (假設最終用戶對該數據沒有任何緊迫性) –

+1

這真的取決於你。然而,典型的延遲可能是0.5到5秒。它可能短至0.05秒,甚至長於30秒。無論您是否使用JSF,此方法都可以工作。 –