DI有一个任务表,其中包含要为不同系统完成的配置任务。每个系统都有一个单独的Perl进程,该进程连续运行并检查表以查看它是否具有该给定系统的任何未完成任务。在一个月的过程中,该表中可能有几十万条记录。伪代码如下所示:
select oldest uncompleted task for a given provisioning system
if found a task
update task to "in progress"
go do some work
update task to completed
sleep 15 seconds
repeat
试图弄清楚如何提高这个过程的效率。如果我减少了睡眠时间,我会在数据库上添加额外的负载,但如果我增加睡眠时间,系统的整体响应会变得非常缓慢。理想情况下,我想彻底消除睡眠,但没有额外的负荷。
是否有像SQL等效的阻塞读取?那么select语句会阻塞,直到有东西返回?
我考虑过另一张表只包含一些不完整的任务列表。但是我仍然需要加入大桌子,所以不确定这是否真的会给我带来任何东西。
我能够提出的唯一解决方案可能就是在表上插入触发器,这可能触及/ tmp中的文件。然后Perl程序可以轮询该文件的时间戳。或者可能将一条小消息发送到Perl程序正在监听的命名管道,并使用阻塞读取。
如果您有任何关于如何解决此问题的帮助,我将不胜感激。这种dB轮询必须是一种常见的模式。
答案 0 :(得分:0)
一些观察结果。很难提供一个明确的答案,因为“最佳”将取决于许多因素。
首先,您需要确定哪些更重要 - 加载数据库或处理速度。可能是两者之间的平衡。
如果限制db上的活动真的很重要,那么你会想要集中管理的东西。最简单的可能是包含id和时间戳的pending_tasks表。一个单独的管理器进程使该表充满,并根据总体负载选择时间戳。你需要确保这个过程永远不会停止。
另一个选择是让每个处理器改变其睡眠时间。如果无事可做,请添加一秒钟。如果有事情要做,请减去一秒钟。显然,睡眠时间最小/最大。如果你愿意,你可以更聪明地使用变化。
这样,每个处理器都会在没有任何事情要做的时候休息。
第三次观察 - 每个系统都有一个进程。只需获取接下来的10个任务(或其他)。在实际开始工作之前,不要将它们标记为正在进行中。
最后,你真正喜欢的这种异步交流可以在其他地方找到。在PostgreSQL中,它们被称为通知。我担心我不知道MySQL中有任何类似的功能。
HTH