H2数据库集群

H2数据库集群

1. H2数据库简单介绍

1.1 H2数据库优势

经常使用的开源数据库:H2,Derby,HSQLDB。MySQL,PostgreSQL。

当中H2,HSQLDB相似,十分适合作为嵌入式数据库使用。其它的数据库大部分都须要安装独立的client和服务器端。
H2的优势:
1、h2採用纯Java编写,因此不受平台的限制。
2、h2仅仅有一个jar文件,十分适合作为嵌入式数据库试用。


3、性能和功能的优势
H2比HSQLDB的最大的优势就是h2提供了一个十分方便的web控制台用于操作和管理数据库内容,这点比起HSQLDB的swing和awt控制台实在好用多了。


H2和各数据库特征比較

1.2 H2特征

1.2.1 主要特征

• 超快的数据库引擎
• 开源
• 纯JAVA编写
• 支持标准SQL和JDBC
• 支持内嵌模式、服务器模式和集群
• 高强度的安全保障
• 支持PostgreSQL的ODBC驱动
• 多种并发机制

1.2.2 其它特征

• 支持磁盘和内存数据库,支持仅仅读数据库,支持暂时表
• 支持事务(读提交和序列化事务隔离)。支持2阶段提交
• 支持多连接,支持表级锁
• 使用基于成本的优化机制,对于复杂查询使用零遗传算法进行管理
• 支持可滑动可更新的结果集,支持大型结果集、支持结果集排序,支持方法返回结果集
• 支持数据库加密(使用AES或XTEA进行加密)。支持SHA-256password加密,提供加密函数。支持SSL

1.3 连接模式

1.3.1 内嵌模式

内嵌模式下。应用和数据库同在一个JVM中,通过JDBC进行连接。内嵌模式是最快和最easy的连接模式。

它的缺点是不论什么时候数据库仅仅能在一台虚拟机(和载入类)。像全部的模式。持久数据库和内存数据库都被支持。没有打开连接数和打开数据库数量方面的限制。


这里写图片描写叙述

1.3.2 服务器模式

使用服务器模式(有时被称为远程模式或是C/S模式)时,应用能够通过JDBC或ODBC打开一个远程的数据库。服务器能够启动在同一个虚拟机或是不同的虚拟机上。也能够启动在不同的计算机上。大量的应用能够同一时候连接到同一个数据库上。

服务器模式相比内嵌模式性能慢一些,由于全部的数据都须要通过TCP/IP进行传输。

像全部的模式一样,支持持久数据库和内存数据库。没有打开连接数和打开数据库数量方面的限制。
这里写图片描写叙述
备注:
H2支持三种服务模式:
web server:此种运行方式支持使用浏览器訪问H2 Console
TCP server:支持client/服务器端的连接方式
PG server:支持PostgreSQLclient
启动tcp服务连接字符串演示样例:
jdbc:h2:tcp://localhost/~/test (使用用户主文件夹)
jdbc:h2:tcp://localhost/data/test (使用绝对路径)

1.3.3 混合模式

混合模式是内嵌模式和服务器模式的组合。第一个应用通过内嵌模式与数据库建立连接。同一时候也作为一个服务器启动。于是另外的应用(运行在不同的进程或是虚拟机上)能够同一时候訪问相同的数据。第一个应用的本地连接与嵌入式模式的连接性能一样的快,而远程连接有点慢。
服务器能通过应用来进行启动和停止(使用服务API)。或是是自己主动的方式(自己主动混合模式)。当使用自己主动混合模式,全部client都须要使用相同的URL进行连接(无论它是一个本地还是一个远程连接。
这里写图片描写叙述

1.3.4 数据库URL综述

数据库支持多种连接模式和连接设置,不同的连接模式和连接设置是通过不同的URL来区分的。URL中的设置是不区分大写和小写。


备注:以下仅仅列出经常使用的。详情请參考
http://www.h2database.com/html/features.html#database_url
Topic URL Format and Examples
使用TCP/IP的服务器模式(远程连接) jdbc:h2:tcp://[:]/[]
jdbc:h2:tcp://localhost/~/test
jdbc:h2:tcp://dbserv:8084/~/sample
jdbc:h2:tcp://localhost/mem:test
使用SSL/TLS的服务器模式(远程连接)
jdbc:h2:ssl://[:]/
jdbc:h2:ssl://localhost:8085/~/sample;
username和password jdbc:h2:[;USER=][;PASSWORD=]
jdbc:h2:file:~/sample;USER=sa;PASSWORD=123
调试跟踪项设置 jdbc:h2:;TRACE_LEVEL_FILE=

1.3.5 命令行工具

H2数据库提供了一组命令行工具,假设你须要了解这些工具,使用參数-?,如:

java -cp h2*.jar org.h2.tools.Backup -?

命令行工具有:
• Backup创建数据库备份
• ChangeFileEncryption 同意改变文件加密password和数据库的加密算法
• Console 启动基于浏览器的H2控制台
• ConvertTraceFile转换 .trace.db 文件到JAVA应用和SQL脚本
• CreateCluster从一个独立的数据库服务创建集群
• DeleteDbFiles 删除全部的数据库文件
• Recover恢复损坏的数据库
• Restore从数据库备份中恢复数据库
• RunScript 运行数据库SQL脚本
• Script 为数据库备份或迁移导出SQL脚本
• Server 启动H2服务模式
• Shell命令行工具
这些工具也能在程序中通过调用对应的方法来使用,相关具体的调用说明,请參考JavaDoc文档http://www.h2database.com/html/tutorial.html#command_line_tools


2. H2安装与server mode启动

2.1 H2安装与维护

2.1.1 下载安装文件

下载文件:h2-2014-04-05.zip
下载地址:http://www.h2database.com/html/download.html

2.1.2 安装并採用服务器模式启动

  1. 远程连接Linux服务器,这里进入到 usr/local/ 文件夹
  2. 上传安装文件至h2文件夹下;(可自行设定安装文件夹)
  3. 解压该安装文件:
    这里写图片描写叙述
  4. 确认已经安装了JDK,和已经配置了JAVA_HOME环境变量。比如:
    这里写图片描写叙述
  5. 进入到h2/bin文件夹,能够看到以下文件。当中h2.sh是以console方式启动。參考其新建h2_server.sh文件
    这里写图片描写叙述
  6. 编辑h2_server.sh。例如以下:
#!/bin/sh
dir=$(dirname "$0")
java -cp "$dir/h2-1.3.176.jar:$H2DRIVERS:$CLASSPATH" org.h2.tools.Server -tcpAllowOthers -webAllowOthers -webPort 8082 "$@"

说明:
org.h2.tools.Server: 以服务器模式启动
-tcpAllowOthers: 同意远程机器通过TCP方式訪问
-webAllowOthers: 同意远程机器通过浏览器訪问
-webPort 8082: 默认的訪问port(8082为未被占用的port,假设此port已经被其它port占用,则改为其它port)

  1. 启动h2服务(假设没有运行权限则须要更改h2_server.sh文件权限)
    这里写图片描写叙述

  2. 通过远程浏览器来訪问h2
    訪问地址:http://服务器ip:8082/
    出现例如以下页面。并点击test connection会出现test successful说明h2部署成功
    这里写图片描写叙述

说明:
Jdbc:h2:tcp://服务器ip/test: test是数据库文件的名称,(默认路径/usr/local/h2/bin)
User name : sa h2默认的用户,password为空
点击如图connectbutton。test数据库文件自己主动生成到/usr/local/h2/bin 文件夹下:test.h2.db


3. H2集群

3.1 集群综述

数据库支持简单的集群/高可用性机制。架构是:两个数据库服务运行在两台不同的计算机上,两台计算机有相同数据库的副本,假设两个服务器都处于运行状态,每一个数据库操作都被在两台计算机上运行。假设一台服务器宕机(断电、硬件故障、网络故障等),另外一台计算机仍能提供服务,从这一刻開始,数据库操作仅在一台服务器上运行。直到另外一台服务器恢复运行。


集群仅能用于服务器模式(内嵌模式并不支持集群)。能够在数据库运行状态下恢复集群而不用停止剩余的服务器(通过使用CreateCluster工具又一次创建)。已连接的应用程序会自己主动断开。可是加入上AUTO_RECONNECT = TRUE參数的。将自己主动重连。(可是要求在第二个数据库恢复期间没有应用在改变第一个数据库的数据。因此恢复集群是一个手工的过程。)
初始化集群,使用以下的步骤:
• 创建数据库
• 使用 CreateCluster工具创建一个数据库副本并分到另外的地方。而且初始化集群。这样就得到了相同数据的两个数据库
• 启动两个数据库服务(每一个数据库的副本)
• 如今能够通过应用client连接到数据库

3.2 创建集群

要了解集群怎样工作,请尝试以下的样例。在这个样例里。两个数据库分别在同不同计算机上。分别在两台计算机上新建base文件夹,这里在bin文件夹下。

  1. 创建文件夹
mkdir h2Server1 # 主机1上
mkdir h2Server2 # 主机2上
  1. 启动tcp服务
    分别在两台主机上。以服务器模式启动数据库服务,
    启动TCP服务指向第一个文件夹。你能够运行以下的命令:
    主机1上启动shell脚本:
#!/bin/sh
dir=$(dirname "$0")
java -cp "$dir/h2-1.3.176.jar:$H2DRIVERS:$CLASSPATH" org.h2.tools.Server -tcpAllowOthers -tcpPort 9101 -webAllowOthers -webPort 8081 -baseDir h2Server1 "$@"

主机2上启动shell脚本:

#!/bin/sh
dir=$(dirname "$0")
java -cp "$dir/h2-1.3.176.jar:$H2DRIVERS:$CLASSPATH" org.h2.tools.Server -tcpAllowOthers -tcpPort 9102 -webAllowOthers -webPort 8082 -baseDir h2Server1 "$@"

然后。使用 CreateCluster 工具初始化集群,假设数据库不存在,将创建一个新的空数据库,在主机1上运行:

Java -cp h2-1.3.176.jar org.h2.tools.CreateCluster 
-urlSource "jdbc:h2:tcp://172.16.21.139:9101/testCluster" 
-urlTarget "jdbc:h2:tcp://172.16.21.131:9102/testCluster" 
-user "sa" 
-serverList "172.16.21.139:9101,172.16.21.131:9102"

(说明:-urlSource和-urlTarget指明了哪个是主DB(全部select操作都从这个DB走),其它insert, delete, update操作分别向两个DB进行操作)。

• 如今应用或者H2控制台能够通过以下的JDBC的URL连接数据库:
jdbc:h2:tcp://172.16.21.139:9101,172.16.21.131:9102/testCluster
• 假设你停掉一个服务(通过杀进程),你会发现到其它机器继续工作,因此数据库仍能能够訪问。
• 恢复集群,你须要先删掉宕机的数据库,然后重新启动宕机的数据库的服务,再又一次运行CreateCluster集群工具。

3.3 检測运行状态下的集群

查找哪些节点当前正在运行,通过运行以下的SQL语句:

SELECT VALUE FROM INFORMATION_SCHEMA.SETTINGS WHERE NAME='CLUSTER'

结果返回为 ” (两个单引號),说明集群模式被屏蔽。否则,集群服务器列表将被单引號包括着返回。如’server1:9191,server2:9191’。
另外,也能够通过使用Connection.getClientInfo()获取服务列表。


从getClientInfo()返回的属性列表中,包括在连接列表服务器的数量一numServers属性。为了得到实际的服务器。 getClientInfo()也有属性server0..serverX ,当中serverX是服务器num再减去1 。
比如:为了获得在连接列表中第二服务器。能够通过使用getClientInfo(‘server1’)。注意: serverX属性仅仅返回的IP地址和port,而不是主机名。

3.4 集群限制

仅仅读查询仅仅针对第一个群集节点运行,但全部其它的语句在全部节点都会运行。

眼下还不支持针对事务的负载均衡。以下几个方法由于处在集群中不同节点,可能运行的结果会不同(操作会使两个数据库产生不一致的结果),必须慎重运行:
RANDOM_UUID(), SECURE_RAND(), SESSION_ID(), MEMORY_FREE(), MEMORY_USED(), CSVREAD(), CSVWRITE(), RAND(),[当没有使用种子]. 这些方法不能直接使用在改动语句中 (如INSERT, UPDATE, MERGE)。然而。你能够使用它们在仅仅读语句中,他们的结果也能用在改动语句中。

自己主动增长列和标识列不支持集群。当插入数据时,序列值须要手动创建。


在集群模式下,不支持SET AUTOCOMMIT FALSE语句,假设须要设置成为不自己主动提交,能够运行方法Connection.setAutoCommit(false)。


4. 稳定性与可用性

4.1 測试对照

測试场景,分为几种场景測试,分别对单节点单数据库方式与两台主机两个数据库分别多个线程插入查询增量的数据,进行性能分析,比較集群的性能损耗的,以及对集群的可用性,分别对两个server进行停止服务模拟宕机的情况。验证其可用性。

4.2 主机配置

1、 硬件配置:
- CPU:Intel(R) Core(TM) i5-4590 CPU @ 3.30GHz * 2(2核处理器)
- 内存:2G
- 磁盘:75G。RAID5磁盘阵列
2、 软件配置:
- 操作系统:CentOS Linux release 7.1.1503(Linux version 3.10.0-229.14.1.el7.x86_64)
- H2数据库:h2-1.3.176
- JDK: 1.7.0_79

4.3 单节点单数据库与集群对照

4.3.1 測试场景

測试场景1:起单个数据库服务,測试单节点下。操作简单SQL的性能;分别起N(1, 10, 100)个线程并发新增N(1万, 10万, 100万, 1000万)条记录。

測试场景2:两台主机分别起两个数据库服务,并对其进行集群配置,操作简单SQL的性能;分别起N(1, 10, 100)个线程并发新增N(1万, 10万, 100万, 1000万)条记录。

4.3.2 測试步骤:

1.首先以服务器模式启动数据库服务,详情參考:4.1.2 安装并採用服务器模式启动。
2.每次都先清除数据,保持数据库一致,运行以下语句:

DROP TABLE IF EXISTS TEST_TABLE;
CREATE TABLE TEST_TABLE(id VARCHAR(36),name VARCHAR(100));

3.通过jmeter,运行新增记录语句

INSERT INTO TEST_TABLE VALUES('測试id','測试name');

4.3.3 測试结果:

这里写图片描写叙述

4.4 集群下查询验证

4.4.1 測试场景

測试场景:两台主机分别起两个数据库服务,起10个线程不断运行以下语句,查询不同的数据条数(10万、100万)。

1 0 threads , 10万 records:

SELECT * FROM TEST_TABLE LIMIT 10000

主机1:
这里写图片描写叙述


主机2:
这里写图片描写叙述

1 0 threads , 100万 records:

SELECT * FROM TEST_TABLE LIMIT 100000

主机1:
这里写图片描写叙述

主机2:
这里写图片描写叙述

这里写图片描写叙述

4.5 可用性測试

4.5.1 測试场景

測试场景:两台主机分别起两个数据库服务,測试分别模拟当中一台宕机(停止服务)的情况。

4.5.1.1 測试场景1:

停掉target(server2) 数据库服务
1.集群情况下。停掉server2。然后运行以下语句,成功

INSERT INTO TEST_TABLE VALUES('測试1','測试1');
INSERT INTO TEST_TABLE VALUES('測试2','測试2');
INSERT INTO TEST_TABLE VALUES('測试3','測试3');

2.运行SELECT * FROM TEST_TABLE,能查询出数据

此时数据仅仅写入到server1:
这里写图片描写叙述

Server2上并没有写入:
这里写图片描写叙述

3.重新启动server2,此时能够看到server2数据自己主动又一次写入

这里写图片描写叙述

4.5.1.1 測试场景2:

停掉source(server1) 数据库服务

先又一次运行:

DROP TABLE IF EXISTS TEST_TABLE;
CREATE TABLE TEST_TABLE(id VARCHAR(36),name VARCHAR(100));

此时server1与server2数据库表都为空:
这里写图片描写叙述

这里写图片描写叙述

1.集群情况下。通过jmeter写入10万条数据。

2.写入数据过程中,停掉server1
通过訪问server1控制台无法连接,确认无法提供服务。
通过jdbc:h2:tcp://172.16.21.139:9101,172.16.21.131:9102/testCluster集群方式连接server2,出现能够成功连接。


Jmeter仍能继续写入数据。

3.完毕数据写入后
这里写图片描写叙述

Server1:
这里写图片描写叙述

Server2:
这里写图片描写叙述

4.重新启动server1仍不会将server2中的记录同步过去server1。仅仅能靠手工删除server1中的数据库,把server2的复制过去,重新启动集群服务。

4.7 结果分析

  1. 对于集群方式。update statement性能要比单机单数据库服务情况要下降50%-70%。

  2. 查询语句运行仅仅在第一个节点,压力不能分担到第二个节点。因此并发查询数据量过大的情况下有出现内存溢出情况。
  3. Server2停掉后。server1能继续提供数据库服务。

    并在server2重新启动后。集群工具自己主动同步数据。

  4. Server1停掉后。server2能继续提供数据库服务,集群工具自己主动不会同步数据,此时仅仅能靠手工删除server1中的数据库。把server2的复制过去,重新启动集群服务(这个结论感觉跟官方说明不太一样,可是验证的測试的结果是这样…问题在哪?)。



备注:

  1. 使用最新的1.4.x版本号也測了一下。保存文件方式改变了。
  2. 集群的时候,server2。停掉后,server1能继续提供数据库服务,在server2删掉数据文件后重新启动,须要又一次在用集群工具建立集群,此时须要注意urlSource 应为server1,urlTarget 应为server2。
  3. server1,停掉后,server2相同能继续提供数据库服务,在server1删掉数据文件后重新启动。须要又一次在用集群工具建立集群,此时须要更换urlSource 应为server2,urlTarget 应为server1。

    就是说以终于保持服务的数据库为准。使用集群工具启动集群服务时。将把urlSource 的数据文件复制到urlTarget ,假设弄反了。会把空数据库文件覆盖了在使用的数据库文件(相当于把数据都清空了~~)。到这里能够看出,跟官网描写叙述基本一致了。

  4. 数据进行同步过程中,会堵塞读写。
原文地址:https://www.cnblogs.com/yjbjingcha/p/7372744.html