Sharding-JDBC 几行配置实现读写分离~

news/2025/3/17 6:32:41/文章来源:https://www.cnblogs.com/yaoyangding/p/18342494

Sharding-JDBC 几行配置实现读写分离~

 
2022-05-252,435阅读6分钟
 

大家好,我是不才陈某~

今天聊一下如何通过Sharding-JDBC简单的实现读写分离~

为什么要读写分离?

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

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

当然读写分离并不是万能的,还有前面的分库分表方案。

读写分离如何搭建?

MySQL搭建读写分离非常简单,一般有一主一从、一主多从,对于MySQL的主从的相关概念这里就不再详细介绍了。

下面陈某就以MySQL5.7为例,使用docker搭建一个一主一从的架构,步骤如下:

1. pull镜像

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

 
shell
代码解读
复制代码
docker pull mysql:5.7.26

2. 创建目录

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

 
shell
代码解读
复制代码
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主节点的配置文件,内容如下:

 
conf
代码解读
复制代码
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从节点的配置文件,内容如下:

 
conf
代码解读
复制代码
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主节点

命令如下:

 
shell
代码解读
复制代码
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,供从服务器使用

命令如下:

 
shell
代码解读
复制代码
[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从服务器

命令如下:

 
shell
代码解读
复制代码

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_filemaster_log_pos两个参数,然后切换到从服务器上进行主服务器的连接信息的设置。

主服务上执行:

 
shell
代码解读
复制代码
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地址:

 
shell
代码解读
复制代码
[root@aliyun /]# docker inspect --format='{{.NetworkSettings.IPAddress}}' master
172.17.0.2

从服务器上执行:

 
shell
代码解读
复制代码
[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线程

 
shell
代码解读
复制代码
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对于读写分离的配置非常简单,分为如下几个步骤:

关于数据库中的表的SQL就不再贴了,文末有案例源码,自己下载!

1. 数据源配置

无论是分库分表还是读写分离,数据源的声明肯定是必须的,如下:

 
yaml
代码解读
复制代码
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

源码已经上传GitHub,关注公众号:码猿技术专栏,回复关键词:9537 获取

2. 主从节点配置

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

配置规则如下:

 
properties
代码解读
复制代码
#主库数据源名称,名称随意
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>一定要注意,这个是主从配置的名称(相当于逻辑数据源),名称可以随意,但是一定要唯一。

陈某的配置如下:

 
yaml
代码解读
复制代码
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的日志,如下:

可以看到都在ds1中执行了

2、读操作

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

可以看到都在ds2中执行了

总结

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

关于读写分离还有一些内容未介绍,将会放在后面文章详细介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/777973.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis为什么用单线程不用多线程

1.线程上下文切换开销。 2.线程之间共享变量,加锁解锁开销。瓶颈不在cpu而是在内存和网络io带宽。 3.多线程代码复杂。

全网最适合入门的面向对象编程教程:32 Python 的内置数据类型-类 Class 和实例 Instance

在Python中,类(Class)是创建对象(实例,Instance)的模板。类定义了对象的属性和行为,而实例是类的具体对象,具有独立的属性值。全网最适合入门的面向对象编程教程:32 Python 的内置数据类型-类 Class 和实例 Instance摘要: 在Python中,类(Class)是创建对象(实例,…

小猪佩奇学英语——第二天

第二天 例句被动语态:be+动词的过去分词Mr.Dinosaur is lost My boot is lost My keys are lost描述某个人最喜欢的东西是什么时,要用所有格(某个人的),因为某个人和东西是两个独立个体如:he 和 movie是两个独立个体,不能连起来,要用His Georges favourite toy is Mr.D…

epoll的解释

同步阻塞最差。 同步非阻塞可能会跑一圈一个作业也收不上来。 select / poll 可以确定有人完成作业了,因为是有人完成作业后举手,你才下去收作业的。但是需要一个一个去问。 epoll就很好了。

客户端和服务器通过http协议基于》》tcp协议,经过三次握手进行socket连接

io多路复用在两个地方被用到:一个是网络通信。 一个是redis的线程模型。

Git 开发规范

目录Git 开发规范分支管理策略git flowgithub flowgitlab flowtrunk-based development总结Commit Message Git 开发规范 分支管理策略 git flowVincent Driessen 于2010年提出的分支模型,可以说是最早、最全面的分支管理策略了,后续出现的分支管理策略基本都是基于 git flow…

k8s工作负载控制器--DaemonSet

目录一、概述二、适用场景三、基本操作1、官网的DaemonSet资源清单2、字段解释3、编写DaemonSet资源清单4、基于yaml创建DaemonSet5、注意点5.1、必须字段5.2、DaemonSet 对象的名称5.3、.spec.selector 与 .spec.template.metadata.labels之间的关系6、查看DaemonSet6.1、查看…

【考研概率论】两个集合的交集与并集相等意味着什么?

今天要给大家分享的笔记是:《交集和并集相等的两个事件一定是相同的事件》:

实现一个终端文本编辑器来学习golang语言:第三章文本查看器part1

本章我们来完成文本编辑器的文件打开和查看功能,最后成品如上图。我们将分4步,逐渐完成本章所需功能。内容比较多,会分为两个部分,第一部分主要关注于“View视图”和“buffer及文本读取”。 如上图最终效果所示,我们希望在终端的最下方增加一个状态栏,能够展示当前被打开…

基于和声搜索算法(Harmony Search,HS)的机器设备工作最优调度方案求解matlab仿真

1.程序功能描述通过和声搜索算法(Harmony Search,HS)实现机器设备工作时间调度,使得多个机器进行并行工作,使得最终完成任务的时间达到最小。仿真结果输出工作调度甘特图以及和声搜索算法的适应度值收敛曲线。2.测试软件版本以及运行结果展示 MATLAB2022a版本运行 3.核心程序…

从零体检一个魔塔社区模型(modelscope)最简单demo

从社区拿一个模型,比如以下这个链接 https://www.modelscope.cn/models/iic/cv_mobilenet-v2_bad-image-detecting 它的代码样例如下 from modelscope.pipelines import pipeline from modelscope.utils.constant import Tasks from modelscope.outputs import OutputKeysimg …

P2831 [NOIP2016 提高组] 愤怒的小鸟

讲解 P2831 [NOIP2016 提高组] 愤怒的小鸟。考虑状态压缩动态规划,需要根据两个点推出抛物线的解析式。思路: 考虑先求出经过 \((x_1,y_1),(x_2,y_2)\) 的抛物线解析式 我们有: \[\begin{cases} ax_1^2 + bx_1 = y_1 \\ ax_2^2 + bx_2 = y_2\end{cases} \]考虑将 \(b\) 消掉…