当前位置:   article > 正文

MyCat分库分表入门示例_mycat 分库示例

mycat 分库示例

一、简介

  • 分库:将原本一个数据库中的数据,拆分到多个数据库进行保存,然后我们通过访问一个数据库,在MyCat中成为逻辑库。
  • 分表:如果一个数据表的数据量已经超过千万,那么查询速度会比较慢,这时候可以考虑进行分表操作,将一个表的数据保存到多个表中,这样可以控制单表的数据量。

二、作用

分库分表的作用可以通过下表对比可见:

分库分表作用
 分库分表前分库分表后
并发情况MySql单机部署,扛不住高并发需求MySql从单台机器到多台机器,并发访问效率提高不少
磁盘使用情况单机磁盘使用几乎爆满拆分为多个库,每个库的磁盘使用率大大降低
SQL执行性能单个数据表的数据量太大,查询缓慢单个数据表数据量减少,查询效率大大提高

三、如何进行分库分表

  • 水平拆分:就是表一张表的数据给弄到多个库的多个表进行保存,但是每个库里面的表结构都是一样的, 只不过每个库表放的数据不同,所有库表的数据加起来就是全部数据。   意义:就是将数据均匀地拆分到更多的库中,然后用多个库来扛更多的并发,还有就是用多个库的存储容量来进行扩容。
  1. 水平拆分简单示例:
  2. database1: 192.168.1.12 user(id,name,age)
  3. database2: 192.168.1.11 user(id,name,age)
  4. 两个数据库中的数据表结构都一样,只是根据某种规则,比如按id的范围,如果id在某个范围内就将该条数据保存在database1; 如果在另外一个范围内就保存在database2中。
  • 垂直拆分:就是一个表有很多字段,给拆分到多个表中或者是多个库上去。每个库表的数据表结构都不同,每个库表只包含部分字段。一般来说,会将较少的访问频率比较高的表放到同一张表中,然后将较多的访问频率比较低的字段放到另外一张表中。因为数据库是有缓存的,你访问频率高的字段少,在缓存中存放的行越多,查询性能就越好。
  1. 垂直拆分示例:
  2. database1 : 192.168.1.12
  3. basic_student_info(id,xm,sfzjh,zzmm,xh) 这个表主要用于保存学生信息经常出现的字段
  4. expand_student_info(id,dh,mz,syd) 这个表主要用于保存学生信息中不太常见的字段
  5. 将一个数据字段比较多的表拆为两个表进行保存,两边数据库表的结构不一致。

四、分库分表方式

  • a. 按range进行:每个库一段连续的数据,一般按时间范围进行拆分,较少用,会产生热点问题,大量的流量都打在最新的数据上。
  • range拆分的好处在于扩容的时候很简单,只需要预备好,给每个月的数据准备一个数据库,到了一个新的月份,自然就保存到别的库上面去了,缺点就是大量的请求,都是访问最新的数据
  •  
  • b. 按照某个字段hash一下均匀分散,较常见。
  • hash的好处就是平均分配每个库的数据量和请求压力;缺点就是扩容起来比较麻烦,会有一个数据迁移的难点,之前的数据需要重新计算hash然后分发到不同的数据库或表中。

五、示例

下面通过一个简单的示例说明一下MyCat是如何进行分库分表的。环境信息:

  1. centos7.0
  2. 主机: 192.168.1.12192.168.1.13
  3. mycat:1.6
  4. 需要jdk环境变量

这里主要要配置几个文件: schema.xml 、server.xml 、sequence_conf.properties等

【a】编辑server.xml,修改逻辑库的地址(即我们后面配置数据源的时候就只需要连接这个逻辑库即可)

vim server.xml
  1. <user name="root">
  2. <property name="password">123456</property>
  3. <property name="schemas">mycat_order</property>
  4. <!-- 表级 DML 权限设置 -->
  5. <!--
  6. <privileges check="false">
  7. <schema name="TESTDB" dml="0110" >
  8. <table name="tb01" dml="0000"></table>
  9. <table name="tb02" dml="1111"></table>
  10. </schema>
  11. </privileges>
  12. -->
  13. </user>
  14. <user name="user">
  15. <property name="password">123456</property>
  16. <property name="schemas">mycat_order</property>
  17. <property name="readOnly">true</property>
  18. </user>

这里配置了一个逻辑库mycat_order以及加了两个用户root/123456和user/123456. 这里为了测试范围分片规则,所以server.xml中还需要修改本地序列化规则:

注意:需要修改为0,才能使用本地序列化的值。

【b】创建数据库和表:这里需要在两台服务器1.12和1.11上面都执行。

  1. --t_order 、 t_order_detail
  2. CREATE TABLE `t_order` (
  3. `order_id` INT(20) NOT NULL COMMENT '订单ID',
  4. `user_id` INT(11) DEFAULT NULL COMMENT '用户ID',
  5. `pay_mode` TINYINT(4) DEFAULT NULL COMMENT '支付方式',
  6. `amount` FLOAT DEFAULT NULL COMMENT '金额',
  7. `order_date` DATETIME DEFAULT NULL COMMENT '订单时间',
  8. PRIMARY KEY (`order_id`)
  9. ) ENGINE=INNODB DEFAULT CHARSET=utf8
  10. CREATE TABLE `t_order_detail` (
  11. `od_id` INT(20) NOT NULL COMMENT '订单详情ID',
  12. `order_id` INT(20) DEFAULT NULL COMMENT '订单ID',
  13. `goods_id` INT(20) DEFAULT NULL COMMENT '商品ID',
  14. `unit_price` FLOAT DEFAULT NULL COMMENT '单价',
  15. `qty` INT(11) DEFAULT NULL,
  16. PRIMARY KEY (`od_id`)
  17. ) ENGINE=INNODB DEFAULT CHARSET=utf8

登录Mysql:

 mysql -u root -p0905

创建数据库:

  1. create database test_mycat;
  2. show database;

use test_mycat;

分别执行上面的两条创建表语句:

订单表:

订单详情表:

show tables;

因为测试mycat分库分表,所以需要在另外一台服务器上面执行上面的创建表语句。

  1. mysql -uroot -p0905
  2. show databases;
  3. create database test_mycat;
  4. use test_mycat;

show tables;

至此,192.168.2.11 和192.168.2.12两台服务器上的数据库和表都一模一样。

【c】编辑schema.xml:配置数据节点datanode、datahost等信息

vim schema.xml
  1. <schema name="mycat_order" checkSQLschema="false" sqlMaxLimit="100">
  2. <table name="t_order" dataNode="dn1,dn2" rule="mod-long">
  3. <childTable name="t_order_detail" primaryKey="od_id" joinKey="order_id" parentKey="order_id"></childTable>
  4. </table>
  5. </schema>
  6. <dataNode name="dn1" dataHost="host1" database="test_mycat" />
  7. <dataNode name="dn2" dataHost="host2" database="test_mycat" />
  8. <dataHost name="host1" maxCon="1000" minCon="10" balance="0"
  9. writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  10. <heartbeat>select user()</heartbeat>
  11. <!-- can have multi write hosts -->
  12. <writeHost host="host1" url="192.168.1.12:3306" user="root"
  13. password="0905">
  14. </writeHost>
  15. </dataHost>
  16. <dataHost name="host2" maxCon="1000" minCon="10" balance="0"
  17. writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  18. <heartbeat>select user()</heartbeat>
  19. <!-- can have multi write hosts -->
  20. <writeHost host="host2" url="192.168.1.11:3306" user="root"
  21. password="0905">
  22. </writeHost>
  23. </dataHost>

【d】编辑rule.xml: 配置根据主表的主键ID 即order_id进行分库分表

vim rule.xml
  1. <tableRule name="mod-long">
  2. <rule>
  3. <columns>order_id</columns>
  4. <algorithm>mod-long</algorithm>
  5. </rule>
  6. </tableRule>

接着继续修改mod-long规则的数据节点个数,因为这里只用到了两个节点(两个数据库服务器)。

  1. <function name="mod-long" class="io.mycat.route.function.PartitionByMod">
  2. <!-- how many data nodes -->
  3. <property name="count">2</property>
  4. </function>

【e】vim sequence_conf.properties : 配置序列化ID

vim sequence_conf.properties
  1. ORDER.HISIDS=
  2. ORDER.MINID=1001
  3. ORDER.MAXID=2000
  4. ORDER.CURID=1000
  5. ORDERDETAIL.HISIDS=
  6. ORDERDETAIL.MINID=1001
  7. ORDERDETAIL.MAXID=2000
  8. ORDERDETAIL.CURID=1000

【f】启动MyCat:

cd ./bin/

  1. ./mycat start
  2. netstat -ntlp :查看mycat是否启动

【g】测试

  1. mysql -uroot -p123456 -h127.0.0.1 -P8066
  2. show databases;
  3. 可以查看逻辑库的名字:mycat_order

  1. use mycat_order;
  2. show tables;

  1. select * from t_order;
  2. select * from t_order_detial;

ERROR 3009 (HY000): java.lang.IllegalArgumentException: Invalid DataSource:0

如果碰到上面的错误,检查一下schema.xml有没有写错,如果没有错再检查一下mysql防火墙有没有开启,重启一下防火墙。(笔者就是在使用sqlyong连接两台服务器上面的mysql时都不成功,重启完防火墙就好了。)

【h】插入数据测试分库分表

  1. INSERT INTO `t_order`
  2. (`order_id`,
  3. `user_id`,
  4. `pay_mode`,
  5. `amount`)
  6. VALUES (NEXT VALUE FOR MYCATSEQ_ORDER,101,1,111.1);
  7. INSERT INTO `t_order`
  8. (`order_id`,
  9. `user_id`,
  10. `pay_mode`,
  11. `amount`)
  12. VALUES (NEXT VALUE FOR MYCATSEQ_ORDER,102,5,222.2);
  13. INSERT INTO `t_order`
  14. (`order_id`,
  15. `user_id`,
  16. `pay_mode`,
  17. `amount`)
  18. VALUES (NEXT VALUE FOR MYCATSEQ_ORDER,103,7,333.3);
  19. select * from t_order;

【i】vim sequence_conf.properties : 可以看到ORDER.CURID=1003记录了当前序列已经到了1003,说明本地序列配置生效。

vim sequence_conf.properties 

【j】测试订单详情表数据分表情况

插入数据库数据:

  1. INSERT INTO `t_order_detail`
  2. (`od_id`,
  3. `order_id`,
  4. `goods_id`,
  5. `unit_price`,
  6. `qty`)
  7. VALUES (NEXT VALUE FOR MYCATSEQ_ORDERDETAIL,
  8. 1003,
  9. 55,
  10. 10,
  11. 20);
  12. INSERT INTO `t_order_detail`
  13. (`od_id`,
  14. `order_id`,
  15. `goods_id`,
  16. `unit_price`,
  17. `qty`)
  18. VALUES (NEXT VALUE FOR MYCATSEQ_ORDERDETAIL,
  19. 1002,
  20. 66,
  21. 20,
  22. 30);
  23. INSERT INTO `t_order_detail` (
  24. `od_id`,
  25. `order_id`,
  26. `goods_id`,
  27. `unit_price`,
  28. `qty`
  29. )
  30. VALUES
  31. (
  32. NEXT VALUE FOR MYCATSEQ_ORDERDETAIL,
  33. 1001,
  34. 77,
  35. 30,
  36. 40
  37. ) ;

逻辑数据库中的数据分布:

实际物理库中数据分布:

至此,一个比较简单的分库分表示例就完成了,笔者也是周末琢磨了一天才弄出来的,所以做个笔记总结一下,希望能帮到有需要的朋友,后面还会陆续研究其他分片规则。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/407177
推荐阅读
相关标签
  

闽ICP备14008679号