Mycat分库分表
什么是分库分表
- 将存放在一个数据库(主机)中的数据,按照特定方式进行拆分,分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果
垂直分割
纵向切分
- 将单个表,拆分成多个表,分散到不同的数据库
- 将单个数据库的多个表进行分类,按业务类别分散到不同的数据库上
水平分割
- 横向切分
- 按照表中的某个字段的某种规则,把表中的许多记录进行切分,分散到多个数据库中
mycat介绍
软件介绍
- mycat是基于java的分布式数据库系统中间层,为高并发环境的分布式访问提供解决方案
- 支持JDBC形式的连接
- 支持MySQL、Oracle、Sqlserver、Mongodb等
- 提供数据读写分离服务
- 可以实现数据库服务器的高可用
- 提供数据分片服务
- 基于阿里巴巴Cobar进行研发的开源软件
- 适合数据大量写入数据的存储需求
分片规则
mycat支持提供10种分片规则
- 枚举法、sharding-by-intfile
- 固定分片、rule1
- 范围约定、auto-sharding-long
- 求模法、mod-long
- 日期列分区法、sharding-by-date
- 通配取模、sharding-by-pattern
- ASCII求模通配、sharding-by-prefixpattern
- 编程指定、sharding-by-substring
- 字符串拆分hash解析、sharding-by-stringhash
- 一致性hash、sharding-by-murmur
工作过程
当mycat收到一个SQL查询时
- 先解析这个SQL查找涉及到的表
- 然后看此表的定义,如果有分片规则,则获取SQL里分片字段的值,并匹配分片函数,获得分片列表
- 然后将SQL发往这些分片去执行
- 最后收集和处理所有分片结果数据,并返回到客户端
修改配置文件
目录结构说明
- bin //mycat命令、如 启动 停止 等
- catlet //扩展功能
- conf //配置文件
- lib //mycat使用的jar
- log //mycat启动日志和运行日志
- wrapper.log //mycat服务启动日志
- mycat.log //记录SQL脚本执行后的报错内容
重要的配置文件说明
- server.xml //设置连mycat的帐号信息
- schema.xml //配置mycat的真实库表
- rule.xml //定义mycat分片规则
配置标签说明
<user>... ...</user>
//定义连mycat用户信息<datanode>... ...</datanode>
//指定数据节点<datahost>... ...</datahost>
//指定数据库地址及用户信息
准备四台主机,搭建mycat分片服务器,通过某种特定条件,将存放数据库(主机)中的数据,分散存放到多个数据库(主机)中,已达到分散单台设备负载的效果。其中192.168.4.56作为mycat服务器,192.168.4.54和192.168.4.55作为数据库服务器,192.168.4.254作为客户端。如图所示: 在一个
数据分片的拓扑如图所示:
一:公共配置
(1)关闭防火墙和selinux,配置yum源(系统源),这里不再操作
(2)把54,55还原成独立数据库服务器,且只保留默认4个库其他都删除,停止56主机的mha管理服务,下载mycat 软件到56主机
(3)在54(主机c2)和55(主机c1)上面创建db1和db2库
[root@c1 ~]# mysql -u root -p123456 mysql> create database db1; //c1上面创建db1库 Query OK, 1 row affected (0.00 sec) [root@c2 ~]# mysql -u root -p123456 mysql> create database db2; //c2上面创建db2库 Query OK, 1 row affected (0.00 sec)
在54上面授权一个用户
mysql> grant all on *.* to root@"%" identified by "123456"; Query OK, 0 rows affected, 1 warning (0.00 sec)
在55上面授权一个用户
mysql> grant all on *.* to root@"%" identified by "123456"; Query OK, 0 rows affected, 1 warning (0.00 sec)
(4)修改数据库的配置文件
注意:1代表不区分表名的大小写,0为区分大小写
主机c1上面:
[root@c1 ~]# vim /etc/my.cnf [mysqld] lower_case_table_names=1 //表名忽略大小写 [root@c1 ~]# systemctl restart mysqld
主机c2上面:
[root@c2 ~]# vim /etc/my.cnf [mysqld] lower_case_table_names=1 [root@c2 ~]# systemctl restart mysqld
(5)在56主机上面安装JDK
[root@mycat ~]# rpm -qa | grep -i jdk //安装自带的即可 java-1.8.0-openjdk-1.8.0.131-11.b12.el7.x86_64 java-1.8.0-openjdk-headless-1.8.0.131-11.b12.el7.x86_64 copy-jdk-configs-2.2-3.el7.noarch [root@mycat ~]# yum -y install java-1.8.0-openjdk
(6)在56主机上面安装mycat
[root@mycat ~]# cd mysql/ [root@mycat mysql]# tar -xf Mycat-server-1.4-beta-20150604171601-linux.tar.gz //免安装,解压即可使用 [root@mycat mysql]# mv mycat/ /usr/local/ [root@mycat mysql]# ls /usr/local/mycat/ bin catlet conf lib logs version.txt [root@mycat mysql]# cd /usr/local/mycat/ [root@mycat mycat]# ./bin/mycat --help Usage: ./bin/mycat { console | start | stop | restart | status | dump }
(7)修改配置文件
查看server.xml配置文件
[root@mycat mycat]# cd conf/ [root@mycat conf]# vim server.xml </system> <user name="root"> //连接mycat服务时使用的用户名 test <property name="password">123456</property> //使用test用户连接mycat用户时使用的密码 <property name="schemas">TESTDB</property> //连接上mycat服务后,可以看到的库名多个时,使用逗号分隔 (是逻辑上的库名,服务器上没有这个库名,随便取,但要记住) </user> <user name="user"> <property name="password">user</property> <property name="schemas">TESTDB</property> <property name="readOnly">true</property> //定义只读权限,使用定义的user用户连接mycat服务后只有读记录的权限,不写这一行则是可读可写 </user> 修改schema.xml配置文件 [root@mycat conf]# vim schema.xml <table name="travelrecord" dataNode="dn1,dn2" rule="auto-sharding-long" /> //travelrecord(逻辑上的,名字不能随便写,一般不动)表分片到数据节点dn1和dn2,dn1和dn2随便取的名字 <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> <table name="hotnews" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="mod-long" /> <dataNode name="dn1" dataHost="c1" database="db1" /> //数据节点对应的服务器 name="dn1"名称要与上面的对应 dataHost="c1"写本机主机名,database="db1"存在的数据库名,定义分片使用的库,所在的物理主机,真正存储数据的db1库在物理主机mysql55上 <dataNode name="dn2" dataHost="c2" database="db2" /> //定义分片使用的库,所在的物理主机,真正存储数据的db1库在物理主机mysql55上 指定c1名称主机对应的ip地址 <dataHost name="c1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="c1" url="192.168.4.55:3306" user="root" password="123456"> //访问数据库时,mycat服务连接数据库服务器时使用的用户名和密码 3ff7 <!-- can have multi read hosts --> </writeHost> </dataHost> 指定c2名称主机对应的ip地址 <dataHost name="c2" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <!-- can have multi write hosts --> <writeHost host="c2" url="192.168.4.54:3306" user="root" password="123456"> //访问数据库时,mycat服务连接数据库服务器时使用的用户名和密码 <!-- can have multi read hosts --> </writeHost> </dataHost>
(8)添加PATH路径
[root@mycat conf]# export PATH=/usr/local/mycat/bin:$PATH [root@mycat conf]# echo "PATH=/usr/local/mycat/bin:$PATH" >> /etc/profile [root@mycat conf]# source /etc/profile [root@mycat conf]# echo $PATH /usr/local/mycat/bin:/usr/local/mycat/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@mycat conf]# which mycat /usr/local/mycat/bin/mycat
(9)启动服务并查看端口
[root@mycat conf]# mycat start Starting Mycat-server... [root@mycat conf]# netstat -antup | grep :8066 tcp6 0 0 :::8066 :::* LISTEN 6421/java [root@mycat conf]# ps -C java PID TTY TIME CMD 6421 ? 00:00:04 java 用root用户登录 [root@client ~]# mysql -h192.168.4.54 -uroot -p123456 mysql> show processlist; +----+-------+--------------------+------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------+--------------------+------+---------+------+----------+------------------+ | 3 | root | 192.168.4.56:34580 | db2 | Sleep | 80 | | NULL | | 4 | root | 192.168.4.56:34570 | db2 | Sleep | 100 | | NULL | | 5 | root | 192.168.4.56:34572 | db2 | Sleep | 40 | | NULL | | 6 | root | 192.168.4.56:34562 | db2 | Sleep | 30 | | NULL | | 7 | root | 192.168.4.56:34564 | db2 | Sleep | 90 | | NULL | | 8 | root | 192.168.4.56:34566 | db2 | Sleep | 60 | | NULL | | 9 | root | 192.168.4.56:34574 | db2 | Sleep | 70 | | NULL | | 10 | root | 192.168.4.56:34576 | db2 | Sleep | 10 | | NULL | | 11 | root | 192.168.4.56:34578 | db2 | Sleep | 20 | | NULL | | 12 | root | 192.168.4.56:34568 | db2 | Sleep | 50 | | NULL | | 14 | root | 192.168.4.51:58354 | NULL | Query | 0 | starting | show processlist | +----+-------+--------------------+------+---------+------+----------+------------------+ 11 rows in set (0.00 sec) [root@client ~]# mysql -h192.168.4.55 -uroot -p123456 mysql> show processlist; +----+-------+--------------------+------+---------+------+----------+------------------+ | Id | User | Host | db | Command | Time | State | Info | +----+-------+--------------------+------+---------+------+----------+------------------+ | 3 | root | localhost | NULL | Sleep | 2352 | | NULL | | 4 | root | 192.168.4.56:45148 | db1 | Sleep | 2 | | NULL | | 5 | root | 192.168.4.56:45150 | db1 | Sleep | 62 | | NULL | | 6 | root | 192.168.4.56:45160 | db1 | Sleep | 12 | | NULL | | 7 | root | 192.168.4.56:45162 | db1 | Sleep | 92 | | NULL | | 8 | root | 192.168.4.56:45152 | db1 | Sleep | 32 | | NULL | | 9 | root | 192.168.4.56:45154 | db1 | Sleep | 42 | | NULL | | 10 | root | 192.168.4.56:45156 | db1 | Sleep | 22 | | NULL | | 11 | root | 192.168.4.56:45158 | db1 | Sleep | 82 | | NULL | | 12 | root | 192.168.4.56:45164 | db1 | Sleep | 52 | | NULL | | 13 | root | 192.168.4.56:45166 | db1 | Sleep | 72 | | NULL | | 14 | root | 192.168.4.51:32796 | NULL | Query | 0 | starting | show processlist | +----+-------+--------------------+------+---------+------+----------+------------------+ 12 rows in set (0.00 sec) [root@mycat conf]# ls /usr/local/mycat/logs/ mycat.log mycat.pid wrapper.log //wrapper.log为错误日志 [root@mycat conf]# ldconfig -v //更新加载的模块
(10)客户端访问
命令: mysql -hmycat主机的IP -P端口号 -u用户 -p密码
[root@clent ~]# mysql -h192.168.4.56 -P8066 -uroot -p123456 mysql> show databases; +----------+ | DATABASE | +----------+ | TESTDB | +----------+ 1 row in set (0.00 sec) mysql> USE TESTDB; Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> mysql> show tables; +------------------+ | Tables in TESTDB | +------------------+ | company | | customer | | customer_addr | | employee | | goods | | hotnews | | orders | | order_items | | travelrecord | +------------------+ 9 rows in set (0.00 sec)
客户端测试
枚举法:
(1)修改配置文件
[root@ip56 ~]# vim /usr/local/mycat/conf/partition-hash-int.txt 10000=0 //hash值代表的哪个数据库DB1 10010=1 //hash值代表的哪个数据库DB2 10020=2 //hash值代表的哪个数据库DB3 [root@ip56 ~]# /usr/local/mycat/bin/mycat stop [root@ip56 ~]# /usr/local/mycat/bin/mycat start
(2)创建表
客户端50主机
[root@ip50 ~]# mysql -h192.168.4.56 -P8066 -uroot -p123456 mysql> create table employee( -> ID int primary key auto_increment, -> sharding_id int, -> name char(15), -> age tinyint); //插入数据 mysql> insert into employee(sharding_id,name,age) -> values -> (10000,"bob",21), -> (10010,"lucy",18), -> (10020,"jerry",29), -> (10020,"jack",34);
(3)53,54,55下分别查看employee表下的数据
求模法:
(1)修改配置文件
[root@ip56 ~]# vim /usr/local/mycat/conf/rule.xml <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">3</property> //这里的3代表分片用的主机数 </function> [root@ip56 ~]# vim /usr/local/mycat/conf/schema.xml .. .. <table name="hotnews" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="mod-long" /> .. ..
(2)创建表
mysql> create table hotnews( -> ID int primary key auto_increment, -> id int, -> title char(50), -> comment char(50), -> worker char(30)); //50客户端登录插入数据 mysql> insert into hotnews(num,title,comment,worker) values(0,"000","fhuewf","fnoighnioq"); mysql> insert into hotnews(num,title,comment,worker) values(1,"000","fhuewf","fnoighnioq"); mysql> insert into hotnews(num,title,comment,worker) values(2,"000","fhuewf","fnoighnioq");
(3)53,54,55上分别查看表数据
数据存储不切片,type=global
(1)创建表
mysql> create table company( -> ID int primary key auto_increment, -> name char(50), -> num int); (2)插入数据 mysql> insert into company(name,num) values -> ("baidu",12), -> ("tengxun",13), -> ("alibaba",2), -> ("google",5); (3)在52,53,54主机上查看数据
添加新库新表
(1)修改配置文件
[root@ip56 ~]# vim /usr/local/mycat/conf/server.xml ... ... <user name="root"> <property name="password">123456</property> <property name="schemas">TESTDB,BBSDB</property> //添加新库,逗号隔开 ... ... [root@ip56 ~]# vim /usr/local/mycat/conf/schema.xml ... ... <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="BBSDB" checkSQLschema="false" sqlMaxLimit="100"> <table name="user" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" /> <table name="pay" primaryKey="ID" dataNode="dn1,dn2,dn3" rule="mod-long" /> <table name="gz" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> </schema> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> ... ...
(2)重启服务
[root@ip56 ~]# /usr/local/mycat/bin/mycat stop [root@ip56 ~]# /usr/local/mycat/bin/mycat start [root@ip56 ~]# ss -ntulp | grep 8066
(3)客户端50重新等入数据库查看新添加的库跟表
[root@ip50 ~]# mysql -h192.168.4.56 -P8066 -uroot -p123456 mysql> show databases; mysql> use BBSDB; mysql> show tables; //创建表 mysql> create table pay( -> ID int primary key auto_increment, -> num int, -> name char(15), -> money float(7,2)); //插入数据 mysql> insert into pay(num,name,money) values -> (12,"bob",200), -> (7,"harry",500), -> (8,"kenji",666);
(4)52,53,54主机分别查看数据
mysql> select * from pay;
- ARM异常向量表顺序的定义
- linux的centos版本下安装WordPress
- bzoj3994 SDOI2015 约数个数和
- Python基本语法元素 - 温度转换 II
- Eureka服务注册中心
- 【转】C++类中的static数据成员,static成员函数
- 部分实用C/C++语法总结_190519
- iot rootkit 学习 lesson 5(上) 内核模块的基础知识:带有文件、函数和行信息的消息
- GOF23 工厂模式
- 利用函数递归实现简单的轮播图效果
- 转载:使用nat123通过自己的电脑搭建一个网站
- C# 将文件存入数据库 EF 版
- 青蛙跳台阶二
- 正则表达式贪婪非贪婪是啥玩意等!
- vs2015重新安装
- Python基本语法元素 - 数字形式转换 I
- 什么是设计模式
- Eclipse的基本操作以及配置
- 安装网站源码时提示:【写入配置失败,请检查***目录是否可写入!】 (已解决)
- Win7简易模拟Win10的开始页面