面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时间有大量并发读操作和较少写操作类型的应用系统来说,将单一的数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。 通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理能力。 使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。
虽然读写分离可以提升系统的吞吐量和可用性,但同时也带来了数据不一致的问题,这包括多个主库之间的数据一致性,以及主库与从库之间的数据一致性的问题。并且,读写分离也带来了与数据分片同样的问题,它同样会使得应用开发和运维人员对数据库的操作和运维变得更加复杂。透明化读写分离所带来的影响,让使用方尽量像使用一个数据库一样使用主从数据库,是读写分离中间件的主要功能。
在上一篇文章介绍到Mysql数据库的分库分表,本文将介绍读写分离
192.168.0.3 192.168.0.4 复制代码
这里不做过多介绍了 我这里安装的Mysql 8.0
MySQL 主从复制的方式有多种,本文主要演示基于基于日志(binlog)的主从复制方式。
主从配置需要注意的点
主从服务器操作系统版本和位数一致; Master 和 Slave 数据库的版本要一致; Master 和 Slave 数据库中的数据要一致; Master 开启二进制日志, Master 和 Slave 的 server_id 在局域网内必须唯一; 复制代码
Master 上的配置
1.安装数据库; 2.修改数据库配置文件, 指明 server_id, 3.开启二进制日志(log-bin); 4.启动数据库, 查看当前是哪个日志, position 号是多少; 5.登录数据库, 授权数据复制用户(IP 地址为从机 IP 地址, 如果是双向主从, 6.这里的还需要授权本机的 IP 地址, 此时自己的 IP 地址就是从 IP 地址); 7.备份数据库(记得加锁和解锁); 8.传送备份数据到 Slave 上; 9.启动数据库; 复制代码
以下步骤, 为单向主从搭建成功, 想搭建双向主从需要的步骤:
登录数据库, 指定 Master 的地址、 用户、 密码等信息(此步仅双向主从时需要) 开启同步 查看状态 复制代码
1.1、版本一致 1.2、初始化表,并在后台启动mysql 1.3、修改root的密码 复制代码
#vim /etc/my.cnf [mysqld] log-bin=mysql-bin //[必须]启用二进制日志 server-id=222 //[必须]服务器唯一ID,默认是1,一般取IP最后一段/自定义都可以的 复制代码
mysql> mysql -u root -p mysql> show master status; 复制代码
可以看到这些信息,说明前面我们配置成功
#vi /etc/my.cnf [mysqld] log-bin=mysql-bin //[不是必须]启用二进制日志 server-id=226 //[必须]服务器唯一ID,默认是1,一般取IP最后一段/自定义都可以的 复制代码
mysql> mysql -u root -p mysql> show master status; 复制代码
可以看到这些信息,说明前面我们配置成功
systemctl restart mysqld.service 复制代码
change master to master_host='192.168.0.4',master_user='test',master_password='12root',master_log_file='mysql-bin.000001',master_log_pos=155; 复制代码
一般不用root帐号,"%" 表示所有客户端都可能连,只要帐号,密码正确,此处可用具体客户端IP代替,如192.168.0.4(主服务器的IP),加强安全 8. 开启主从同步
mysql> start slave; #停止主从同步命令为:stop slave 复制代码
mysql> show slave status/G; 复制代码
注:Slave_IO及Slave_SQL进程必须正常运行,即YES状态,否则都是错误的状态(如:其中一个NO均属错误)
说明们的主从同步配置成功
注意:如果如果从库宕机,重新启动,要连接上mysql服务,执行 start slave 这个命令,开启主从同步
分别查询两台服务器的数据库
在主数据库创建test表
mysql> create database test; 复制代码
查询从数据库
我们刚刚在主数据库创建的test库在从数据库有的 说明我们的主从是成功的
注: 编写一shell脚本,用nagios监控slave的两个yes(Slave_IO及Slave_SQL进程),如发现只有一个或零个yes,就表明主从有问题了,发短信警报吧
SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) DEFAULT NULL, `name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; SET FOREIGN_KEY_CHECKS = 1; 复制代码
从数据库会自动同步
application.properties 配置
# 配置真实数据源 sharding.jdbc.datasource.names=master1,slave0 # 主数据库 sharding.jdbc.datasource.master1.type=com.zaxxer.hikari.HikariDataSource sharding.jdbc.datasource.master1.hikari.driver-class-name=com.mysql.cj.jdbc.Driver sharding.jdbc.datasource.master1.jdbc-url=jdbc:mysql://192.168.0.3:3306/ds0?characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai sharding.jdbc.datasource.master1.username=test sharding.jdbc.datasource.master1.password=12root # 从数据库 sharding.jdbc.datasource.slave0.type=com.zaxxer.hikari.HikariDataSource sharding.jdbc.datasource.slave0.hikari.driver-class-name=com.mysql.cj.jdbc.Driver sharding.jdbc.datasource.slave0.jdbc-url=jdbc:mysql://192.168.0.3:3306/ds0?characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai sharding.jdbc.datasource.slave0.username=test sharding.jdbc.datasource.slave0.password=12root # 配置读写分离 # 配置从库选择策略,提供轮询与随机,这里选择用轮询 sharding.jdbc.config.masterslave.load-balance-algorithm-type=round_robin sharding.jdbc.config.masterslave.name=ms sharding.jdbc.config.masterslave.master-data-source-name=master1 sharding.jdbc.config.masterslave.slave-data-source-names=slave0 # 开启SQL显示,默认值: false,注意:仅配置读写分离时不会打印日志 sharding.jdbc.config.props.sql.show=true spring.main.allow-bean-definition-overriding=true 复制代码
主要改动application.properties配置 其他地方不做改动
控制台打印:可以查询看到走的从数据库可以看到插入数据走的主数据库