2013-08-03 96 views
0

如何在Go中創建基於磁盤的延遲隊列?Go中的磁盤備份陣列

我正在編寫一個Go程序,在特定時間間隔後對數據採取某些操作。這是一個精簡版本。

func IncomingJob (data MyStruct) { 
    //Run immediately 
    dosomething(&data, 1) 
    time.Sleep(5 * time.Minute) 
    //Run after 5 minutes has passed from initial arrival 
    dosomething(&data, 2) 
    time.Sleep(5 * time.Minute) 
    //Run after 10 minutes has passed from initial arrival 
    dosomething(&data, 3) 
    time.Sleep(50 * time.Minute) 
    //Run after 60 minutes has passed from initial arrival 
    dosomething(&data, 4) 
} 

這個func將被初始化爲goroutinue。

go IncomingJob(data) 

我遇到的問題是,IncomingJob的每個實例60分鐘運行,並且MyStruct對象保持在存儲器中用於該持續時間。總內存使用量非常大。如果我想支持每小時100萬次運行,那意味着在任何給定的時間,內存中有100萬個對象在等待,什麼也不做。我也可以使用time.AfterFunc,但這並不會改變內存使用情況。

Go有一些磁盤支持的FIFO隊列/緩衝區實現嗎?這樣我可以有3個隊列(針對不同的時間間隔)並輪詢它並睡眠,直到輪詢數據被重新處理的正確時間。這樣我會在串行化過程中丟失一些CPU週期,將I/O延遲添加到其他內存應用程序中,但可以節省大量內存。

更新:time.AfterFunc使用更少的內存。

func IncomingJob (data MyStruct) { 
    //Run immediately 
    dosomething(&data, 1) 
    time.AfterFunc(5 * time.Minute, func() { 
     //Run after 5 minutes has passed from initial arrival 
     dosomething(&data, 2) 
     time.AfterFunc(5 * time.Minute, func() { 
      //Run after 10 minutes has passed from initial arrival 
      dosomething(&data, 3) 
     }) 
      time.AfterFunc(50 * time.Minute, func() { 
       //Run after 50 minutes has passed from initial arrival 
       dosomething(&data, 4) 
     }) 
    }) 
} 

回答

0

聽起來像embedded database的工作。我相信一個FIFO可以很容易地通過例如。一個NoSQL鍵/值存儲。

你可能想看看kv(作者在這裏)。 Catch:值限制爲64k,因此您可能需要從多個K/V對中組合分開的FIFO項目。

+0

http://godoc.org/github.com/cznic/kv#DB.First - 首先如何選擇?它是最早輸入的k,v還是存在於數據庫中?順便說一句,你的kv看起來完美的代碼的另一部分,我應該需要在應用程序中添加耐久性。 – sajal

+0

@sajal:第一:在關鍵排序順序。所以是的,如果你使用有序號碼序列(或time.Now()。UnixNano())作爲鍵,那麼.First將返回仍然在數據庫中的「最老」的項目。 – zzzz