mycat读写分离+垂直切分+水平切分+er分片+全局表 测试

原文http://blog.163.com/[email protected]/blog/static/172718064201683031639683/

读写分离:利用最基础的mysql主从复制,事务性的查询无法分离出去(因为会导致数据不一致),这样就无法做到真正的读写分离,因为有些场景可能大部分都是事物性的读。解决方法: galera for mysql 强一致性。

http://www.blogjava.net/amigoxie/archive/2014/12/24/421788.html

http://blog.csdn.net/benluobobo/article/details/51099607

http://blog.csdn.net/wulex/article/details/52495488

好的实例连接:http://blog.csdn.net/wulex/article/details/52495488

安装使用过程遇到的问题:

1、mycat启动后报错,进程直接退出: Error: Exception thrown by the agent : java.net.MalformedURLException: Local host name unknown: java.net.UnknownHostException: ys-fs: ys-fs: Name or service not known

原因:本机要配置/etc/hosts  127.0.0.1 主机名

一、垂直切分测试:

1、schema.xml里面加入:

<schema name="weixin" checkSQLschema="false" sqlMaxLimit="100" dataNode="weixin" />

<schema name="yixin" checkSQLschema="false" sqlMaxLimit="100" dataNode="yixin" />

<schema name="sms" checkSQLschema="false" sqlMaxLimit="100" dataNode="sms" />

<dataNode name="weixin" dataHost="host0" database="weixin" />

<dataNode name="yixin" dataHost="host1" database="yixin" />

<dataNode name="sms" dataHost="host2" database="sms" />

<dataHost name="host0" maxCon="1000" minCon="10" balance="0"

writeType="0" dbType="mysql" dbDriver="native">

<heartbeat>select user()</heartbeat>

<!-- can have multi write hosts -->

<writeHost host="namenode" url="192.168.168.230:3306" user="root" password="youngsun" />

</dataHost>

<dataHost name="host1" maxCon="1000" minCon="10" balance="0"

writeType="0" dbType="mysql" dbDriver="native">

<heartbeat>select user()</heartbeat>

<!-- can have multi write hosts -->

<writeHost host="hadoop1" url="192.168.168.231:3306" user="root" password="youngsun" />

</dataHost>

<dataHost name="host2" maxCon="1000" minCon="10" balance="0"

writeType="0" dbType="mysql" dbDriver="native">

<heartbeat>select user()</heartbeat>

<!-- can have multi write hosts -->

<writeHost host="hadoop2" url="192.168.168.232:3306" user="root" password="youngsun" />

</dataHost>

2、server.xml加入:

<user name="test_wyh">

<property name="password">test</property>

<property name="schemas">weixin,yixin,sms</property>

</user>

3、遇到问题:

1)、Caused by: org.xml.sax.SAXParseException; lineNumber: 106; columnNumber: 16; The content of element type "mycat:schema" must match "(schema*,dataNode*,dataHost*)".

原因:要按照schema、datanode 、datahost的顺序放,不能打乱。也就是所有schema要放一起,然后接着才能放datanode。。。。

2)、报1184错误,是因为没有 把datahost主机的权限授予mycat所在主机。

<writeHost host="hadoop2" url="192.168.168.232:3306" user="root" password="youngsun" />

这里的 用户要授予mycat所在主机远程访问权限:

GRANT ALL PRIVILEGES ON *.* TO ‘root‘@‘%‘ IDENTIFIED BY ‘youngsun‘

二、水平切分测试:

1、分别建立4个库:user0、user1、user2、user3。我这里4个库建在4个独立的主机上。

CREATE DATABASE  user0 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;

2、创建表结构

在user0~user2创建同样的表结构,t_user和t_user_class_rel的建表语句参考如下:

DROP TABLE IF EXISTS `t_user_ext`;
CREATE TABLE `t_user_ext` (
 `user_id` int(11) NOT NULL COMMENT ‘用户ID‘,
 `receive_address` varchar(256) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT ‘收货地址‘,
 `create_time` datetime NOT NULL,
 `province_code` varchar(10) COLLATE utf8_unicode_ci DEFAULT NULL,
 PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT=‘用户信息表‘;

DROP TABLE IF EXISTS `t_user_class_rel`;
CREATE TABLE `t_user_class_rel` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘id‘,
 `caller` varchar(16) CHARACTER SET utf8 NOT NULL COMMENT ‘调用方系统表示‘,
 `province_code` varchar(10) CHARACTER SET utf8 DEFAULT NULL COMMENT ‘省份编码‘,
 `user_id` int(11) NOT NULL COMMENT ‘用户ID‘,
 `class_id` int(11) NOT NULL COMMENT ‘班级ID‘,
 `role_type` int(11) DEFAULT NULL COMMENT ‘用户在该班的角色(1学生2家长3教师)‘,
 `create_time` datetime NOT NULL COMMENT ‘创建时间‘,
 `modify_time` datetime DEFAULT NULL COMMENT ‘修改时间‘,
 PRIMARY KEY (`id`),
 UNIQUE KEY `idx_rel_user_class_id` (`user_id`,`class_id`,`role_type`),
 KEY `idx_rel_user_id` (`user_id`) USING BTREE,
 KEY `idx_rel_class_id` (`class_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

3、添加schema:加了一点内容:不分表的情况测试(只对部分表进行切分。其实这种时候,没有切分的表,应该是不需要跟已经切分过的表进行关联,否则就会垮库join。既然是这样,那业务就比较独立了,为什么不把这部分表垂直切分出去呢?) 总结心得:1、如果某张表进行水平切分了,那么跟他有事物关联的表,要么搞全局表,要么进行er分片,不然就会导致垮库join。而没有关联关系的表或者非事物关联的表,实际上可以垂直切分出去(如果有必要)。2、dataHost可以理解成一个主机组,可以是单机,可以是主从,可以是galera 等搭建起来的集群。读写分离就是在这里处理的。ha、读写分离等都在这里进行配置,都是针对datahost。

<schema name="test_sharding" checkSQLschema="false" sqlMaxLimit="100">

       <!-- auto sharding by id (long) -->
       <table name="t_user" dataNode="user0,user1,user2,user3" rule="rule_wyh">
           <childTable name="t_user_class_rel" primaryKey="id" joinKey="user_id" parentKey="user_id" />
       </table>

<!-- 此处测试不分表的情况。要先在这里配置,然后可以在mycat创建t_user_1表,也可以在user3对应的local创建表。如果这里没事先配置,无法在mycat建表,会报错。这个还可以通过制定默认datanode实现,更简单,配置方法:在shcema标签上加上datanode -->

<table name="t_user_1" dataNode="user3" >
       </table>
 </schema>

<dataNode name="user0" dataHost="host0" database="user0" />
 <dataNode name="user1" dataHost="host1" database="user1" />
 <dataNode name="user2" dataHost="host2" database="user2" />
 <dataNode name="user3" dataHost="host3" database="user3" />

4、添加datahost:host3

<dataHost name="host3" maxCon="1000" minCon="10" balance="0"

writeType="0" dbType="mysql" dbDriver="native">

<heartbeat>select user()</heartbeat>

<!-- can have multi write hosts -->

<writeHost host="ys-fs" url="192.168.168.238:3306" user="root" password="youngsun" />

</dataHost>

在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配置成读库。

<dataHost name="host1" maxCon="1000" minCon="10" balance="1"

writeType="0" dbType="mysql" dbDriver="native">

<heartbeat>select user()</heartbeat>

<!-- can have multi write hosts -->

<writeHost host="hadoop1" url="192.168.168.231:3306" user="root" password="youngsun" >

<readHost host="hadoop3" url="192.168.168.233:3306" user="root" password="youngsun" weight="1" />

</writeHost>

</dataHost>

时间: 2024-10-07 22:52:55

mycat读写分离+垂直切分+水平切分+er分片+全局表 测试的相关文章

Mycat读写分离和分库分表配置

Mycat是一个开源的分布式数据库系统,不同于oracle和mysql,Mycat并没有存储引擎,但是Mycat实现了mysql协议,前段用户可以把它当做一个Proxy.其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端mysql存储引擎里面.最新版本的Mycat不仅支持mysql,还可以支持MS SqlServer,Oracle,DB2等关系型数据库,而且还支持MongoDB这种NoSQL.Mycat对调用者屏蔽了后端存储具体实现. Mycat的原理是先拦截用户的SQL语句并做分

Mycat读写分离、主从切换学习(转)

http://blog.csdn.net/zhanglei_16/article/details/50707487 Mycat读写分离.主从切换学习问题一:分表.分库的优缺点,以及分表无法成为主流分表方式:是在将一个大表,在一个db库内,分成多个分表,优点是:分开之后的表,仍然在一个库内,便于查看.管理.缺点:db只能在一个服务器内,不能解决I/O问题,负载集中 分库方式:将一个大表,分布在多个DB中,每个DB只保留一部分数据,所有数据组合起来才是全库的数据.优点:优点是分担IO.负载均衡,可以

LVS+MYCAT+读写分离+MYSQL主备同步部署手册

LVS+MYCAT+读写分离+MYSQL主备同步部署手册 1          配置MYSQL主备同步…. 2 1.1       测试环境… 2 1.2       配置主数据库… 2 1.2.1         编辑my.cnf文件… 2 1.2.2         重启数据库… 2 1.3       锁定主数据库DDL操作… 2 1.4       主备已有数据同步… 2 1.5       停止从服务… 3 1.6       配置备用数据库… 3 1.6.1         编辑my

LVS+MYCAT读写分离+MYSQL同步部署手册(第三版)

1      配置MYSQL主备同步 1.1    测试环境 mysql版本:5.6.24: 操作系统内核版本:Linux-3.13-0-32 主数据库IP:192.168.10.3: 主数据库名:db351353: 备用数据库IP:192.168.10.4: 备用数据库名:db351353. 1.2    配置主数据库 1.2.1   编辑my.cnf文件 #服务器唯一ID,一般取IP最后一段 server_id = 3 #启用二进制日志 log_bin=mysql_bin #需要备份的数据库

【转载】LVS+MYCAT+读写分离+MYSQL主备同步部署手册(邢锋)

By leo | 2015/05/13 0 Comment LVS+MYCAT+读写分离+MYSQL主备同步部署手册 1          配置MYSQL主备同步…. 2 1.1       测试环境… 2 1.2       配置主数据库… 2 1.2.1         编辑my.cnf文件… 2 1.2.2         重启数据库… 2 1.3       锁定主数据库DDL操作… 2 1.4       主备已有数据同步… 2 1.5       停止从服务… 3 1.6      

web 项目 连接mycat 读写分离失效问题,

问题描述:mycat 读写分离已配好,在sql工具上查询操作是可以的,但是在项目中,读数据就走write 数据库, 解决      :环境spring +mvc +ibaites,在java中自己写jdbc连接是可以,读写分离,但是就是在业务程序中不能读写分离 之前是想是不是jdbc问题,换了几个jdbc连接池还是不行,最后各种查资料(没用网上根本没有这个), 最后各种方法试最后定位到事务的问题,因为代码命名不规范,方法被纳入到事务管理,因此造成读写数据都走write数据库 结论:    myc

Mycat读写分离部署分享

安装配置mycat 涉及到的安装包: 安装包:Mycat-server-1.6-RELEASE-linux.tar.gz 依赖环境:jdk-7u75-linux-x64.tar.gz 1安装JDK (1)创建java目录 # mkdir -p /usr/local/java (2)上传JDK到/usr/local/java目录下 (3)解压jdk-7u75-linux-x64.tar.gz # cd /usr/local/java # tar -zxvf jdk-7u75-linux-x64.t

mysql主从同步+mycat读写分离+.NET程序连接mycat代理

背景 最近新项目需要用到mysql数据库,并且由于数据量大的原因,故打算采用1主1从(主数据库负责增.删.改操作:从数据库负责查操作)的数据库架构,在实现主从之后还要实现读写分离的代理,在网上搜寻了很久,自己也了解了一些资料,目前有三种代理组件:1.mysql_proxy   2.amoeba   3.mycat   我采用了第3种,选择mycat的原因下面会提到. 部署环境 我在我虚拟机下面装了三台Centos7_x64系统: 1.192.168.8.47 主mysql服务器 2.192.16

Mysql mycat读写分离

Mysql mycat读写分离: 下载网址:http://dl.mycat.ioMycat官方网址:http://mycat.org.cn 说明:10.0.1.2为mycat服务器,10.0.1.3.10.0.1.4为mysql服务器 yum install java-1.8.0-openjdk tar zxfv Mycat-server-1.6.7.5-test-20200109231555-linux.tar.gz -C /space/ 配置读写分离: vi /space/mycat/con