我需要一个应该管理数据库的Java应用程序来将工作单元分发给它的客户端。 实际上它是一个网格应用程序:数据库中填充了客户端的输入参数,并且所有元组都必须分发给请求的客户端。客户端发送结果后,服务器会相应地修改数据库(例如标记计算的元组) 现在让我们假设我有一个充满元组的数据库(SQLite或MySQL),并且客户端请求一组输入元组:我希望一组工作单元专门发送给一个唯一的客户端,所以我需要标记它们“已被另一位客户要求”。 如果我查询数据库中的第一个(例如5个)查询,同时另一个客户端发出相同的请求(在多线程服务器体系结构中并且没有任何同步),我认为两个客户端都有可能收到相同的工作单元。
我想象解决方案可能是:
1)制作单线程服务器体系结构(仅在提供上一个客户端请求之后再次调用ServerSocket.accept(),以便仅在客户端有效访问服务器时)
2)在多线程架构中,使查询和元组锁定操作同步,以便获得一种原子性(有效地对数据库进行序列化操作)
3)对数据库服务器(或文件,在SQLite的情况下)使用原子查询操作,但在这种情况下我需要帮助,因为我不知道事情是怎么回事......
但是我希望你理解我的问题:它与seti @ home非常相似,它分配了它的工作单元,但所有分布式单元与其众多客户端的交集是空的(理论上)。 我的非功能需求是语言是java,而数据库是SQLite或MySQL。
答案 0 :(得分:1)
我建议你阅读一些文章,例如this one,看看DB如何为你做同步工作。
答案 1 :(得分:1)
针对每种潜在解决方案的一些反馈......
1)制作单线程服务器 体系结构(ServerSocket.accept() 只有在之后再次被召唤 以前的客户请求已经 服务,所以服务器是 仅由客户有效访问 在时间)
ServerSocket.accept()
将不允许您这样做,您可能需要其他类型的同步以仅允许一个线程处于getting tuples
的情况。这基本上会引导您找到解决方案(2)。
2)在多线程架构中, 进行查询和元组锁定 操作同步,让我 获得一种原子性 (有效地序列化操作 在数据库上)
可行,易于实施以及解决问题的常用方法。唯一的问题是您对性能,延迟和吞吐量的关注程度,因为如果您拥有许多客户端并且工作单元的时间跨度非常短,那么客户端可能最终会锁定90%的时间等待获取“令牌”。
该问题的可能解决方案。对工作单位使用基于散列的分布。假设您有50个工作单位在50个客户之间共享。您为工作单位提供ID,以便客户获得某些工作单位。最后,您可以使用简单的模块操作分配节点:
assigned_node_id = work_unit_id % number_of_working_nodes
此技术称为pre-allocation
,不适用于所有类型的问题,因此取决于您的应用程序。如果您有许多短期运行流程,请使用此方法。
3)使用原子查询操作 数据库服务器(或文件,在这种情况下 (SQLite),但在这种情况下我需要 帮助因为我不知道怎么回事 真的... ...
它实质上与(2)相同,但是如果你能够做到这一点,我怀疑你可以只用SQL,你最终会绑定到你的RDBMS的一些特定功能。您很可能需要一些非标准的SQL过程来实现此解决方案。并且,它不能解决您在解决方案2中发现的问题。
Summary
解决方案2更有可能在90%的情况下工作,任务越长,此解决方案就越好。如果任务时间非常短,一定要选择基于pre-allocation
的算法。
使用解决方案3,您可以放弃便携性和灵活性。
DRY: try some other Open Source systems ...
很少有开源java项目已经处理过这类问题,它们可能对你来说太过分了,但我认为值得一提......