具有不可靠网络和低带宽的Java ORM的策略

具有不可靠网络和低带宽的Java ORM的策略

问题描述:

我正在寻找一种需要在不可靠网络中工作的系统的Hibernate。有一个我们需要读写访问的单个*数据库,但是它可以通过一个非常不规则的Wi-Fi网络提供。此外,可能会有功率损失不能彻底关闭应用程序,因此任何解决方案都必须具有持续高速缓存,以保持电源周期。最后,这是一个只有适度内存和磁盘空间的嵌入式系统,因此例如对数据库进行全面复制并不是一种可行的策略。具有不可靠网络和低带宽的Java ORM的策略

我对Hibernate 2nd Level缓存有一个基本的了解,我想知道是否可以用Ehcache这样的东西来解决这个问题,但是主要的推力似乎是性能不可用,所以我我并没有意识到这些陷阱可能是什么。

我也非常愿意考虑涉及复制到本地数据库的其他策略。我宁愿不必做太多沉重的工作来实现这一点。

寻找一些经验或可能的选择。

+0

注意,当我说“适度”内存时,我的意思是大约256Mb,并且有虚拟内存。所以它并不坏,只是不如桌面/服务器那么笨重。 – 2011-05-15 17:03:35

Daffodil Replicator(http://enterprise.replicator.daffodilsw.com/index.html)允许JDBC源之间的复制。它支持双向更新,合并和冲突解决以及部分副本。

这可用于使主数据库与本地(部分)副本同步。您可以使用hibernate与本地副本数据库进行通信,并在该进程之外完成所有其他操作。

你不能指望在hibernate和数据库之间的网络中取得成功。

我建议您定义一组高级原子操作,然后为它们定义一组(例如)宁静服务。或者,如果您愿意,可以使用soap并查看WS- *选项以获得可靠的消息传递,以处理重试以及所有其他杂乱的细节。

或者,您可以调查跨链接的cassandra是否比SQL更好,或者其他重要的东西。

+0

这是一个值得考虑的策略,但并没有真正解决任何问题,因为在系统关闭的情况下,您仍然必须维护这些操作结果的本地副本,然后保持一致性等。我知道可以编写一个复制系统,但我试图尽可能避免这样做。 – 2011-04-30 23:50:58

如果只是两台机器偶尔连接的情况,我会建议保留一个可以回放的事务日志,并将每个条目标记为已处理。尽管如此,有限的内存可能会使这种困难变得困难

虽然也许你可以存储压缩的事务日志。

如何在持久/持久消息队列上对数据库操作进行排队,并让一些消息中间件处理网络问题?

根据你的操作方式,一致性问题(呃,“异常”是我猜想的正确的词)可能会出现,但是如果你有不可靠的网络,仍然需要体面的表现,那么放松一致性可能是一种方式去。

我会犹豫使用EhCache等。他们不是为此设计的,因此您可能需要“扩展”框架。另一方面,消息队列具有针对这些场景设计的解决方案。

+0

最持久的消息队列系统使用数据库来保持持久性。为了真正可靠,数据库将不得不被集群化(然后可能使用网络进行通信)。 – 2011-05-10 11:56:40

+0

@Nicolas:“外设”消息队列将使用的持久性存储必须使用设备的本地存储。如果通过网络使用资源来实现这一点,那么它就没有任何意义。原则上,这些操作应该在设备的本地存储上进行存储(排队),并且消息传递系统需要重试操作直到成功。*数据库的可靠性是另一回事。 – 2011-05-12 17:33:38

+0

未复制且未备份的“持续”消息队列在磁盘故障时不提供保修。这是用户完成的一些事情,直到与主服务器的最后一次同步将会丢失。这是我的观点。 – 2011-05-12 17:48:21

“此外,可能会有功率损失不能彻底关闭应用程序,因此任何解决方案都必须具有持续高速缓存,以保持电源周期。”

对于Hibernate 2级缓存,您已经有了一个解决方案。但是你没有说出什么是真正的要求。你有一个不可实现的网络。没关系,你有不可行的电源。这也没关系。现在你想达到什么样的服务水平?什么是可以接受的?

数据丢失是否可接受?你能接受多少?你接受什么风险?

为了更加明确,假设您有一个数据库的本地副本或至少部分数据库。假设您知道如何排队/保存在本地进行的修改。假设您将这些修改存储在硬盘上,以便在发生电源故障时保证安全。假设您可以在连接再次可用时将更改与主数据库合并。

这已经有很多假设了。好吧,但如果一个硬盘在电源故障后失败会发生什么?你知道硬盘不喜欢电源故障,并且在电源故障时往往会损坏,甚至可能会损坏?

因此,你把一个RAID,并添加一个不间断电源。这很好。操作系统检测到电源故障事件。完成当前事务并正确关闭。您的RAID可以保护您免受磁盘故障。

好的,但如果整个计算机停止运作会发生什么?发生火灾时会发生什么?还是水害?所有磁盘将被管理,数据不可恢复,并且与*数据库不同步的内容将丢失。它可以接受吗?

即使无线网络打开,电源也能正常工作......无论如何,*数据库的可靠性如何?你有定期备份吗?还是集群解决方案?你确定你的*数据库是可靠吗?

从数据库的角度来看,很容易使用群集或备份并使用事务来确保数据一致性。您仍然可以释放数据(如果特别不使用群集),但您应该可以恢复到最后一次备份。

但是,如果您想离线工作(数据库不可用),并且您不是唯一可以修改数据库的人员,则会发生冲突。这不再是缓存,休眠或任何技术问题。

这是功能性问题。几个修改脱机时发生什么并且您必须合并?什么是可接受的?什么不是。这可能是在重新连接时,最近的更改适用,旧的更改将被丢弃。或者检测到冲突冲突并提示用户处理它们。您可以尝试应用排队更改并应用所有这些...

我倾向于认为您可以提供“离线模式”,但您的用户必须知道他们处于离线状态,并且应该在*数据库中的变化正在终结,并最终解决冲突。但是,我的观点。

+0

可靠性问题的一个很好的描述,但我真的主要关心面对片状网络的离线访问。我认为复制解决方案应该以标准方式处理冲突(作为可以回滚的分布式事务或最后赢得策略)。 – 2011-05-15 17:02:01

休眠(和二级缓存)是真的是不是为此设计的。我的猜测是,您可能最好使用小型嵌入式Java RDBMS(例如H2或HSQLDB)作为本地临时队列(处于最持久模式),然后与后台线程进行同步。然后,您可以提供一个连接到该后台线程的同步微调器UI,为用户提供一定程度的反馈。

顺便提一下,Hibernate有点胖,无法转储到嵌入式环境中。您可能需要考虑myBatis。