0

如何在 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)
}

这个函数将被初始化为一个 goroutinue。

go IncomingJob(data)

我遇到的问题是 IncomingJob 的每个实例运行 60 分钟,并且该MyStruct对象在这段时间内保留在内存中。总内存使用量非常大。如果我想支持每小时运行 100 万次,这意味着在任何给定时间,内存中都有 100 万个MyStruct对象在等待,什么也不做。我也可以使用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)
        })
    })
}
4

1 回答 1

0

听起来像是嵌入式数据库的工作。我敢肯定,例如,可以很容易地对 FIFO 建模。NoSQL 键/值存储。

你可能想看看kv(作者在这里)。Catch:值限制为 64k,因此您可能需要将多个 K/V 对组合成单独的 FIFO 项。

于 2013-08-03T14:48:56.480 回答