writeType="0" dbType="mysql" dbDriver="native">
select user()
在238上授权授权:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'youngsun';
flush privileges;
5、
配置
rule.xml
文件
在schema.xml的文件内容中可看到t_user表指定的分片规则是rule1,需要在conf/rule.xml文件中设置rule1的规则为根据user_id进行分片,并按照类“org.opencloudb.route.function.PartitionByLong”的规则进行分片,即将user_id模除1024后每256内分到一个数据库中,即模除后0~255到user0数据库库,256~511到user1数据库,512~767到user2数据库,768~1023到user3数据库。
总结心得:普通取模算法,连续的id会路由到不同的分片。增大了批量插入的事务控制难度,而固定分片hash算法根据二进制则可能会分到连续的分片,减少插入事务事务控制难度。
该文件的参考内容如下所示:
xml version="1.0" encoding="UTF-8"
?>
DOCTYPE mycat:rule SYSTEM "rule.dtd"
>
<
mycat:rule
xmlns:mycat
="http://org.opencloudb/"
>
<
tableRule
name
="rule_wyh"
>
<
rule
>
<
columns
>
user_id
columns
>
<
algorithm
>
func_4p
algorithm
>
rule
>
tableRule
>
<
function
name
="
func_4p
"
class
="org.opencloudb.route.function.PartitionByLong"
>
<
property
name
="partitionCount"
>
4
property
>
<
property
name
="partitionLength"
>
256
property
>
function
>
mycat:rule
>
6、
配置
server.xml
文件
在server.xml文件中的schemas属性中添加test_sharding的schema。修改后的文件如下所示:
DOCTYPE mycat:server SYSTEM "server.dtd"
>
<
mycat:server
xmlns:mycat
="http://org.opencloudb/"
>
<
system
>
<
property
name
="sequnceHandlerType"
>
0
property
>
system
>
<
user
name
="test"
>
<
property
name
="password"
>
test
property
>
<
property
name
="schemas"
>
weixin,yixin,photo,
test_sharding
property
>
user
>
mycat:server
>
7、
水平切分测试
重启MyCAT,使用MySQL客户端连接后,连接后可在test_sharding数据库下看到t_user和t_user_class_rel表,
在MySQL客户端连接的MyCat的test_sharding数据库的t_user表运行如下插入语句,插入user_id=1、255、256、511、512、1023、1024、50、300、1000的数据:注意insert into 必须带上字段名列表,不然报错插不进去。
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('1', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('255', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('256', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('511', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('512', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('1023', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('1024', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('50', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('300', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
INSERT INTO t_user( user_id , receive_address , create_time , province_code ) VALUES('1000', '广州市越秀区广州大道中599号', '2014-07-17 10:53:15', 'GD');
而后在MyCAT的test_sharding数据库的t_user表运行select查看记录执行情况。进入localhost的user0~user3数据库,查看数据是否按照之前确定的rule1的规则写入不同的数据库。
读者可在test_sharding数据库的t_user表执行update和delete等语句,并去分库查看执行结果,可得知MyCAT对MySQL客户端基本透明,对程序也几乎透明,在select语句运行时,MyCAT会自行去各个分库按照规则获取合并结果。
接着测试按照ER关系策略分片的t_user_class_rel表是否按照user_id的分片策略,同样user_id的数据分布在同一个user库的t_user表和t_user_class_rel表。
在MyCAT的test_mycat数据库的t_user_class_rel表运行如下语句:
INSERT INTO `t_user_class_rel`( `id` , `caller` , `province_code` , `user_id` , `class_id` , `role_type` , `create_time` , `modify_time`) VALUES ('257', 'eip', 'GD', '2', '35', '3', '2012-08-05 17:32:13', '2013-12-27 16:07:32');
INSERT INTO `t_user_class_rel`( `id` , `caller` , `province_code` , `user_id` , `class_id` , `role_type` , `create_time` , `modify_time`) VALUES ('1', 'eip', 'GD', '257', '35', '3', '2012-08-05 17:32:13', '2013-12-27 16:07:32');
INSERT INTO `t_user_class_rel`( `id` , `caller` , `province_code` , `user_id` , `class_id` , `role_type` , `create_time` , `modify_time`) VALUES ('2', 'eip', 'GD', '513', '35', '3', '2012-08-05 17:32:13', '2013-12-27 16:07:32');
INSERT INTO `t_user_class_rel`( `id` , `caller` , `province_code` , `user_id` , `class_id` , `role_type` , `create_time` , `modify_time`) VALUES ('3', 'eip', 'GD', '769', '35', '3', '2012-08-05 17:32:13', '2013-12-27 16:07:32');
而后在MyCAT的test_mycat数据库的t_user_class_rel表运行select查看记录执行情况。进入localhost的user0~user3数据库,查看数据是否按照之前确定的rule1的规则和ER分片策略写入不同的数据库。
分片join解决方案心得小结:如果一张表做分片了,其他有一张表要跟这张表做关联,方案如下:
1、全局表(适合做的才做):非跨分片join
2、另一张表也搞分片:非跨分片join
3、share join(只能2个表join):跨分片join
4、另一张表里join用到的字段冗余到 已经做了分片的那张表上去:不用join (该方案可用性不错)
5、另一张表里join用到的字段 搞成一张全局表:非跨分片join
三、读写分离
MyCAT的读写分离机制如下:
- 事务内的SQL,全部走写节点,除非某个select语句以注释/*balance*/开头
- 自动提交的select语句会走读节点,并在所有可用读节点中间随机负载均衡
- 当某个主节点宕机,则其全部读节点都不再被使用,因为此时,同步失败,数据已经不是最新的,MyCAT会采用另外一个主节点所对应的全部读节点来实现select负载均衡。
- 当所有主节点都失败,则为了系统高可用性,自动提交的所有select语句仍将提交到全部存活的读节点上执行,此时系统的很多页面还是能出来数据,只是用户修改或提交会失败。
231和233主从配置,233配置成读库。
writeType="0" dbType="mysql" dbDriver="native">
select user()