2011-04-30 51 views
7

我正在尋找一種需要在不可靠網絡中工作的系統的Hibernate。有一個我們需要讀寫訪問的單箇中央數據庫,但是它可以通過一個非常不規則的Wi-Fi網絡提供。此外,可能會有功率損失不能徹底關閉應用程序,因此任何解決方案都必須具有持續高速緩存,以保持電源週期。最後,這是一個只有適度內存和磁盤空間的嵌入式系統,因此例如對數據庫進行全面複製並不是一種可行的策略。具有不可靠網絡和低帶寬的Java ORM的策略

我對Hibernate 2nd Level緩存有一個基本的瞭解,我想知道是否可以用Ehcache這樣的東西來解決這個問題,但是主要的推力似乎是性能不可用,所以我我並沒有意識到這些陷阱可能是什麼。

我也非常願意考慮涉及複製到本地數據庫的其他策略。我寧願不必做太多沉重的工作來實現這一點。

尋找一些經驗或可能的選擇。

+0

注意,當我說「適度」內存時,我的意思是大約256Mb,並且有虛擬內存。所以它並不壞,只是不如桌面/服務器那麼笨重。 – 2011-05-15 17:03:35

回答

0

Daffodil Replicator(http://enterprise.replicator.daffodilsw.com/index.html)允許JDBC源之間的複製。它支持雙向更新,合併和衝突解決以及部分副本。

這可用於使主數據庫與本地(部分)副本同步。您可以使用hibernate與本地副本數據庫進行通信,並在該進程之外完成所有其他操作。

2

你不能指望在hibernate和數據庫之間的網絡中取得成功。

我建議您定義一組高級原子操作,然後爲它們定義一組(例如)寧靜服務。或者,如果您願意,可以使用soap並查看WS- *選項以獲得可靠的消息傳遞,以處理重試以及所有其他雜亂的細節。

或者,您可以調查跨鏈接的cassandra是否比SQL更好,或者其他重要的東西。

+0

這是一個值得考慮的策略,但並沒有真正解決任何問題,因爲在系統關閉的情況下,您仍然必須維護這些操作結果的本地副本,然後保持一致性等。我知道可以編寫一個複製系統,但我試圖儘可能避免這樣做。 – 2011-04-30 23:50:58

1

如果只是兩臺機器偶爾連接的情況,我會建議保留一個可以回放的事務日誌,並將每個條目標記爲已處理。儘管如此,有限的內存可能會使這種困難變得困難

雖然也許你可以存儲壓縮的事務日誌。

2

如何在持久/持久消息隊列上對數據庫操作進行排隊,並讓一些消息中間件處理網絡問題?

根據你的操作方式,一致性問題(呃,「異常」是我猜想的正確的詞)可能會出現,但是如果你有不可靠的網絡,仍然需要體面的表現,那麼放鬆一致性可能是一種方式去。

我會猶豫使用EhCache等。他們不是爲此設計的,因此您可能需要「擴展」框架。另一方面,消息隊列具有針對這些場景設計的解決方案。

+0

最持久的消息隊列系統使用數據庫來保持持久性。爲了真正可靠,數據庫將不得不被集羣化(然後可能使用網絡進行通信)。 – 2011-05-10 11:56:40

+0

@Nicolas:「外設」消息隊列將使用的持久性存儲必須使用設備的本地存儲。如果通過網絡使用資源來實現這一點,那麼它就沒有任何意義。原則上,這些操作應該在設備的本地存儲上進行存儲(排隊),並且消息傳遞系統需要重試操作直到成功。中央數據庫的可靠性是另一回事。 – 2011-05-12 17:33:38

+0

未複製且未備份的「持續」消息隊列在磁盤故障時不提供保修。這是用戶完成的一些事情,直到與主服務器的最後一次同步將會丟失。這是我的觀點。 – 2011-05-12 17:48:21

3

「此外,可能會有功率損失不能徹底關閉應用程序,因此任何解決方案都必須具有持續高速緩存,以保持電源週期。」

對於Hibernate 2級緩存,您已經有了一個解決方案。但是你沒有說出什麼是真正的要求。你有一個不可實現的網絡。沒關係,你有不可行的電源。這也沒關係。現在你想達到什麼樣的服務水平?什麼是可以接受的?

數據丟失是否可接受?你能接受多少?你接受什麼風險?

爲了更加明確,假設您有一個數據庫的本地副本或至少部分數據庫。假設您知道如何排隊/保存在本地進行的修改。假設您將這些修改存儲在硬盤上,以便在發生電源故障時保證安全。假設您可以在連接再次可用時將更改與主數據庫合併。

這已經有很多假設了。好吧,但如果一個硬盤在電源故障後失敗會發生什麼?你知道硬盤不喜歡電源故障,並且在電源故障時往往會損壞,甚至可能會損壞?

因此,你把一個RAID,並添加一個不間斷電源。這很好。操作系統檢測到電源故障事件。完成當前事務並正確關閉。您的RAID可以保護您免受磁盤故障。

好的,但如果整個計算機停止運作會發生什麼?發生火災時會發生什麼?還是水害?所有磁盤將被管理,數據不可恢復,並且與中央數據庫不同步的內容將丟失。它可以接受嗎?

即使無線網絡打開,電源也能正常工作......無論如何,中央數據庫的可靠性如何?你有定期備份嗎?還是集羣解決方案?你確定你的中央數據庫是可靠嗎?

從數據庫的角度來看,很容易使用羣集或備份並使用事務來確保數據一致性。您仍然可以釋放數據(如果特別不使用羣集),但您應該可以恢復到最後一次備份。

但是,如果您想離線工作(數據庫不可用),並且您不是唯一可以修改數據庫的人員,則會發生衝突。這不再是緩存,休眠或任何技術問題。

這是功能性問題。幾個修改脫機時發生什麼並且您必須合併?什麼是可接受的?什麼不是。這可能是在重新連接時,最近的更改適用,舊的更改將被丟棄。或者檢測到衝突衝突並提示用戶處理它們。您可以嘗試應用排隊更改並應用所有這些...

我傾向於認爲您可以提供「離線模式」,但您的用戶必須知道他們處於離線狀態,並且應該在中央數據庫中的變化正在終結,並最終解決衝突。但是,我的觀點。

+0

可靠性問題的一個很好的描述,但我真的主要關心面對片狀網絡的離線訪問。我認爲複製解決方案應該以標準方式處理衝突(作爲可以回滾的分佈式事務或最後贏得策略)。 – 2011-05-15 17:02:01

1

休眠(和二級緩存)是真的是不是爲此設計的。我的猜測是,您可能最好使用小型嵌入式Java RDBMS(例如H2或HSQLDB)作爲本地臨時隊列(處於最持久模式),然後與後臺線程進行同步。然後,您可以提供一個連接到該後臺線程的同步微調器UI,爲用戶提供一定程度的反饋。

順便提一下,Hibernate有點胖,無法轉儲到嵌入式環境中。您可能需要考慮myBatis。