freyja v2版本发布
上回说了
freyja将重新把重心放在orm、sharding、cache上
1、更完善的orm
2、应用层屏蔽的底层sharding
3、应用层上的cache
那么,直接上代码了。
因为没什么开源经验,所以直接介绍freyja的思想和代码了。
1、cache部分直接改的是spring aop cache
spring cache 拓展
加了几个annotation:
CacheDelete、CacheListReplace 等等。。。。
现在存在2个问题:1、不是线程安全的。2、不知道如何才能像spring 的cache 注解那样 被扫描到:http://www.iteye.com/problems/83419
另外:cache和freyja v2没有任何关系。
cache的介绍有点少,缓存越接近上层效率越高。所以基本上放弃了freyja v1对缓存的理解,改到上层缓存。
通过注解维护缓存的关系。上面的spring cache 拓展实际上是之前写的,现由对其进行了大改。山寨、拓展了spring 自带cache 同样使用spel表达式 CacheSave这个注解略微不同,key取值取的是返回值,以后会补上一篇介绍。
2、orm
orm部分采用自己的annotation:@Id,@Column,@Table,@Transient 用这几个来标注实体与表的关系
orm比纯jdbc带来的开销在于一层的sql解析,sql解析交给了温少的alibaba.druid的sql parser部分来处理。
(温少是谁?:http://code.alibabatech.com/wiki/dashboard.action)
解析的效率很高,具体有多高我没具体测试过。以为无论开销多大对于项目来说是属于可忽略的开销,因为项目的sql都是预编译sql,解析这一层被缓存了所以开销可忽略。
orm的语法上和上一版的基本一致。
3、sharding
sharding部分和orm基本上没任何关系,这个部分只针对纯sql 的处理。我觉得freyja的sharding方式趋于完美
freyja v2的sharding 由@SubColumn决定分库、分表方式。@SubColumn是以这个字段为基准对记录进行切分
public DbResult getShardingTableName(Object value) { String tableName = getTableName(); int hashCode = value.hashCode(); if (hashCode < 0) { hashCode = -hashCode; } int dbNo = hashCode % ShardingUtil.engine.getDbNum(); int tableNo = hashCode % ShardingUtil.engine.getTableNum(); tableName = tableName + "_" + tableNo; return new DbResult(tableName, tableNo, dbNo); } public DbResult getShardingTableNameById(Object idValue) { String tableName = getTableName(); if (idValue == null || !isSubTable()) { return new DbResult(tableName, -1, -1); } else { int n = (Integer) idValue / ShardingUtil.engine.getIdSubNum(); int dbNo = n / ShardingUtil.engine.getTableNum(); int tableNo = n % ShardingUtil.engine.getTableNum(); tableName = tableName + "_" + tableNo; return new DbResult(tableName, tableNo, dbNo); } }
配合spring jdbc的AbstractRoutingDataSource 达到一个多数据源操作环境
具体而言如果你需要对t_user表进行分库、分表操作:
1、 <bean id="fryjaTemplate" class="org.freyja.v2.jdbc.FreyjaJdbcTemplate">
<property name="jdbcTemplate" ref="jdbcTemplate" /> <property name="packagesToScan" value="com.x.data.bean" /> <property name="freyjaProperties"> <value> show_sql=true db_num=2 table_num=2 id_sub_num=1000000 </value> </property> </bean>
配置 db_num、table_num、id_sub_num
id_sub_num为每张表容量,另外建表的时候需要修改对应的自动增长起始值
<bean id="baseDataSource" parent="parentDataSource"> <property name="url" value="${mysql.url}" /> <property name="username" value="${mysql.user}" /> <property name="password" value="${mysql.password}" /> </bean> <bean id="dataSource" class="com.guyu.core.spring.datasource.DynamicDataSource"> <property name="targetDataSources"> <map key-type="java.lang.Integer"> <entry key="0" value-ref="pu_game_0" /> <entry key="1" value-ref="pu_game_1" /> </map> </property> <property name="defaultTargetDataSource" ref="baseDataSource" /> </bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource" ref="dataSource" /> </bean>
2、你需要在User实体上加上@Table(name = "t_user", isSubTable = true)
标注这个表需要切分
3、 @Column(name = "open_id")
@SubColumn(isSubColumn = true) private String openId;
需要选取其中一个字段标注为SubColumn
sharding针对的是纯jdbc,有兴趣的可以研究下druid的sql parser (ps:资料很少)
其他的补充:
1、为什么freyja1和2都要用spring jdbc?
没什么特别的理由,一直都在用hibernate但先接触的spring jdbc,觉得还不错就用了。另外spring jdbc本身就很接近于orm所以就对他进行了改造。
2、druid
在做freyja v1的时候实际上都有了解过druid的sql parser功能,但是觉得老外的jsqlparser出来得早用的人多会比较好就用了jsqlparser。
后来做v2发展sharding功能的时候联系到了温少,他让我看sql parser。结果真不得了。sql parser要什么有什么,例如orm部分sql parser直接就支持而且非常方便。虽然有点问题但是反馈给温少之后一会儿就解决了。sharding功能也是在交流过程中产生的。
附件中的压缩包中的druid_0.2.11111.jar是包含sharding支持的版本。druid的最新版不知道有没有发布包含这个部分。
还需要大量的测试测试测试和测试,现在freyja v2用于项目当用,有什么需要修复和添加的功能都会随着实际应用而改动。
希望大家就cache、orm、sharding部分的实现思路进行讨论!
下一篇: php怎么实现简单密码登录
推荐阅读
-
苹果发布了第二个测试版本的OS X 10.11
-
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
-
FormValid0.5版本发布,带ajax自定义验证例子
-
最新发布的Chrome 45版本内存消耗暴减1/4 性能大提升
-
3月9日发布的Apple Watch 22种选择:你会购买哪个版本?
-
苹果新发布本本MacBook Pro Retina版本拆机详细过程(大量组图)
-
微信发布新版本SDK 开发者赶快升级
-
《ServerSuperIO Designer IDE使用教程》-2.与硬件网关数据交互,并进行数据级联转发,直到云端。发布:v4.2.1版本
-
.net的mvc的fw版本为4.5发布到阿里云【云虚拟主机】上.
-
AMD 17.1.1显卡驱动发布下载:有史以来最强一次驱动版本迭代