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



我正在寻找一个需要在不可靠的网络中工作的系统Hibernate。有一个我们需要读写访问的中央数据库,但它是通过一个非常不稳定的wi-fi网络提供的。此外,可能会出现电源丢失,导致应用程序无法干净地关闭,因此任何解决方案都必须具有能够在电源周期中存活下来的持久缓存。最后,这是一个嵌入式系统,只有适度的内存和磁盘空间,因此,例如,对数据库进行全面复制是不可行的策略。

我对Hibernate第二级缓存有一个基本的了解,我想知道是否有可能用Ehcache这样的东西来配置它来解决这个问题,但它的主要目的似乎是性能而不是可用性,所以我不知道陷阱可能是什么。

我也很愿意考虑其他涉及到本地数据库复制的策略。我宁愿自己不做太多繁重的工作来实现它。

寻找一些经验或可能的替代方案。

"此外,可能会有电源丢失而不能干净地关闭应用程序,因此任何解决方案都必须有一个可以在电源周期中存活的持久缓存。"

在您的头脑中已经有了Hibernate 2级缓存的解决方案。但是你没有说真正的要求是什么。你的网络不可靠。没关系,你的电源不稳定。这也没关系。现在你想达到什么样的服务水平呢?什么是可接受的,什么是不可接受的?

数据丢失可以接受吗?你能接受多少?你们接受什么险别?

更明确地说,假设您有数据库的本地副本或至少部分副本。假设您知道如何将本地进行的修改排队/保存。假设你将这些修改存储在硬盘上,以便在电源故障的情况下安全。假设您能够在连接再次可用时将更改合并到主数据库。

已经有很多假设了。好的,但是如果一个硬盘在断电后失效怎么办?你知道硬盘不喜欢断电,而且容易损坏,甚至可能损坏吗?

因此,您安装了RAID,并添加了不间断电源。这很好。从操作系统检测电源故障事件。完成当前事务并正确关闭。当硬盘出现故障时,RAID可以保护您。

好的,但是如果整个电脑停止工作怎么办?万一发生火灾怎么办?还是水渍?所有磁盘都将被管理,数据不可恢复,未与中央数据库同步的数据将丢失。是否可以接受?

即使wifi开着,电源也能正常工作…中央数据库的可靠性究竟如何?你有定期备份吗?还是集群解决方案?你确定你的中央数据库是可靠的吗?

从数据库的角度来看,使用集群或备份和使用事务来确保数据一致性是很容易的。您仍然可以丢失数据(特别是如果不使用集群),但是您应该能够恢复到上次备份。

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

这是功能性问题。当离线发生多个修改并且必须合并时,该怎么办?什么是可接受的?什么不是。这可能是在重新连接时,应用最近的更改,而丢弃较旧的更改。或者检测到潜在的冲突并提示用户处理它们。您可以尝试应用队列更改并应用所有更改…

我倾向于认为您可以提供"脱机模式",但您的用户必须知道他们是脱机的,并且在最终解决冲突的中央数据库上永久更改时应该有通知。但这是我的观点。

在hibernate和数据库之间建立这样的网络是不可能成功的。

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

或者,你可以研究一下跨链接的cassandra是否比SQL更好,或者在复制方面是否有其他大的东西

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

取决于你怎么做,一致性问题(好吧,"异常"是正确的词我猜)可能会出现,但如果你有不可靠的网络,仍然想要体面的性能,那么满足于宽松的一致性可能是一种方式。

我会犹豫使用EhCache等。它们不是为此而设计的,因此您可能不得不"拉伸"框架。另一方面,消息队列具有专为此类场景设计的解决方案。

如果这只是两台机器之间零星连接的情况,我建议保留一个可以回放的事务日志,并将每个条目标记为已处理。然而,有限的记忆可能会使这变得困难。

也许您可以压缩存储事务日志。

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

顺便说一下,将Hibernate转储到嵌入式环境中有点胖。你可以考虑一下myBatis。

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

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

最新更新