当前位置: 首页 > 工具软件 > CobarClient > 使用案例 >

轻量级分布式数据库访问层amoeba,cobarClient试用感受

赏开宇
2023-12-01

轻量级分布式数据库访问层amoeba,cobarClient试用感受



最近准备鼓捣一下读写分离,数据shading等这一类型数据scale的东东。

因为用的是mysql,双master,master-slave,master-salves-slaves,master-master-slaves-slaves都看了一下,简单的试了一下master-slave,成功OK。

但是在应用层次如何来透明的应对和管理这些多个数据源,甚至实现loadblance和HA,fail over呢。

比较好的做法就是引入一个单独的数据访问层,来屏蔽掉对应用层次的细节了。

 

mysql的话,用得最多的当然mysqlproxy。但这个东东全靠写lua脚本,又要去学一个语言,麻烦啊。而且听说在数据源很多很复杂的情况下,lua脚本写起来也是很多很复杂。

处于暂时的研究目的,就先不去试这个了。就找了两个国内这个方面比较好的开源项目来试一下。一个就是amoeba,一个就是cobarClient了~!

 

####试用amoeba感受####

amoeba首页在此:

http://amoeba.meidusa.com/wordpress/

amoeba主要是引入了一个对于应用层次完全透明的数据访问层,和应用层链接采取mysql协议。在取得客户端请求后,解析mysql协议,解析sql,然后按切分和路由规则发送到相应的db实例中。具体的自己点进去看吧。amoeba目前只能针对多个数据库实例进行分片,而不能单个数据库实例里面表分片。目前也不支持事务。

 

下面是一些试用过程中的片段:

一 。  amoeba进行数据水平切分的测试,采用的innodb引擎:

用一个id取摸的简单规则进行了测试;


insert,这种是可以正确切分的:
insert into staff(id,name) values(1,'name');
insert into staff(id,name) values(2,'name');

但是如果写

insert into staff(id,name) value(2,'name');

就要悲剧。。。貌似目前对sql的写法细节比较挑。

insert into staff values (id1,name1),(id2,name2)....;
insert into staff values (null,name1),(null,name2)....;
也不能正确shading,插入到default dbserver去了。1是这种批量插入写法amoeba暂时不支持,2是路由规则匹配不到就直接进入defaultdb执行。

如果你每个db的表主键都采用自增id的话,写如下sql

insert into staff(name) values(10);
每个db都会插入数据。采用当前db表的自增序列。可能造成不同库id重复的情况,这一点在数据迁移的时候和跨库数据读取交互的时候会存在很大问题。
解决方法是:你必须要在sql里面带上主键的值,且保证切分规则对于不同的数据传入的主键值不重复。
                         所以一旦分片,最好建立一个全局的id,并且在插入的时候显式指定。

 

二 。   虽然amoeba说明目前不支持事务。但我还是打算试一下路由到单个db实例时候的事务是否正确。

把autocommit设置为0
之后连续两个insert(都路由到db1)之后rollback,再来一次commit的,木啥问题.没commit的话,数据库中实际数据也没有插入。

但是放到应用中(spring3.x+ibatis2.x),使用Spring的dataSourceTrsantionManager管理事务。

测试一个简单的插入语句insert,之后throw异常,发现无法回滚。。。。

看来事务确实有很多问题,暂时不支持,分布式的就更别提了。。

 

三 。  测试一下对多个db库的负载均衡和HA的支持

先自己开启mysql的两个实例,做好读写分离。然后配置amoeba

先在dbserver.xml配置下面的db以及虚拟db
<dbServer name="server1"  parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">127.0.0.1</property>

<!-- mysql password
<property name="password">lumi</property>
-->
</factoryConfig>
</dbServer>

<dbServer name="server2"  parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">220.167.54.227</property>
<property name="port">32230</property>
<!-- mysql password
<property name="password">lumi</property>
-->
</factoryConfig>
</dbServer>

<dbServer name="virtualSlave" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>

<!-- Separated by commas,such as: server1,server2,server1 -->
<property name="poolNames">server1,server2</property>
</poolConfig>
</dbServer>
然后在amoeba.xml做路由配置


<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
<property name="ruleLoader">
<bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
<property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
<property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
</bean>
</property>
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
<property name="LRUMapSize">1500</property>
<property name="defaultPool">server1</property>

<!-- -->
<property name="writePool">server1</property>
<property name="readPool">virtualSlave</property>

<property name="needParse">true</property>
</queryRouter>

最后去掉rule.xml里面的配置信息,全部把路由规则交给amoeba.xml里面的queryRouter。ok重启amoeba。
进去后发现select语句在两台db实例间轮询查询,说明负载平衡起作用了。关掉其中一个db实例后,全部都走另外一个db实例查询。

后面有测试了,将两个db实例做成一个virtualMasterDB,然后loadbalance配置为HA。写全部指向第1个db实例,这台挂了后自动指向第2个db实例。

读的话就跟之前测试这个一样全部指向VirtualSlave。全部OK。这样一个简单的master-master-slaves的loadblance+简单HA的架构就搭建起来了。

 

看来目前aomeba的问题就是,很多细节上支持尚不完善,如sql解析等等。不支持local事务。另外引入这个虚拟层后本身就变成了一个单点的问题还需要解决。

关于性能的话,本身基于java的,可以调整虚拟机参数还有各种链接参数,另外性能报告这里有一个:http://www.54chen.com/java-ee/amoeba-benchmark-report.html 还行。

最后再给个官方参考文档例子:http://docs.hexnova.com/amoeba/

 

###使用cobarClient感受###

cobarClient是淘宝开源的基于ibatis的cobarClinet数据库分布式数据访问层框架。看介绍应该用于过一些实际当中的项目。这个东东诞生的初期就是因为当时客户不愿意使用阿里的cobarServer层次的数据层解决方案(应该跟amoeba的思路差不多吧,单独的虚拟层,莫非就是淘宝现在TDDL的前身,据说阿里大部分用cobarserver来解决,淘宝用的tddl?),因为要单独使用一个server层的物理机器。就搞了个这个轻量级的应用层使用的shading框架解决方案出来。

这个东东的地址是 http://code.alibabatech.com/wiki/display/CobarClient/Home。
中文手册地址:http://code.alibabatech.com/docs/cobarclient/zh/

这个框架是基于Maven2.2.1, iBatis 2.3.4. 726 , Spring2.5.6SEC01..02(Spring3 is NOT supported, its API is changed), MVEL2.0.16(里面的切分表达式用的语句)

spring3x由于api变动无法用,同理ibatis3x也一样悲剧
CobarClient因为是更高层次的封装,(相对于protocol,driver等级别,比如amoeba这种)也就是应用框架级别的封装,所以更好扩展。
相对于amoeba来说,他没有解析sql的过程,路由sql和shading规则都是扩展spring的SqlMapClinetTemple拦截解析ibatis的sqlmap statement来做的。
对比amoeba,amoeba相当于是引入了一个完整的数据访问中间件层,对应用透明。CobarClient对DAL层有一定的侵入,且目前只支持ibatis2x,和spring2x,所以你的
应用系统也必须要基于这两个框架。
测试了一下,相对来说。CobarClient目前的功能更丰富,更多切分的细节方便控制。一样可以做简单的HA,。目前还没看到如何做loadblance。只支持简单的双击HA。但如果在rule规则中自己扩展好的话,应该一样可以实现loadblance。
因为amoeba要解析mysql协议,要对sql做parse。目前看来很多特殊的sql写法都有支持不完整的情况。
比如insert into tbale1 values(xx),(xx)...这种是当前是没法做切分的。而cobarClient可以。不可以的话你在应用层也更加方便扩展和修改。


而amoeba不支持事务。cobarClient支持Best Effort 1PC的食物支持。
保证一个数据操作过程中多个数据源各自的本地事务, 但不保证全局的分布式事务

对于中小型项目,用cobarClient更方便定制化和自己扩展。

 类似资料: