Mysql 主从复制读写分离
主从复制
根据需要搭建一主两从的 mysql 集群配置,首先我们需要三台虚拟机并且都安装mysql
查看机器中是否有mysql服务
[root@centos ~]# systemctl status mysqld
修改mysql的配置文件
[root@localhost mysql]# vim /etc/my.cnf
分别在配置文件中加入如下配置
//注意保证每个mysql服务器的server-id的值不同
server-id=1
log-bin=mysql-bin
log-slave-updates
slave-skip-errors=all
#重启mysql服务
systemctl restart mysqld
#登录到mysql
mysql -u root -p
#登录mysql执行如下命令检测配置是否生效
SHOW VARIABLES like 'server_id';
#退出mysql,删除每个节点的文件
rm -rf /var/lib/mysql/auto.cnf
#删除完毕后再次重新启动mysql
systemctl restart mysqld
#登录master节点执行如下命令,查看file值和position值,与下面的master_log_file和master_log_pos属性对应
show master status;
#登录从节点执行如下命令:
change master to
master_host='10.15.0.9',
master_user='root',
master_password='root',
master_log_file='mysql-bin.000001',
master_log_pos=120;
#开启从节点
start slave;
#查看从节点状态
************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.15.0.9
Master_User: root
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 120
Relay_Log_File: mysqld-relay-bin.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000001
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
注意:
1.出现 Slave_IO_Running: Yes 和 Slave_SQL_Running: Yes 说名成功,
2.如果在搭建过程出现错误,可以查看查看错误日志文件 cat /var/log/mysqld.log
#通过客户端工具进行测试(主节点表中数据改变从节点也跟着改变)
#关闭主从复制(在从节点执行)
stop slave;
注意:如果出现Slave I/O: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work. Error_code: 1593错误,请执行如下命令,rm -rf /var/lib/mysql/auto.cnf删除这个文件,之所以出现会出现这样的问题,是因为我的从库主机是克隆的主库所在的主机,所以auto.cnf文件中保存的UUID会出现重复.
读写分离
通过加入一个中间件 Mycat 对client的请求进行区分,读请求给从机并进行负载均衡,写请求给主机。由于无法将mysql的链接写死在项目的配置文件中,所以Mycat需要分别知道 主机的链接ip 和 从机的链接ip,项目链接的 ip 只要链接 Mycat 所在的机器即可。
Mycat 还可以完成分库分表:当mysql中一个表的字段非常多,而我们业务所需的查询只要几个字段时,查询效率会非常低,分库分表可以将非常多的字段进行分表,几个字段作为一个表,最后将查询结果进行汇总。
Mycat 中将 mysql 中的数据库进行逻辑库映射。(项目链接此逻辑库即可)
安装Mycat
# 1.下载mycat(直接浏览器复制下载)
http://dl.mycat.io/1.6-RELEASE/Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz
# 2.解压mycat
tar -zxvf Mycat-server-1.6-RELEASE-20161028204710-linux.tar.gz -C /usr/soft/
配置主机和从机列表
[root@centos mycat]# vim conf/schema.xml
# 配置mycat中conf下的配置schema.xml(删除其中的内容,只留下 Mycat 标签)
<mycat:schema xmlns:mycat="http://io.mycat/">
</mycat:schema>
<!-- 定义MyCat的逻辑库 -->
<schema name="mycatuser" checkSQLschema="false" sqlMaxLimit="100" dataNode="testNode"></schema>
<!-- 定义MyCat的数据节点 database 真实mysql的数据库 -->
<dataNode name="testNode" dataHost="dtHost" database="upload" />
<dataHost name="dtHost" maxCon="1000" minCon="10" balance="1"
writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<!--mycat和每一个节点建立心跳,保证节点的正常运行-->
<heartbeat>select user()</heartbeat>
<!--写节点-->
<writeHost host="hostM1" url="10.15.0.111:3306" user="root" password="root">
<!--从节点-->
<readHost host="hostS1" url="10.15.0.112:3306" user="root" password="root" />
</writeHost>
</dataHost>
配置Mycat的用户名和密码
#配置登陆mycat的权限server.xml(删除其中的内容,只留下 Mycat 标签)
[root@centos mycat]# vim conf/server.xml
<system>
<!-- 这里配置的都是一些系统属性,可以自己查看mycat文-->
<property name="defaultSqlParser">druidparser</property>
<property name="charset">utf8</property>
</system>
<user name="root">
<property name="password">root</property>
<property name="schemas">mycatuser</property>
</user>
Mycat启动
Mycat 默认启动时间5秒,需要修改
[root@centos mycat]# vim conf/wrapper.conf
wrapper.startup.timeout=7200 //随便找个位置加入即可,改为2小时
启动 Mycat (见到 successfully 即为启动成功)
[root@centos mycat]# ./bin/mycat console
项目链接Mycat
更改项目中的配置文件
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
#此处链接的mycat,库民称为逻辑库
url: jdbc:mysql://10.15.0.111:8066/mycatuser?useUnicode=true&characterEncoding=UTF8&serverTimezone=UTC&useSSL=false
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
测试Mycat的读写分离是否生效
//测试从数据库中查询主机和从机数据不一致的数据,看返回的是主机里的数据还是从机里的数据
@Test
public void testSaveUser() {
User user = new User("温晓琪",true,"1",new Date(),"1","1");
userService.saveUser(user);
}
@Test
public void testUserNameAndPassword() {
User user = new User();
user.setName("赵小六1");
user.setPassword("1");
User user1 = userService.queryUserByNameAndPassword(user);
System.out.println(user1);
}
Mycat进行读写分离使用的是sql和事务,如果service层方法上如果去掉@Transactional注解,读写分离将会失效。
测试前要保证Mycat正常启动
用户还可以自定义springboot程序实现mysql的读写分离,详情请参考:
https://blog.csdn.net/weixin_38231448/article/details/104932764