目的
通过实现数据库的分表, 读写分离来解决数据库性能瓶颈
数据库中间件的实现流程
- 解析sql
- 数据源管理
- 数据源分配
- 请求/响应
- 结果整合
Mycat中的概念
- 逻辑库(schema)
在云计算时代,数据库中间件可以以多租户的形式给一个或多个应用提供服务,每个应用访问的可能是一个独立或者是共享的物理库,常见的如阿里云数据库服务器 RDS。 - 逻辑表(table)
分布式数据库中,对应用来说,读写数据的表就是逻辑表。逻辑表,可以是数据切分后,分布在一个或多个分片库中,也可以不做数据切分,不分片,只有一个表构成。
- 分片表
分片表,是指那些原有的很大数据的表,需要切分到多个数据库的表,这样,每个分片都有一部分数据,所 有分片构成了完整的数据。 - 非分片表
一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。数据只存储在一个节点上 - ER表
子表的记录与所关联的父表记录存放在同一个数据分片上,即子表依赖于父表,通过表分组(Table Group)保证数据 Join 不会跨库操作。比如用户表与用户地址表 - 全局表
Mycat 中通过数据冗余来解决这类表的 join,即所有的分片都有一份数据的拷贝,所有将字典表或者符合字典表特性的一些表定义为全局表。比如数据字典表
demo
需求
将用户表按照id%2的规则存储到两个分片节点中
环境准备
- mysql
- 检查系统是否自带mysql数据库安装包无需下载
rpm -qa | grep mysql
- 安装mysql
yum install mysql-server
// 设置root用户
service mysqld stop
mysqld_safe --user=mysql --skip-grant-tables --skip-networking &
// 新窗口执行
mysql -u root mysql
// 输入新密码
// 设置新密码
UPDATE user SET Password=PASSWORD('newpassword') where USER='root';
FLUSH PRIVILEGES;
quit
// 设置远程访问
service mysqld restart
mysql -uroot -p
use mysql;
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
FLUSH PRIVILEGES;
service mysqld restart
- 防火墙问题
centos6防火墙设置
- jdk
// 安装在/usr/lib/jvm目录下
yum install -y java-1.8.0-openjdk-devel.x86_64
安装mycat
- 安装包地址
mycat官网下载 - 解压, 建议放在/usr/local/Mycat目录下
- 在 Linux 系统的环境变量中配置 MYCAT_HOME
vi /etc/profile
// 新增MYCAT_HOME
MYCAT_HOME=/usr/local/Mycat-server-1.6.7.5-release-20200422133810-linux/mycat
// 刷新
source /etc/profile
配置db_user
- 单库初始化
// 创建db_user库在节点1和2
CREATE DATABASE db_user DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
// 创建users表
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users` (
`userID` int(11) NOT NULL COMMENT '用户ID',
`username` varchar(16) COLLATE utf8_bin DEFAULT NULL COMMENT '用户名',
`phoneNum` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '手机号码',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`ddID` int(11) DEFAULT NULL COMMENT '所属会员类型',
`createTime` datetime DEFAULT NULL COMMENT '注册时间',
`lastUpdate` datetime DEFAULT NULL COMMENT '最后更新时间',
PRIMARY KEY (`userID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
- 修改mycat配置
- schema.xml 是逻辑库定义和表以及分片定义的配置文件
<schema name="db_user" checkSQLschema="true" sqlMaxLimit="100">
<table name="users" primaryKey="userID" dataNode="db_user_dataNode1,db_user_dataNode2" rule="mod-userID-long">
</table>
</schema>
<dataNode name="db_user_dataNode1" dataHost="db_userHOST1" database="db_user" />
<dataNode name="db_user_dataNode2" dataHost="db_userHOST2" database="db_user" />
<dataHost name="db_userHOST1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="userHost1" url="jdbc:mysql://192.168.110.128:3306" user="root"
password="12345678">
</writeHost>
</dataHost>
<dataHost name="db_userHOST2" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="jdbc" switchType="1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="userHost2" url="jdbc:mysql://192.168.110.129:3306" user="root"
password="12345678"></writeHost>
</dataHost>
- rule.xml 是分片规则的配置文件
// 新增
<tableRule name="mod-userID-long">
<rule>
<columns>userID</columns>
<algorithm>mod-long</algorithm>
</rule>
</tableRule>
// 修改
<function name="mod-long"
class="io.mycat.route.function.PartitionByMod">
<property name="count">2</property>
</function>
- server.xml 是 Mycat 服务器参数调整和用户授权的配置文件
<user name="root" defaultAccount="true">
<property name="password">123456</property>
<property name="schemas">db_user</property>
<property name="defaultSchema">db_user</property>
</user>
- 启动mycat
// bin目录下执行
./mycat start
- 配置文件修改,需要重启 Mycat 或者通过 9066 端口 reload
- 服务启动问题可以通过/logs/wrapper.log日志排查
- 正常启动成功后才会有mycat.log日志, 配置在config目录下的log4j2.xml
test
- 在逻辑库执行脚本
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('1', '张1', '13611111111', '31', '2', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('2', '王二', '13622222222', '32', '5', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('3', '李三', '13633333333', '33', '3', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('4', '赵四', '13644444444', '34', '1', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
INSERT INTO `users`(userID,userName,phoneNum,age,ddID,createTime,lastUpdate) VALUES ('5', '田五', '13655555555', '35', '3', '2018-10-10 13:39:41', '2018-10-10 13:39:41');
- 观察各节点的数据
- 节点1
- 节点2