读写分离主要是为了将对数据库的操作分散到不同的数据库节点上。
一般情况下选择一主多从,一台主数据库负责写,其他的从数据库负责读,主库和从库进行数据同步。
如何实现读写分离
- 部署多台数据库,选择其中的一台作为主数据库,其他的一台或者多台作为从数据库。
- 保证主数据库和从数据库之间的数据是实时同步的,这个过程也就是我们常说的主从复制。
- 系统将写请求交给主数据库处理,读请求交给从数据库处理
主从复制
实现主从复制
实现主从复制要进行的配置:
-
主服务器:
-
开启二进制日志
-
配置唯一的server-id
-
获得master二进制日志文件名及位置
-
创建一个用于slave和master通信的用户账号
-
-
从服务器:
- 配置唯一的server-id
-
- 使用master分配的用户账号读取master二进制日志
- 启用slave服务
主数据库配置
修改mysql配置文件
[mysqld]
log-bin=mysql-bin #开启二进制日志
server-id=1 #设置server-id
重启服务:
- 关闭服务:mysqladmin -u root -p shutdown
- 启动服务:mysqld_safe
注意:master开启二进制日志后默认记录所有库所有表的操作,可以通过配置来指定只记录指定的数据库甚至指定的表的操作,具体在mysql配置文件的[mysqld]可添加修改如下选项:
# 不同步哪些数据库
binlog-ignore-db = mysql
binlog-ignore-db = test
binlog-ignore-db = information_schema
# 只同步哪些数据库,除此之外,其他不同步
binlog-do-db = game
创建用于同步的账号
创建用户并授权:用户:repl 密码:slavepass。123.57.44.85是从库的ip地址。
mysql> CREATE USER 'repl'@'123.57.44.85' IDENTIFIED BY 'slavepass';#创建用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'123.57.44.85';#分配权限
mysql>flush privileges; #刷新权限
获取master二进制日志文件名及位置
记录二进制文件名(mysql-bin.000003)和位置(73)。
mysql > SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000003 | 73 | test | manual,mysql |
+------------------+----------+--------------+------------------+
从数据库配置
修改配置文件
[mysqld]
server-id=2 #设置server-id,必须唯一
重启服务。
配置 Master 同步信息
mysql> CHANGE MASTER TO MASTER_HOST='182.92.172.80',MASTER_USER='repl',MASTER_PASSWORD='slavepass',MASTER_LOG_FILE='mysqlbin.000003',MASTER_LOG_POS=73;
启动同步线程
mysql>start slave;
查看slave状态
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 182.92.172.80
Master_User: rep1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000013
Read_Master_Log_Pos: 11662
Relay_Log_File: mysqld-relay-bin.000022
Relay_Log_Pos: 11765
Relay_Master_Log_File: mysql-bin.000013
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
...
当Slave_IO_Running和Slave_SQL_Running都为YES的时候就表示主从同步设置成功了。接下来就可以进行一些验证了,比如在主master数据库的test数据库的一张表中插入一条数据,在slave的test库的相同数据表中查看是否有新增的数据即可验证主从复制功能是否有效,还可以关闭slave(mysql>stop slave;),然后再修改master,看slave是否也相应修改(停止slave后,master的修改不会同步到slave),就可以完成主从复制功能的验证了。
主从复制原理
- 主库将数据库中数据的变化写入到 binlog
- 从库连接主库
- 从库会创建一个 I/O 线程向主库请求更新的 binlog
- 主库会创建一个 binlog dump 线程来发送 binlog ,从库中的 I/O 线程负责接收
- 从库的 I/O 线程将接收的 binlog 写入到 relay log 中。
- 从库的 SQL 线程读取 relay log 同步数据本地(也就是再执行一遍 SQL )。
使用 ShardingSphere-JDBC 实现读写分离
使用限制:
- 不处理主库和从库的数据同步
- 不处理主库和从库的数据同步延迟导致的数据不一致
- 不支持主库多写
- 不处理主从库间的事务一致性。主从模型中,事务中的数据读写均用主库。
Spring Boot Starter 使用: https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/
参考资料:
- https://www.cnblogs.com/gl-developer/p/6170423.html
- javaguide
- https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/