使用Sharding-JDBC 实现Mysql读写分离

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 使用Sharding-JDBC 实现Mysql读写分离

为什么要读写分离?


读写分离则是将事务性的增、改、删操作在主库执行,查询操作在从库执行。


一般业务的写操作都是比较耗时,为了避免写操作影响查询的效率,可以使用读写分离。


当然读写分离并不是万能的,还有分库分表


读写分离如何搭建?


MySQL搭建读写分离非常简单,一般有一主一从、一主多从。以MySQL5.7为例,使用docker搭建一个一主一从的架构,步骤如下:


1. pull镜像


使用如下命令从镜像仓库中下载镜像:

docker pull mysql:5.7.26


2. 创建目录


MySQL数据和配置文件挂载的目录:

mkdir -p /usr/local/mysqlData/master/cnf
mkdir -p /usr/local/mysqlData/master/data
mkdir -p /usr/local/mysqlData/slave/cnf 
mkdir -p /usr/local/mysqlData/slave/data


3. 编写配置master节点配置


修改MySQL主节点的配置文件,内容如下:

vim /usr/local/mysqlData/master/cnf/mysql.cnf
[mysqld]
## 设置server_id,注意要唯一
server-id=1
## 开启binlog
log-bin=mysql-bin
## binlog缓存
binlog_cache_size=1M
## binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed


4. 编写配置slave节点配置


修改MySQL从节点的配置文件,内容如下:

vim /usr/local/mysqlData/slave/cnf/mysql.cnf
[mysqld]
## 设置server_id,注意要唯一
server-id=2
## 开启binlog,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
## 如果需要同步函数或者存储过程
log_bin_trust_function_creators=true
## binlog缓存
binlog_cache_size=1M
## binlog格式(mixed、statement、row,默认格式是statement)
binlog_format=mixed
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062


5. 启动MySQL主节点


docker run -itd -p 3306:3306 --name master -v /usr/local/mysqlData/master/cnf:/etc/mysql/conf.d -v /usr/local/mysqlData/master/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.26


6. 添加复制master数据的用户reader,供从服务器使用


[root@aliyun /]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
6af1df686fff        mysql:5.7           "docker-entrypoint..."   5 seconds ago       Up 4 seconds        0.0.0.0:3306->3306/tcp, 33060/tcp   master
[root@aliyun /]# docker exec -it master /bin/bash
root@41d795785db1:/# mysql -u root -p123456
mysql> GRANT REPLICATION SLAVE ON *.* to 'reader'@'%' identified by 'reader';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)


7. 创建并运行mysql从服务器


docker run -itd -p 3307:3306 --name slaver -v /usr/local/mysqlData/slave/cnf:/etc/mysql/conf.d -v /usr/local/mysqlData/slave/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7.26


8. 在从服务器上配置连接主服务器的信息


首先主服务器上查看master_log_file、master_log_pos两个参数,然后切换到从服务器上进行主服务器的连接信息的设置。


主服务上执行:

root@6af1df686fff:/# mysql -u root -p123456
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000003 |      591 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


docker查看主服务器容器的ip地址:

[root@aliyun /]# docker inspect --format='{{.NetworkSettings.IPAddress}}' master
172.17.0.2

从服务器上执行:

[root@aliyun /]# docker exec -it slaver /bin/bash
root@fe8b6fc2f1ca:/# mysql -u root -p123456  
mysql> change master to master_host='172.17.0.2',master_user='reader',master_password='reader',master_log_file='mysql-bin.000003',master_log_pos=591;


9. 从服务器启动I/O 线程和SQL线程


mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.17.0.2
                  Master_User: reader
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000003
          Read_Master_Log_Pos: 591
               Relay_Log_File: edu-mysql-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes


Slave_IO_Running: Yes,Slave_SQL_Running: Yes即表示启动成功。


Sharding-JDBC 实现读写分离


上面使用Docker搭建了一个MySQL的一主一从的架构,如下:

ip:port 节点 数据库
192.168.47.149:3306 主节点 product_db_1
192.168.47.149:3307 从节点 product_db_1


Sharding-JDBC对于读写分离的配置非常简单,分为如下几个步骤:


1. 数据源配置


spring:
  # Sharding-JDBC的配置
  shardingsphere:
    datasource:
      # 数据源,这里配置两个,分别是ds1,ds2
      names: ds1,ds2
      # 主库
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.47.149:3306/product_db1?useUnicode=true&characterEncoding=utf-8
        username: root
        password: 123456
      # 从库
      ds2:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://192.168.47.149:3307/product_db1?useUnicode=true&characterEncoding=utf-8
        username: root
        password: 123456


2. 主从节点配置


第①步仅仅配置了数据源,并未指定哪个是主库,哪个是从库,Sharding-JDBC 默认是不知道哪个主库还是从库的,因此需要自己配置。


配置规则如下:

#主库数据源名称,名称随意
spring.shardingsphere.masterslave.<master-slave-data-source-name>.master-data-source-name= 
#从库数据源名称列表
spring.shardingsphere.masterslave.<master-slave-data-source-name>.slave-data-source-names[0]= 
#从库数据源名称列表
spring.shardingsphere.masterslave.<master-slave-data-source-name>.slave-data-source-names[1]= 
 #从库负载均衡算法类名称。该类需实现MasterSlaveLoadBalanceAlgorithm接口且提供无参数构造器
spring.shardingsphere.masterslave.<master-slave-data-source-name>.load-balance-algorithm-class-name=
#从库负载均衡算法类型,可选值:ROUND_ROBIN,RANDOM。若`load-balance-algorithm-class-name`存在则忽略该配置
spring.shardingsphere.masterslave.<master-slave-data-source-name>.load-balance-algorithm-type=


这里的<master-slave-data-source-name>一定要注意,这个是主从配置的名称(相当于逻辑数据源),名称可以随意,但是一定要唯一。


使用的配置如下:

spring:
  # Sharding-JDBC的配置
  shardingsphere:
    # 主从节点配置
    masterslave:
      # 从库负载均衡算法,内置两个值:RANDOM、ROUND_ROBIN
      load-balance-algorithm-type: round_robin
      # 主从的名称,随意,但是要保证唯一
      name: ms
      # 指定主数据源
      master-data-source-name: ds1
      # 指定从数据源
      slave-data-source-names:
        - ds2


指定的逻辑数据源为ms,主库为ds1,从库为ds2。


load-balance-algorithm-type:指定从库的负载均衡算法


3. 测试


经过上面两步的配置,Sharding-JDBC的读写分离已经配置成功,测试一下


理想效果:


写操作:任何的写操作都应该在主库数据源ds1中执行

读操作:任何的读操作都应该在从库数据源ds2中执行

1、写操作

直接insert插入一条数据,查看Sharding-JDBC的日志,如下

1673448438299.jpg

可以看到都在ds1中执行了


2、读操作

根据商品ID查询一条数据,效果如下:

1673448448397.jpg

可以看到都在ds2中执行了


总结


介绍了MySQL的读写分离架构搭建以及使用Sharding-JDBC去实现程序中无感知使用读写分离。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
27天前
|
负载均衡 监控 关系型数据库
MySQL 官宣:支持读写分离了!!
【10月更文挑战第8天】MySQL的读写分离功能显著提升了数据库性能、可用性和可靠性。通过将读写操作分配至不同服务器,有效减轻单个服务器负载,提高响应速度与吞吐量,并增强系统稳定性。此外,它还支持便捷的扩展方式,可通过增加只读服务器提升读操作性能。实现读写分离的方法包括软件层面(如使用数据库中间件)和硬件层面(使用独立服务器)。使用时需注意数据一致性、负载均衡及监控管理等问题。
|
12天前
|
Java 关系型数据库 MySQL
mysql5.7 jdbc驱动
遵循上述步骤,即可在Java项目中高效地集成MySQL 5.7 JDBC驱动,实现数据库的访问与管理。
21 1
|
23天前
|
SQL 分布式计算 关系型数据库
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-24 Sqoop迁移 MySQL到Hive 与 Hive到MySQL SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
61 0
|
23天前
|
SQL 分布式计算 关系型数据库
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-23 Sqoop 数据MySQL到HDFS(部分) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
29 0
|
23天前
|
SQL 分布式计算 关系型数据库
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
Hadoop-22 Sqoop 数据MySQL到HDFS(全量) SQL生成数据 HDFS集群 Sqoop import jdbc ETL MapReduce
39 0
|
2月前
|
关系型数据库 MySQL Java
MySQL主从复制实现读写分离
MySQL主从复制(二进制日志)、 Sharding-JDBC实现读写分离
MySQL主从复制实现读写分离
|
3月前
|
前端开发 关系型数据库 MySQL
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别
这篇文章讨论了`com.mysql.jdbc.Driver`和`com.mysql.cj.jdbc.Driver`两个MySQL驱动类的区别,指出`com.mysql.jdbc.Driver`适用于MySQL 5的`mysql-connector-java`版本,而`com.mysql.cj.jdbc.Driver`适用于MySQL 6及以上版本的`mysql-connector-java`。文章还提到了在实际使用中如何根据MySQL版本选择合适的驱动类。
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别
|
3月前
|
关系型数据库 MySQL Java
【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
【Azure 应用服务】App Service 无法连接到Azure MySQL服务,报错:com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
165 0
|
3月前
|
SQL 关系型数据库 MySQL
mysql读写分离,主从同步
本文介绍了如何在Laravel项目中配置数据库读写分离,并实现MySQL主从同步。主要步骤包括:在`config/database.php`中设置读写分离配置;为主机授予从机访问权限;配置各MySQL服务器的`/etc/my.cnf`文件以确保唯一的`server-id`;以及通过SQL命令设置主从关系并启动从服务。文章还针对一些常见错误提供了排查方法。最后通过验证确认主从同步是否成功。[原文链接](https://juejin.cn/post/6901581801458958344)。版权所有者为作者佤邦帮主,转载请遵循相关规定。
|
3月前
|
cobar 关系型数据库 MySQL
使用MyCat实现MySQL主从读写分离(一)概述
【8月更文挑战第11天】MySQL读写分离通过主从复制分散负载,主库负责写操作,从库承担读查询,以复制技术确保数据一致性。此策略有效缓解锁竞争,提升查询效能并增强系统可用性。实现方式包括应用层处理,简便快捷但灵活性受限;或采用中间件如MyCAT、Vitess等,支持复杂场景但需专业团队维护。
87 0