简述 本文中,首先配置mysql主从复制,然后使用mycat进行读写分离,最后使用mycat来做分库分表。 在数据库访问层 ),仅将mysql连接信息修改为mycat连接信息。
源代码 iarc-data
环境 IDE: IntelliJ IDEA JDK: 1.8.0_u162 Framework: spring boot, dubbo Middleware: mycat DB: MySql WebServer: Tomcat (本地端口8088)
开发 mysql主从复制 采用1主1从的结构
mysql节点信息 1 2 192.168.56.103 master 192.168.56.101 slave
master配置
/etc/my.cnf,添加如下内容
1 2 3 server_id=1 # server_id必须保证主从不一样 log-bin=mysql-bin # mysql二进制日志 binlog-do-db=ijava # 指定只对ijava数据库进行二进制日志
重启mysql(systemctl restart mysql)
登入mysql查看master信息($ mysql> show master status;) 看到如下内容
1 2 3 4 5 +------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +------------------+----------+--------------+------------------+-------------------+ | mysql-bin.000002 | 120 | ijava | | | +------------------+----------+--------------+------------------+-------------------+
创建同步用的mysql用户(也可忽略该步骤,直接使用mysql用户root进行登录)
1 2 $ mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'repl422'; $ mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
slave配置
/etc/my.cnf,添加如下内容
1 2 server_id=2 # server_id必须保证主从不一样 replicate-do-db=ijava # 指定只对ijava数据库进行主从复制
slave中使用不同的uuid(虚拟机复制时uuid是一样的,主从复制会报错1593) mysql中生成新的唯一uuid
然后vim /var/lib/mysql/auto.cnf
重启mysql(systemctl restart mysql)
指定master,启动并查看slave
1 2 3 $ mysql> CHANGE MASTER TO MASTER_HOST='192.168.56.103',MASTER_USER='repl',MASTER_PASSWORD='repl422',MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=120; $ mysql> start slave; $ mysql> show slave status \G;
关键信息如下
1 2 3 4 5 6 7 8 9 10 11 12 13 Slave_IO_State: Waiting for master to send event Master_Host: 192.168.56.103 Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 411 Relay_Log_File: mysqld-relay-bin.000002 Relay_Log_Pos: 574 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: ijava
mycat读写分离 mycat安装配置
前往mycat官网 下载1.6.5-release版本的tar.gz
解压至/opt/mycat并修改环境变量
1 2 export MYCAT_HOME=/opt/mycat export PATH=$MYCAT_HOME/bin:$PATH
配置(/opt/mycat/conf目录中) server.xml
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mycat:server SYSTEM "server.dtd"> <mycat:server xmlns:mycat="http://io.mycat/"> <user name="root" defaultAccount="true"> <property name="password">***</property> <property name="schemas">ijava</property> </user> </mycat:server>
schema.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0"?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> <mycat:schema xmlns:mycat="http://io.mycat/"> <schema name="ijava" checkSQLschema="false" sqlMaxLimit="100"> <table name="user" dataNode="dn1" /> <table name="order" dataNode="dn1" /> </schema> <dataNode name="dn1" dataHost="localhost1" database="ijava" /> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM1" url="192.168.56.103:3306" user="root" password="***"> <readHost host="hostS2" url="192.168.56.101:3306" user="root" password="***" /> </writeHost> </dataHost> </mycat:schema>
启动/停止mycat(mycat start/stop)
使用firewall-cmd开放mycat端口(8066,9066)
配置mysql使其忽略表大小写 /etc/my.cnf中,添加如下配置节并重启mysql
1 lower_case_table_names=1
仅需修改连接字符串
1 spring.datasource.druid.ijava.url=jdbc:mysql://192.168.56.103:8066/ijava***
mycat分库分表 mysql库与表 新建2个库,并在其中新建表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 CREATE SCHEMA isharding1; CREATE TABLE isharding1.user ( id INT NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL ) ENGINE = InnoDB; CREATE TABLE isharding1.inbound ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL ) ENGINE = InnoDB; CREATE SCHEMA isharding2; CREATE TABLE isharding2.user ( id INT NOT NULL PRIMARY KEY, name VARCHAR(50) NOT NULL ) ENGINE = InnoDB; CREATE TABLE isharding2.outbound ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL ) ENGINE = InnoDB;
server.xml 添加isharding schema
1 2 3 4 5 6 7 <mycat:server> ... <user name="root" defaultAccount="true"> <property name="password">***</property> <property name="schemas">ijava,isharding</property> </user> </mycat:server>
schema.xml user表用于展示水平切分,而inbound和outbound则用于垂直切分(不同表放在不同切片)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <mycat:schema xmlns:mycat="http://io.mycat/"> ... <schema name="isharding" checkSQLschema="false" sqlMaxLimit="100"> <table name="user" dataNode="dn01,dn02" rule="mod-long" primaryKey="id" autoIncrement="true"/> <table name="inbound" dataNode="dn01" /> <table name="outbound" dataNode="dn02" /> </schema> ... <dataNode name="dn01" dataHost="isharding" database="isharding1" /> <dataNode name="dn02" dataHost="isharding" database="isharding2" /> ... <dataHost name="isharding" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <heartbeat>select user()</heartbeat> <writeHost host="hostM2" url="192.168.56.103:3306" user="root" password="***"> </writeHost> </dataHost> </mycat:schema>
rule.xml 由于仅有2个切片库,所以规则mod-long的count设置为2
1 2 3 4 <function name="mod-long" class="io.mycat.route.function.PartitionByMod"> <!-- how many data nodes --> <property name="count">2</property> </function>
重启mycat mycat restart
调试 读写分离与主从同步
IntelliJ IDEA中启动数据与服务站点(DataApplication:8002, ServiceApplication:8001)
使用Postman来发起对http://localhost:8001/user/insertUser的请求 requestbody(format: json)
1 {"name": "nothing is true"}
使用DataGrip连接mycat端口8066,验证数据是否正确插入,并连接mysql master/slave来检查数据是否已进行主从同步
分库分表 sql user的数据被拆分到2个不同的库中同名的表中,而inbound/outbound的数据则进入了不同库的不同表
1 2 3 4 USE isharding; INSERT INTO user (id, name) VALUES (1, 'ivan'), (2, 'du'), (3, 'eming'), (4, 'he'); INSERT INTO inbound (name) VALUES ("inbound"); INSERT INTO outbound (name) VALUES ("outbound");
部署 部署到linux下tomcat中 参考数据访问层 中部署部分
参考