C-JDBC
C-JDBC
C-JDBC(Java 数据库连接群集)作为开发源码的数据库群集中间件,可以让任何应用程序通过JDBC能够透明的访问数据库群集。数据库可以分布在多个节点并可以进行数据复制,C-JDBC能够均衡在这些节点之间的查询负载。 C-JDBC通过软件来实现RAIDb(廉价数据库冗余阵列)。C-JDBC是GNU LGPL许可证下的ObjectWeb项目。
http://c-jdbc.objectweb.org/网站上的C-JDBC-Brochure-EN.pdf写的内容挺好。(C-JDBC)tutorial.pdf内容也挺翔实。
大型应用随着用户量访问越来越大,增加数据库存储和做好数据库冗余可以增加系统的可靠性和性能。
无需修改客户端应用程序,无需变更应用服务器或数据库服务器软件。C-JDBC的JDBC driver把SQL请求转给C-JDBC controller(负责在databases之间做负载均衡)
The database is distributed and replicated among several nodes and C-JDBC load balances the queries between these nodes.
就这一句话就太诱人了!
上周的某一个上午,搞定C-JDBC的安装配置啦~
主要根据官方的user guide和这篇好文: http://huaronghu.spaces.live.com/blog/cns!B9A68E1C1CA857AD!288.entry
准备工作:
环境:windows,postgreSQL,JDK
建立数据库“们”,安装若干db在若干server上,所以如果使用商业数据库的话,就会需要好几套的钱哪。
安装C-JDBC:
下载了binary版的c-jdbc-2.0.2-bin.zip,解压到作为C-JDBC server的机器上(e.g. C:\software\c-jdbc-2.0.2-bin),
设置环境变量,新增系统变量:CJDBC_HOME =C:\software\c-jdbc-2.0.2-bin
把实际使用的数据库的JDBC driver(例如mysql-connector-java-3.1.12-bin.jar ,postgresql-8.0.309.jdbc2.jar)拷贝到c-jdbc/drivers 中
配置文件:
在c-jdbc-2.0.2-bin/config/virtualdatabase目录中创建虚拟数据库配置文件。
里面DatabaseBackend 标签中定义的就是被集群的数据库。
试验时,创建了文件:postgresql-raidb1-distribution.xml,使用了2个postgreSQL数据库,采用了全复制的方法。
注意,如果采用全复制,所以在2个数据库上建库、建表的全部脚本都要完全相同,否则将会报出mismatch的错误。
目前感觉配置里面最有用的配置就是<AuthenticationManager>,<DatabaseBackend>和<LoadBalancer>(还没有仔细看)。
配置时可以参考已经提供的例子,c-jdbc-2.0.2-bin/config/RAIDb-1-full-example.xml,里面对每一个属性都有比较详细的注释,DatabaseBackend中还有各个开源数据库连接的例子,挺贴心的。
<! DOCTYPE C-JDBC PUBLIC "-//ObjectWeb//DTD C-JDBC 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-2.0.2.dtd" >
< C-JDBC >
< VirtualDatabase name ="myDB" maxNbOfConnections ="20" minNbOfThreads ="1" maxNbOfThreads ="20" blobEncodingMethod ="hexa" >
< AuthenticationManager >
< Admin >
< User username ="admin" password ="c-jdbc" />
</ Admin >
< VirtualUsers >
< VirtualLogin vLogin ="boss" vPassword ="boss" />
</ VirtualUsers >
</ AuthenticationManager >
< DatabaseBackend name ="postgreSQLNode114" driver ="org.postgresql.Driver" url ="jdbc:postgresql://10.10.0.114:5432/clusterdb" connectionTestStatement ="select now()" >
< DatabaseSchema dynamicPrecision ="column" />
< ConnectionManager vLogin ="boss" rLogin ="postgres9" rPassword ="12345" >
< RandomWaitPoolConnectionManager poolSize ="20" />
</ ConnectionManager >
</ DatabaseBackend >
< DatabaseBackend name ="postgreSQLNode155" driver ="org.postgresql.Driver" url ="jdbc:postgresql://10.10.0.155:5432/clusterdb" connectionTestStatement ="select now()" >
< DatabaseSchema dynamicPrecision ="column" />
< ConnectionManager vLogin ="boss" rLogin ="postgres" rPassword ="abcde" >
< RandomWaitPoolConnectionManager poolSize ="20" />
</ ConnectionManager >
</ DatabaseBackend >
< RequestManager >
< RequestScheduler >
< RAIDb-1Scheduler level ="passThrough" />
</ RequestScheduler >
< RequestCache >
< MetadataCache maxNbOfMetadata ="10000" maxNbOfField ="0" />
< ParsingCache backgroundParsing ="false" maxNbOfEntries ="5000" />
< ResultCache granularity ="table" maxNbOfEntries ="100000" pendingTimeout ="0" >
< ResultCacheRule queryPattern ="default" timestampResolution ="1000" >
< EagerCaching />
</ ResultCacheRule >
</ ResultCache >
</ RequestCache >
< LoadBalancer >
< RAIDb-1 >
< RAIDb-1-LeastPendingRequestsFirst />
</ RAIDb-1 >
</ LoadBalancer >
</ RequestManager >
</ VirtualDatabase >
</ C-JDBC >
在c-jdbc-2.0.2-bin/config/controller目录中创建一个c-jdbc controller的配置文件。
试验时,创建的配置文件为:uud-controller-distributed.xml
<! DOCTYPE C-JDBC-CONTROLLER PUBLIC "-//ObjectWeb//DTD C-JDBC-CONTROLLER 2.0.2//EN" "http://c-jdbc.objectweb.org/dtds/c-jdbc-controller-2.0.2.dtd" >
< C-JDBC-CONTROLLER >
< Controller port ="25322" >
< Report />
< JmxSettings >
< RmiJmxAdaptor port ="1091" />
</ JmxSettings >
< VirtualDatabase configFile ="postgresql-raidb1-distribution.xml" virtualDatabaseName ="myDB" autoEnableBackends ="true" checkpointName ="Initial_empty_recovery_log" />
</ Controller >
</ C-JDBC-CONTROLLER >
注意:Controller和VirtualMachine的配置文件不能采用相同的文件名
启动:
在c-jdbc-2.0.2-bin\bin目录下,运行controller.bat -f ../config/controller/uud-controller-distributed.xml
unix用户使用controller.sh来启动controller
截图:(下回补)
凑合看一下吧,控制台的正常输出:
C:\software\c-jdbc-2.0.2-bin\bin>controller.bat -f ../config/controller/uud-cont
roller-distributed.xml
2007-03-07 15:16:44,017 INFO controller.core.Controller C-JDBC controller (2.0.
2)
2007-03-07 15:16:44,439 INFO controller.core.Controller Loading configuration f
ile: ../config/controller/uud-controller-distributed.xml
2007-03-07 15:16:44,752 INFO controller.core.Controller JMX is enabled
2007-03-07 15:16:44,830 INFO controller.core.Controller Starting JMX server on
host: 10.10.0.155
2007-03-07 15:16:46,376 INFO backend.DatabaseBackend.postgreSQLNode114 Adding c
onnection manager for virtual user "boss"
2007-03-07 15:16:46,501 INFO backend.DatabaseBackend.postgreSQLNode155 Adding c
onnection manager for virtual user "boss"
2007-03-07 15:16:46,642 INFO controller.RequestManager.myDB Request manager wil
l parse requests with the following granularity: TABLE
2007-03-07 15:16:46,657 WARN controller.virtualdatabase.myDB No recovery log ha
s been configured, enabling backend without checkpoint.
2007-03-07 15:16:48,641 INFO backend.DatabaseBackend.postgreSQLNode114 Detected
backend as: PostgreSQL
2007-03-07 15:16:49,063 WARN backend.DatabaseBackend.postgreSQLNode114 Statemen
t.getGeneratedKeys not supported.
2007-03-07 15:16:49,579 INFO backend.DatabaseBackend.postgreSQLNode114 Gatherin
g database schema
2007-03-07 15:16:49,782 INFO controller.RequestManager.myDB Setting new virtual
database schema.
2007-03-07 15:16:49,782 INFO cjdbc.controller.cache Setting new database schema
.
2007-03-07 15:16:49,782 INFO controller.loadbalancer.RAIDb1 Adding blocking tas
k worker thread for backend postgreSQLNode114
2007-03-07 15:16:49,797 INFO controller.loadbalancer.RAIDb1 Adding non blocking
task worker thread for backend postgreSQLNode114
2007-03-07 15:16:49,797 INFO controller.RequestManager.myDB Database backend po
stgreSQLNode114 is now enabled
2007-03-07 15:16:50,922 INFO backend.DatabaseBackend.postgreSQLNode155 Detected
backend as: PostgreSQL
2007-03-07 15:16:51,328 WARN backend.DatabaseBackend.postgreSQLNode155 Statemen
t.getGeneratedKeys not supported.
2007-03-07 15:16:52,172 INFO backend.DatabaseBackend.postgreSQLNode155 Gatherin
g database schema
2007-03-07 15:16:52,390 INFO controller.RequestManager.myDB Virtual database sc
hema merged with new schema.
2007-03-07 15:16:52,390 INFO cjdbc.controller.cache Merging new database schema
2007-03-07 15:16:52,390 INFO controller.loadbalancer.RAIDb1 Adding blocking tas
k worker thread for backend postgreSQLNode155
2007-03-07 15:16:52,390 INFO controller.loadbalancer.RAIDb1 Adding non blocking
task worker thread for backend postgreSQLNode155
2007-03-07 15:16:52,406 INFO controller.RequestManager.myDB Database backend po
stgreSQLNode155 is now enabled
2007-03-07 15:16:52,422 WARN VirtualDatabaseWorkerThread.myDB.metadata Metadata
key [getMaxColumnsInIndex] is not compatible. (Backends are: [jdbc:postgresql:/
/10.10.0.114:5432/clusterdb] and [jdbc:postgresql://10.10.0.155:5432/clu
sterdb] ; Values are:[32] and [0])
2007-03-07 15:16:52,422 INFO controller.core.Controller Adding VirtualDatabase
myDB
2007-03-07 15:16:52,437 INFO controller.core.Controller Waiting for connections
on 0.0.0.0:25322
2007-03-07 15:16:52,469 INFO controller.core.Controller Controller started on 2
007.03.07 10 at 03:16:52 下午 GMT+08:00
2007-03-07 15:16:52,484 INFO controller.core.Controller Controller 10.10.0.
155:25322 ready, listening to requests ...
遇到过的问题:
1、
刚启动没一会儿,就看到config文件读取错误,控制台信息也就此结束。
解决方法:controller.bat -f filename中filename的相对路径和文件名竟然都写错了,汗。。。。
2、
启动时,控制台抛出ERROR以及exception,大意是connection failed, IP没有配置到pg_hba.conf中
解决方法:虽然是连本机的一个数据库,但是由于数据库连接的url里面写的是IP地址,所以仍然要把本机的IP地址配置到pg_hba.conf以允许其访问。
3、
还是启动时抛错了,Connection test failed(org.postgresql.util.PSQLException:Backend start-up failed:FATAL:role "boss_user" does not exist.)
解决方法:原来是在自己写的.xml配置文件中,DatabaseBackend标签里面写的用户名和密码需要是真实数据库的真实用户名和密码。
最后都整好了,但是遇到一个warn的log:
backend.DatabaseBackend.postgreSQLNode155 Statement.getGeneratedKeys not supported
至今不知道是什么问题,有什么影响.
代码部分:
只需要修改应用程序用到的jdbc driver的配置,把c-jdbc/drivers/目录下的c-jdbc-driver.jar拷贝到应用程序的工程里,并加入到class-path中。
之前是使用 Class.forName("com.somevendor.jdbcDriver.Driver") 去连接某特定的数据库
现在是使用 Class.forName("org.objectweb.cjdbc.driver.Driver") 统一处理。
连接字符串:DriverManager.getConnection("jdbc:cjdbc://localhost:25322/mycjdbc") 取得数据库连接。
c-jdbc server称为c-jdbc controller,聆听请求们
其他所有通过c-jdbc来访问的DB们称为db backends.
jdbc:cjdbc://host1:port1,host2:port2/database
host是指跑着c-jdbc controller的机器IP,port是指controller监听客户端链接的端口,默认端口号:25322
注意,不仅真正的DB安装多个在多个机器上,c-jdbc controller也可以安在不同的机器上,这样可以防止一个c-jdbc 坏掉带来的风险。
例如:
DriverManager.getConnection( " jdbc:cjdbc://c1.objectweb.org,c2.objectweb.org/tpcw " ); // 不验证用户名密码
DriverManager.getConnection( " jdbc:cjdbc://host/db?user=me&password=secret " ) // 验证用户名密码的写法1
DriverManager.getConnection( " jdbc:cjdbc://host/db;user=me;password=secret " ) // 验证用户名密码的写法2
然后可以在代码中insert/update几个记录,再单独到各个数据库中去查一下,应该都受到影响就对了。
问题:
1、管理C-JDBC,不知道C-JDBC需要啥管理,不过好像是已經有一個簡單的 Desktop Application 可以控制相關的 administration 介面, 最重要的是, 他結合了 JMX , 可以讓整個監控的環境更完整.. (等待尝试)
2、不知道通过C-JDBC来操作速度如何
3、RAIdb的3种类型,采取哪个更好?把表分开在不同server上对联表查应该不会有影响吧?
其他:
1、Configuring C-JDBC with Jakarta Tomcat
Copy the c-jdbc-driver.jar file to the lib directory of your web application (for example: $TOMCAT_HOME/webapps/mywebapp/WEB-INF/lib).
There are many ways to obtain connections from a Tomcat application. Just ensure that you are using org.objectweb.cjdbc.driver.Driver as the driver class name and that the JDBC URL is a C-JDBC URL
2、Configuring C-JDBC with Hibernate
C-JDBC just has to be defined as any JDBC driver in Hibernate, leaving the syntax set to the proper database. Here is a configuration example to use Hibernate with a C-JDBC cluster made of Sybase backends:
## C-JDBC
hibernate.dialect net.sf.hibernate.dialect.SybaseDialect
hibernate.connection.driver_class org.objectweb.cjdbc.driver.Driver
hibernate.connection.username user
hibernate.connection.password pass
hibernate.connection.url jdbc:cjdbc://localhost:25322/test