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

2023-05-16

为什么要读写分离?

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

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

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

读写分离如何搭建?

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

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

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

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

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的日志,如下:

e2fd1d2b6e4dbbbe1c122a14403ff1e5.png

可以看到都在ds1中执行了

2、读操作

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

b9542301316b5b221690b0ea46c1bd1f.png

可以看到都在ds2中执行了

总结

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

ad692113d84817a51d6ffeb65e571c72.gif

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

利用Sharding-JDBC 实现Mysql读写分离 的相关文章

  • 将 UPDATE 转换为 INSERT INTO ON DUPLICATE KEY UPDATE 语句

    我有这个 UPDATE MySQL 语句 效果很好 UPDATE table1 Inner Join table2 ON table2 id table1 gw id SET table1 field1 1 table1 field2 2
  • PHP PDO相关:更新SQL语句未更新数据库内容

    我正在尝试使用准备好的语句来实现更新语句PHP http en wikipedia org wiki PHP脚本 但它似乎没有更新数据库中的记录 我不确定为什么 所以如果您能分享一些见解 我将不胜感激 Code query UPDATE D
  • Glassfish 4 - JDBC 领域

    Glassfish 4 中的密码加密算法和摘要算法有什么区别 因为Password加密算法不能为空 所以我使用了MD5 Encoding使用了Hex 摘要算法为空 因此默认为 SHA 256 但是 如果我使用 JAAS 制作一个简单的登录应
  • 当“修复表”查询在 mysql 中不起作用时该怎么办?

    我收到此错误 表的存储引擎不支持修复 当我尝试使用查询修复表时repair table tbl college master 表是 innodb 类型 但我不知道我收到此错误 See 手册 http dev mysql com doc re
  • 对于数据库来说,选择正确的数据类型会影响性能吗?

    如果是这样 为什么 我的意思是 tinyint 的搜索速度比 int 快吗 如果是这样 性能上的实际差异是什么 是的 根据数据类型 它确实有所不同 int vs tinyint不会在速度上产生明显的差异 但会在数据大小上产生差异 假设tin
  • 如何在 phpmyadmin 中创建 MySQL 触发器

    我想在 MySQL 中创建一个触发器 我运行以下命令 mysql gt delimiter mysql gt CREATE TRIGGER before insert money BEFORE INSERT ON money gt FOR
  • PDO SQLSRV 和 PDO MySQL 在获取 int 或 float 时返回字符串

    当您获取时 PDO MS SQL Server 和 PDO MySQL 都会返回一个字符串数组 即使列的 SQL 类型本应是数字类型 例如 int 或 float 我设法解决了这个问题 但我想了解为什么它们一开始就这样设计 是不是因为PDO
  • java mysql 准备好的语句

    我正在尝试使用 java 向数据库中进行简单的插入 它告诉我我的 sql 语法已关闭 但是 当我复制打印出来的字符串并将其放入 phpmyadmin 中的 sql 命令中时 它会正确执行该命令 并且我似乎无法弄清楚 java 中的字符串查询
  • MySQL Connector/C++ 库链接错误问题

    PROBLEM 好吧 我一直在尝试遵循 MySQL Forge Wiki 和其他一些网站上的示例代码 这些网站提供了有关如何获得简单数据库连接的教程 但由于某种原因 我的项目总是因链接错误而失败 我可以我自己不明白为什么或如何解决它 我仍在
  • Mysql 检索所有有限制的行

    我想检索特定用户的所有行 限制为 0 x 所以我只是想问是否有任何方法可以检索 mysql 中的所有行 而不调用返回 x 的 count id 的方法 而不重载现有函数 该函数在查询中根本没有限制 与我们的 string Relace 功能
  • Mysql 中 UNION 子句的替代方案

    我有两张桌子 表 a 表 b table a ID 1 2 3 4 5 7 table b ID 2 3 4 5 6 我必须得到这样的输出而无需UNION命令 ID 1 2 3 4 5 6 7 注意 我有一个联合解决方案 select fr
  • 忽略重复条目并在 EF Core 中的 DbContext.SaveChanges() 上提交成功条目

    我有一个 ASP Net Core 2 2 Web API 在我的一个控制器操作中 我向 MySQL 数据库表添加了一堆行 我使用的是 Pomelo 例如 dbContext AddRange entities dbContext Save
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样
  • 如何使用 vitess 仅对特定表进行分片

    我创建了一个包含三个表的未分片键空间 现在我想对前两个表的键空间进行分片 但不想对第三个表进行分片 如何才能做到这一点 Vitess 文档不包含任何与此相关的信息或示例 请帮忙 Thanks vitess 中的垂直分片与水平分片类似 您应该
  • MySQL连接字符集问题

    我在 Mac 上使用带有 MySQL 的 velosurf 没有任何编码问题 但是当我切换到 Linux 计算机时 从 velosurf 获得的值未正确编码 我发现这可能是默认连接字符集的问题 在 Mac 上我得到 mysql gt sho
  • 在服务器上找不到本地主机或 phpMyAdmin:如何修复?

    我按照安装说明进行操作PHP MySQL and PHPMyAdmin 但是当我尝试访问时http localhost phpmyadmin 我收到此错误 未找到 在此找不到请求的 URL phpmyadmin 服务器 然后我尝试访问loc
  • 比特纳米。重置mysql根密码

    我如何重置 MySQL 中的 root 密码和帐户 因为我按照如何为其他服务器授予权限的说明操作 并且意外地将 root 用户 Mysql 绑定到其他 IP 地址 现在看来我无法在 localhost 上以管理员身份登录 Thanks 您有
  • 如何在 Play java 中创建数据库线程池并使用该池进行数据库查询

    我目前正在使用 play java 并使用默认线程池进行数据库查询 但了解使用数据库线程池进行数据库查询可以使我的系统更加高效 目前我的代码是 import play libs Akka import scala concurrent Ex
  • 在 PHP 字符串中格式化 MySQL 代码

    是否有任何程序 IDE 可以在 PHP 字符串中格式化 MySQL 代码 例如 我使用 PHPStorm IDE 但它无法做到这一点 它对 PHP 和 MYSQL 执行此操作 但不适用于 php 字符串内的 MYSQL 我已准备好使用新的
  • 在 MySQL 中存储表情符号的编码问题:如何使用 Prisma ORM 在 NodeJS 中定义字符排序规则?

    亲爱的 Nodejs 专家和数据库专家 我们在 MySQL 数据库中存储表情符号和其他特殊字符时遇到问题 我们使用 Prisma 得到一个错误 这是我们使用的 ORM 参数无法从排序规则 utf8 general ci 转换为 utf8mb

随机推荐

  • 创建一个最简单的链表,插入和删除

    原创文章欢迎转载 创建一个链表 一 头插法创建链表 xff1a include lt stdio h gt struct list int num struct list next typedef struct list list sing
  • C语言循环链表创建,遍历,插入,删除,查找

    在开始程序之前说一个困扰的几天的东西 xff0c 在链表做形参的时候什么时候用 xff08 p xff09 什么时候用 xff08 p xff09 答案 xff1a 只要是要修改head指针必须传递head的地址 xff08 用 p xff
  • C语言顺序表的插入删除

    首先声明一个顺序表的结构 数组的第一个元素是0 xff0c 但是顺序表的第一个一般 从1 人为设定 开始 include lt stdio h gt include lt stdlib h gt define MAXSIZE 10 defi
  • 蓝牙HC05模块探究-设置AT指令

    蓝牙HC05是主从一体的蓝牙串口模块 xff0c 简单的说 xff0c 当蓝牙设备与蓝牙设备配对连接成功后 xff0c 我们可以忽视蓝牙内部的通信协议 xff0c 直接将将蓝牙当做串口用 当建立连接 xff0c 两设备共同使用一通道也就是同
  • WPF、C# iconfont图标字体只显示框框

    在我们写C 或者WPF 程序的时候 xff0c 引入字体图标的时候 xff0c 新手会出现下面这个问题 xff1b 下面说下常见的两个原因吧 xff1a 1 是文件路径定义的不对 xff1a lt TextBlock Text 61 34
  • Linux执行curl报错:Protocol htttp not supported or disabled in libcurl

    因为公司最近要用到docker xff0c 在学习过程中 构建了一个简单web镜像 xff0c 用于测试 通过curl访问地址时 xff0c 报错 随便百度下 xff0c 也没看懂 仔细一看 xff0c 原来是http写成htttp了 所以
  • Android 获取应用信息—PackageManager

    Android 的应用管理主要是通过PackageManagerService来完成的 PackageManagerService服务负责各种APK包的安装 卸载 优化和查询 PackageManagerService在启动时会扫描所有的A
  • eclipse自动补全不生效解决方法

    eclipse有时候设置了自动补全 xff0c 但明明设置了自动补全却没生效的解决办法 xff0c 按照图片上标注序号一步步进入Advanced页面后 xff0c 勾选第四步的三项选项即可 xff0c 重新生效 xff0c 如下
  • 史上最全的C++面试宝典(合集)

    参考 xff1a https www runoob com cplusplus cpp tutorial html 本教程旨在提取最精炼 实用的C 43 43 面试知识点 xff0c 供读者快速学习及本人查阅复习所用 目录 第一章 C 43
  • 电脑主板,显卡,CPU天梯图

    17年6月主板天梯图 18年2月显卡天梯图 18年3月CPU天梯图
  • sqlserver 批量删除存储过程

    sqlserver 2005一次只能删除一个存储过程 xff0c 如果多了 xff0c 需要很长时间才能删完 xff0c 所以写了一段语句 xff0c 直接就把当然数据库下所有用户自定义的存储过程给drop了 不过使用都请留心 xff0c
  • win7开启wifi共享(热点)

    1 首先在电脑左下方搜索cmd xff0c 以管理员身份运行 输入命令 xff1a netsh wlan set hostednetwork mode 61 allow ssid 61 4Gtest key 61 12345678 ssid
  • Spring官方提供【CSRF攻击】解决方案

    步入正文 Cookie cookie是我们常见用来保存用户态信息 xff0c cookie跟随我们的请求自动携带 在同一域名下的请求 xff0c cookie总是自动携带 用户态 当前登入者的用户信息 以上的特性会导致一个潜在漏洞 CSRF
  • RocketMQ 一个topic 多个消费者只有一个消费的问题

    前言 很多时候 xff0c 我们会在多个地方同时订阅一个 topic xff0c 但是发现消费者只能执行一个后注册消费者会顶替之前注册的消费者 原因 在 subscribeTable 和 subscriptionInner 方法中 xff0
  • 如何快速学习一门新计算机语言

    本来想总结老师的方法的 xff0c 可在网上找到一篇一模一样的 xff0c 为了保证原创性 xff0c 所以只好直接引用啦 点击打开链接 如何快速学习一门新计算机语言
  • 福利抽奖 | 开源企业级监控Zabbix6.0都有哪些亮点

    Zabbix是企业级开源监控解决方案 xff0c 支持实时监控数万台服务器 虚拟机和网络设备 xff0c 采集百万级监控指标 xff0c 提供跨平台支持 Zabbix完全开源免费 xff0c 社区十分活跃 xff0c 生态建设良好 xff0
  • Git的一些常用概念

    git思维导图 Git工作区域 为了说明我们日常开发中执行的一系列Git命令的作用是什么 xff0c 我们需要了解Git的工作区域的概念 xff0c 几乎每一个常见的Git命令操作都可以通过工作区域来解释 Git本地有四个工作区域 xff1
  • 有没有完全自主的国产化数据库技术

    前段时间的俄乌冲突 xff0c Oracle 宣布 暂停在俄罗斯的所有业务 xff0c 相信大家的心情绝不是隔岸观火 xff0c 而是细思恐极 数据库号称 IT 领域三大核心之一 xff08 其他两个是 CPU 和操作系统 xff09 xf
  • 多个线程之间如何协同

    1 CountDownLatch 计数器 在多线程协作完成任务的时候 xff0c 有时候需要等待其他线程完成任务后 xff0c 主线程才能继续执行 xff0c 我们可以使用 Thread 类的 join 方法 xff0c 让主线程等待被 j
  • 利用Sharding-JDBC 实现Mysql读写分离

    为什么要读写分离 xff1f 读写分离则是将事务性的增 改 删操作在主库执行 xff0c 查询操作在从库执行 一般业务的写操作都是比较耗时 xff0c 为了避免写操作影响查询的效率 xff0c 可以使用读写分离 当然读写分离并不是万能的 x