我正在寻找一种方法来序列化影响数据存储中数据的任务,而无需使用 MySQL
前任:
在 group1
上做会计的 worker 应该是唯一在组 1 上做会计的 worker ,如果另一个 worker 在组 1 上做会计,应该排队等候。
我可以通过设置信号量表、启动事务、对 group1
的行进行更新、执行我的任务并提交来使用 MySQL 完成此操作。
我在想也许可以使用 0mq redis 或某种消息传递系统来实现相同的目标,并允许我使用我想要的任何数据存储。
我也在想 ScalienDB 可能能够以与 mysql 相同的方式解决问题,因为它支持事务。 ScalienDB 的文档似乎有些不完整,因此我无法确定它是否可以以这种方式进行事务处理。
所以我的问题是:
ScalienDB 是否可以执行一个事务,如果客户端想要编辑表中的一行,而另一个客户端也对其进行了编辑,则该事务会强制客户端等待另一个客户端提交。
使用消息传递系统,您如何建议实现可以归结为如下内容的东西:
var semaphore = semaphore_group() semaphore.acquire('task1',function(){ // do work after a sophomore is locked in semaphore.release() // })
理想情况下,我不希望这个系统依赖于中心化代理
- 是否有适合这个问题的替代解决方案
最佳答案
我最喜欢 Node 的一点是无线程,这意味着每一行代码都可以被视为原子。因此,您只需编写几行 JS 代码即可运行一个套接字服务器,该服务器将为工作人员提供您希望拥有的确切机制,如示例代码所示。
我不确定调用此信号量在技术上是否正确,因为我们会跟踪等待轮到他们的工作人员。
worker :
var Semaphore = reqire('./semaphore.js'),
semaphore = new Semaphore(worker-id, group-id);
semaphore.on('ready', function() {
// Yay! We can work..!
semaphore.done();
}
semaphore.js 骨架:
// imports...
module.exports = S = function(gid) {
events.EventEmitter.call(this);
// create socket connection to semaphore server
// send a message for lock on gid
// emit ready event when server sends ready message.
// send 'done' message when done() method is called.
}; util.inherits(S, events.EventEmitter);
semaphore-server.js 骨架:
// imports...
var queues = {}; // { 'group-id': [worker1, worker2, ...] }
// start socket server
/* on message: take worker-id and group-id
queues[groupid].push(workerid);
check if queues[groupid][0]==workerid and if it is,
send back ready message.
*/
/* on message 'done', remove workerid from queues[groupid]
and if there are any workers waiting, send the first one
ready message.
*/
您的代码不会比上面的这个框架长很多。 ZeroMQ 或任何其他消息对于这种简单的消息系统来说不是必需的。您可能会考虑为工作人员添加超时,并且每当发生超时时,向工作人员发送一条消息,询问“您还在工作吗?”并照此继续。您的超时处理程序还可以检查队列中是否有任何其他工作人员,因此如果没有,甚至没有必要打扰工作人员时间...
如果我需要的只是一个我可以在一个小时内构建的简单系统,我通常更喜欢使用手头已有的工具,而不是求助于第三方。任何其他库/dbms/messaing-system 或任何东西都会增加我不喜欢的软件的复杂性和管理工作。由于您已经在 Node 中构建一些东西并且它已经完美地提供了您想要的东西,所以我相信这是要走的路。
关于node.js - 分布式信号量系统,用于序列化不能同时运行的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10366588/