H2數據庫在集羣方面也有不錯的表現,下面介紹一下如何利用H2的集羣/高可用性機制。
集羣 / 高可用性
數據庫支持簡單的集羣/高可用性機制。
架構是:兩個數據庫服務運行在兩臺不同的計算機上,兩臺計算機有同樣數據庫的副本,如果兩個服務器都處於運行狀態,每個數據庫操作都被在兩臺計算機上執行,如果一臺服務器宕機(斷電、硬件故障、網絡故障等),另外一臺計算機仍能提供服務,從這一刻開始,數據庫操作僅在一臺服務器上執行,直到另外一臺服務器恢復運行。
集羣僅能用於服務器模式(內嵌模式並不支持集羣)。可以在數據庫運行狀態下恢復集羣,但是要求在第二個數據庫恢復期間沒有應用在改變第一個數據庫的數據,因此恢復集羣是一個手工的過程。
初始化集羣,使用下面的步驟:
- 創建數據庫。
- 使用CreateCluster工具創建一個數據庫福分到另外的地方,並且初始化集羣,這樣就得到了同樣數據的兩個數據庫。
- 啓動兩個數據庫服務(每個數據庫的副本)。
- 現在可以通過應用客戶端連接到數據庫。
H2支持兩臺服務器運行兩個數據庫成爲集羣,兩個數據庫互爲備份,如果一個服務器失效,另一個服務器仍然可以工作。另外只有服務模式支持集羣配置。
H2可以通過CreateCluster工具創建集羣,示例步驟如下(在在一臺服務器上模擬兩個數據庫組成集羣):
1、創建目錄
創建兩個服務器工作的目錄
# mkdir server1
# mkdir server2
2、啓動tcp服務
執行如下命令分別在9101、9102端口啓動兩個使用tcp服務模式的數據庫
java org.h2.tools.Server-tcp -tcpPort 9101-baseDir server1
java org.h2.tools.Server-tcp -tcpPort 9102 -baseDir server2
3、使用CreateCluster工具創建集羣
java org.h2.tools.CreateCluster
-urlSource jdbc:h2:tcp://localhost:9101/~/test
-urlTarget jdbc:h2:tcp://localhost:9102/~/test
-user sa
-serverList localhost:9101,localhost:9102
如果兩個數據庫不存在,該命令將會自動創建數據庫。如果一個數據庫失效,可以先刪除壞的數據庫文件,重新啓動數據庫,然後重新運行CreateCluster工具。
舉個例子,讓我們進一步瞭解集羣是如何工作的。
在這個例子裏,兩個數據庫駐留在同一臺計算機上,但通常,兩個數據庫在不同的計算機上。
· 創建兩個目錄:server1,server2。每個目錄將模擬一臺計算機
· 在第一個目錄啓動TCP服務,你可以運行下面的命令:
java org.h2.tools.Server
-tcp-tcpPort 9101
-baseDirserver1
在第二個目錄啓動TCP服務,模擬第二個服務器(冗餘運行),你能使用下面的命令:
java org.h2.tools.Server
-tcp-tcpPort 9102
-baseDirserver2
使用 CreateCluster 工具初始化集羣,如果數據庫不存在,將創建一個新的空數據庫,運行下面命令行:
java org.h2.tools.CreateCluster
-urlSourcejdbc:h2:tcp://localhost:9101/~/test
-urlTargetjdbc:h2:tcp://localhost:9102/~/test
-user sa
-serverList localhost:9101,localhost:9102
應用或者是H2控制檯可以通過下面的JDBC的URL連接數據庫:jdbc:h2:tcp://localhost:9101,localhost:9102/~/test
如果你停止一個服務(通過殺進程),你注意到另一個機器繼續工作,數據庫仍能提供訪問。
恢復集羣,你需要先刪掉宕機的數據庫,然後重啓宕機的數據庫的服務,再重新運行CreateCluster集羣工具。
4、連接數據庫
現在可以使用如下連接字符串連接集羣數據庫
jdbc:h2:tcp://localhost:9101,localhost:9102/~/test
5、監控集羣運行狀態
可以使用如下命令查看配置的集羣服務器是否都在運行
SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='CLUSTER'
該命令也可以用於查找哪些節點當前正在運行。
結果返回爲 ” (兩個單引號),說明集羣模式被屏蔽,否則,集羣服務器列表將被單引號包括着返回,如’server1:9191,server2:9191’。
6、限制
H2的集羣並不支持針對事務的負載均衡,所以很多操作會使兩個數據庫產生不一致的結果,執行如下操作時請小心:
RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND()
自動增長列和標識列不支持集羣,當插入數據時,序列值需要手動創建
不支持SET AUTOCOMMIT FALSE語句,如果需要設置成爲不自動提交,可以執行方法Connection.setAutoCommit(false)