数据库分切设计何必纠结于hibernate shard模式,应该简单化了
2014-11-21 14:27
375 查看
数据库分切设计何必纠结于hibernate shard模式,应该简单化了
最近讨论db shard的帖子比较多,感觉很多都是在参考hibernate shard的思路,但hibernate分表真的那么好吗?我觉得它最少有2个问题:
1. 改成shard后,代码的API调用要变。代码改动很大。
2. 设计很复杂,不清晰,逻辑关系难以理解。
hibernate shard基本上就是为了shard而对hibernate做的增增补补,凑合用还行,根本不具备设计上的参考价值。
对数据库分切方面,到目前为止,我觉得还是guzz的设计最清晰,如果我说的不对,欢迎理性讨论。不管您是否使用guzz,但是guzz在数据库分切方面的设计,对于清晰的设计模式,比hibernate shard更具有借鉴意义。
guzz垂直切分
垂直切分是指将不同的表分别存储到不同的数据库中。guzz默认配置级支持,不需要写任何代码,可以在任何时候,在需要时,将每张表存储到自己单独的一组服务器上,应该说是垂直分切的极限了。而且设计上,无论什么时候怎么分切,都不需要你改动代码。开发时你可以让所有表在一个库上;部署时,分到多个库上;以后业务增加了,再更加分散的放。
垂直分切简单配置方式:
1. 声明你要用多少台数据库,数据库之间什么关系。
Xml代码
<dialect class="org.guzz.dialect.H2Dialect"></dialect>
<dialect name="mysql5dialect" class="org.guzz.dialect.Mysql5Dialect" />
<dialect name="oracle10gdialect" class="org.guzz.dialect.Oracle10gDialect" />
<tran>
<dbgroup name="default" masterDBConfigName="masterDB" />
<dbgroup name="mysql" masterDBConfigName="masterDB" slaveDBConfigName="mysqlSlaveDB" dialectName="mysql5dialect" />
<dbgroup name="oracle" masterDBConfigName="oracleDB" dialectName="oracle10gdialect" />
</tran>
这里我们声明了3组数据库,而且数据库类型还不一样。
2. 对每张表,配置应该存储到那个库里
Xml代码
<a-business dbgroup="default" name="filterWord" class="com.guzzservices.business.FilterWord" />
<a-business dbgroup="mysql" name="filterWordGroup" class="com.guzzservices.business.FilterWordGroup" />
<a-business dbgroup="oracle" name="configuration" class="com.guzzservices.business.Configuration" />
简单的配置,将三个对象分别存储到3台不同的数据库中,完成垂直分切。
guzz水平切表
水平切表是指将一张大表,分切成许多小表。guzz的设计是当需要水平分表时,原先代码不变,为每个需要分切的表编写一个分表策略类,配置到系统中。然后在调用前,声明分表策略即可。
整个过程只需要新写一个类,在调用出增加一行代码即可,对原始系统入侵非常小,风险可控。
流程总比hibernate shard要清晰很多,具体可以看http://code.google.com/p/guzz/wiki/TutorialShadowTable?wl=zh-Hans
数据库主从分离
从垂直分切部分可以看到,guzz也是配置性的原生支持读写分离。如果需要增加从数据库,可以随时加上,不需要改任何代码。不需要改动代码,而且配置也不复杂,应该算是设计上的极限了吧?
你只需要在dbgroup中增加一个属性“slaveDBConfigName”,然后在一个properties文件中加上所有你需要的从数据库连接池配置即可,从数据库可以有许多台。
这个hibernate shard根本就没有涉及到。而且guzz允许程序控制读写库选取,和proxy模式的中间件路由各有优势,毕竟更加容易控制。如果你做过内容提前审核再允许发布的系统,就会明白proxy中间件解决不了全部问题,有些读操作不允许延迟,只能读主库,而是也是读事务,proxy中间件会很尴尬。
异构数据库
这个hibernate以及ibatis之类的更没有了。而且也是对应用透明的,你可以随时选择增加一种数据库,然后把某些表放到上面,如增加一个H2做应用端缓存数据库,自己完成类似Timesten + oracle的架构。
配置方式在上面的垂直分切小节也可以看到。
数据库连接池配置
随着表垂直和水平切分的进行,数据库会越来越多,数据源配置也会越来越多。guzz的设计是配置分组管理,类似Mysql的配置文件。每个数据源配置都在一个组内,无论增加多少都清晰了然,不会名字相互冲突。
示例:
Properties代码
[masterDB]
guzz.identifer=blogMasterDB
guzz.IP=localhost
guzz.maxLoad=120
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=true
user=root
password=root
acquireIncrement=10
idleConnectionTestPeriod=60
[updateMasterDB]
guzz.identifer=incUpdateDB1
guzz.IP=localhost
guzz.maxLoad=20
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/guzzSlowUpdate?useUnicode=true&characterEncoding=UTF-8
user=slowupdate
password=slowupdate
acquireIncrement=10
idleConnectionTestPeriod=60
[logMasterDB]
....
如果一些数据库对某些连接池支持更好,guzz设计上还允许为不同的数据源指定不同的连接池实现。
如果您需要分表,还是放弃hibernate shard或ibatis的设计模式吧,哪些只是临时拼凑出来的东西,设计上根本就不怎么样!
posted on 2010-10-18 21:02 深蓝色心情 阅读(2331) 评论(5) 编辑 收藏 所属分类: Java
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-18 22:09 YangL
hibernate shard大概是零七零八年的代码了吧,好像已经死了。
而guzz在国内的大型论坛应用上还是很不错的,如强国论坛、央视的投票系统。。。 回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-19 11:29 MyYate
水平划分时如何做到排序和分组统计?这个在企业应用里使用很多。http://code.google.com/p/guzz/wiki/TutorialShadowTable?wl=zh-Hans
我看这儿没有给出sample,谢谢~ 回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-19 13:07 darkbluefeeling
@MyYate
水平分切后这方面需要手工进行多表关联查询。水平分表不能自动的进行多表路由,这样分表所带来的性能各方面优势就没有了。
对于这种情况,建议您考虑下垂直分表,把表分到不同的机器上来提高性能。
回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-26 11:10 lll
问题在于,有些系统,瓶颈就在那一张表... ... 你就是单为这张表分配个服务器也没用 回复 更多评论
最近讨论db shard的帖子比较多,感觉很多都是在参考hibernate shard的思路,但hibernate分表真的那么好吗?我觉得它最少有2个问题:
1. 改成shard后,代码的API调用要变。代码改动很大。
2. 设计很复杂,不清晰,逻辑关系难以理解。
hibernate shard基本上就是为了shard而对hibernate做的增增补补,凑合用还行,根本不具备设计上的参考价值。
对数据库分切方面,到目前为止,我觉得还是guzz的设计最清晰,如果我说的不对,欢迎理性讨论。不管您是否使用guzz,但是guzz在数据库分切方面的设计,对于清晰的设计模式,比hibernate shard更具有借鉴意义。
guzz垂直切分
垂直切分是指将不同的表分别存储到不同的数据库中。guzz默认配置级支持,不需要写任何代码,可以在任何时候,在需要时,将每张表存储到自己单独的一组服务器上,应该说是垂直分切的极限了。而且设计上,无论什么时候怎么分切,都不需要你改动代码。开发时你可以让所有表在一个库上;部署时,分到多个库上;以后业务增加了,再更加分散的放。
垂直分切简单配置方式:
1. 声明你要用多少台数据库,数据库之间什么关系。
Xml代码
<dialect class="org.guzz.dialect.H2Dialect"></dialect>
<dialect name="mysql5dialect" class="org.guzz.dialect.Mysql5Dialect" />
<dialect name="oracle10gdialect" class="org.guzz.dialect.Oracle10gDialect" />
<tran>
<dbgroup name="default" masterDBConfigName="masterDB" />
<dbgroup name="mysql" masterDBConfigName="masterDB" slaveDBConfigName="mysqlSlaveDB" dialectName="mysql5dialect" />
<dbgroup name="oracle" masterDBConfigName="oracleDB" dialectName="oracle10gdialect" />
</tran>
这里我们声明了3组数据库,而且数据库类型还不一样。
2. 对每张表,配置应该存储到那个库里
Xml代码
<a-business dbgroup="default" name="filterWord" class="com.guzzservices.business.FilterWord" />
<a-business dbgroup="mysql" name="filterWordGroup" class="com.guzzservices.business.FilterWordGroup" />
<a-business dbgroup="oracle" name="configuration" class="com.guzzservices.business.Configuration" />
简单的配置,将三个对象分别存储到3台不同的数据库中,完成垂直分切。
guzz水平切表
水平切表是指将一张大表,分切成许多小表。guzz的设计是当需要水平分表时,原先代码不变,为每个需要分切的表编写一个分表策略类,配置到系统中。然后在调用前,声明分表策略即可。
整个过程只需要新写一个类,在调用出增加一行代码即可,对原始系统入侵非常小,风险可控。
流程总比hibernate shard要清晰很多,具体可以看http://code.google.com/p/guzz/wiki/TutorialShadowTable?wl=zh-Hans
数据库主从分离
从垂直分切部分可以看到,guzz也是配置性的原生支持读写分离。如果需要增加从数据库,可以随时加上,不需要改任何代码。不需要改动代码,而且配置也不复杂,应该算是设计上的极限了吧?
你只需要在dbgroup中增加一个属性“slaveDBConfigName”,然后在一个properties文件中加上所有你需要的从数据库连接池配置即可,从数据库可以有许多台。
这个hibernate shard根本就没有涉及到。而且guzz允许程序控制读写库选取,和proxy模式的中间件路由各有优势,毕竟更加容易控制。如果你做过内容提前审核再允许发布的系统,就会明白proxy中间件解决不了全部问题,有些读操作不允许延迟,只能读主库,而是也是读事务,proxy中间件会很尴尬。
异构数据库
这个hibernate以及ibatis之类的更没有了。而且也是对应用透明的,你可以随时选择增加一种数据库,然后把某些表放到上面,如增加一个H2做应用端缓存数据库,自己完成类似Timesten + oracle的架构。
配置方式在上面的垂直分切小节也可以看到。
数据库连接池配置
随着表垂直和水平切分的进行,数据库会越来越多,数据源配置也会越来越多。guzz的设计是配置分组管理,类似Mysql的配置文件。每个数据源配置都在一个组内,无论增加多少都清晰了然,不会名字相互冲突。
示例:
Properties代码
[masterDB]
guzz.identifer=blogMasterDB
guzz.IP=localhost
guzz.maxLoad=120
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8&useServerPrepStmts=true
user=root
password=root
acquireIncrement=10
idleConnectionTestPeriod=60
[updateMasterDB]
guzz.identifer=incUpdateDB1
guzz.IP=localhost
guzz.maxLoad=20
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/guzzSlowUpdate?useUnicode=true&characterEncoding=UTF-8
user=slowupdate
password=slowupdate
acquireIncrement=10
idleConnectionTestPeriod=60
[logMasterDB]
....
如果一些数据库对某些连接池支持更好,guzz设计上还允许为不同的数据源指定不同的连接池实现。
如果您需要分表,还是放弃hibernate shard或ibatis的设计模式吧,哪些只是临时拼凑出来的东西,设计上根本就不怎么样!
posted on 2010-10-18 21:02 深蓝色心情 阅读(2331) 评论(5) 编辑 收藏 所属分类: Java
Feedback
# re:数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-18 22:09 YangL
hibernate shard大概是零七零八年的代码了吧,好像已经死了。
而guzz在国内的大型论坛应用上还是很不错的,如强国论坛、央视的投票系统。。。 回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-19 11:29 MyYate
水平划分时如何做到排序和分组统计?这个在企业应用里使用很多。http://code.google.com/p/guzz/wiki/TutorialShadowTable?wl=zh-Hans
我看这儿没有给出sample,谢谢~ 回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-19 13:07 darkbluefeeling
@MyYate
水平分切后这方面需要手工进行多表关联查询。水平分表不能自动的进行多表路由,这样分表所带来的性能各方面优势就没有了。
对于这种情况,建议您考虑下垂直分表,把表分到不同的机器上来提高性能。
回复 更多评论
# re:
数据库分切设计何必纠结于hibernate shard模式,应该简单化了 2010-10-26 11:10 lll
问题在于,有些系统,瓶颈就在那一张表... ... 你就是单为这张表分配个服务器也没用 回复 更多评论
相关文章推荐
- Hibernate中应用dao设计模式进行数据库的增删改查操作
- 用设计模式开发通用数据库操作器 lornshrimp [原作]
- Struts+Hibernate模板开发笔记---设计模式:单例
- JAVA中数据库操作的各种方式与设计模式的应用
- 设计模式在Java数据库编程中的运用
- 数据库物理模型设计的其他模式之自联结模式
- 用设计模式开发通用数据库操作器
- 使用设计模式构建通用数据库访问类
- JAVA中数据库操作的各种方式与设计模式的应用(http://blog.csdn.net/wangyihust/archive/2006/01/14/579613.aspx)
- 用设计模式开发通用数据库操作器
- 使用设计模式构建通用数据库访问类
- Struts+Hibernate模板开发笔记---设计模式:MVC
- 使用设计模式构建通用数据库访问类(转自天极)
- 使用设计模式构建通用数据库访问类
- JAVA中数据库操作的各种方式与设计模式的应用
- 使用设计模式构建通用数据库访问类
- 使用设计模式构建通用数据库访问类
- 用设计模式开发通用数据库访问器
- PetShop3.x学习笔记8-《PetShop 3.x的设计模式与体系结构》节选-数据库可移植性
- JAVA中操作数据库方式与设计模式的应用