日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

【MySQL】Spring Boot项目基于Sharding-JDBC和MySQL主从复制实现读写分离(8千字详细教程)

發布時間:2024/3/12 数据库 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【MySQL】Spring Boot项目基于Sharding-JDBC和MySQL主从复制实现读写分离(8千字详细教程) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

  • 前言
  • 一、 介紹
  • 二、 主從復制
    • 1. 原理
    • 2. 克隆從機
    • 3. 克隆從機大坑
    • 4. 遠程登陸
    • 5. 主機配置
    • 6. 從機配置
    • 7. 主機:建立賬戶并授權
    • 8. 從機:配置需要復制的主機
    • 9. 測試
    • 10. 停止主從同步
  • 三、 讀寫分離
    • 1. Sharding-JDBC介紹
    • 2. 一主一從
    • 3. 一主一從讀寫分離
      • 3.1 實現步驟
      • 3.2 配置讀寫分離規則
      • 3.3 允許bean定義覆蓋配置項
      • 3.4 啟動項目測試


前言

  • 本篇文章將手把手教你如何在 Linux 虛擬機上搭建 MySQL 一主一從的數據庫架構,教你如何實現 MySQL 主從復制,再到手把手教你如何在 Spring Boot 項目上使用 Sharding-JDBC 框架實現讀寫分離。
  • 筆者開發環境介紹:
    • Linux 系統:Centos 7
    • 虛擬機:VMware 16
    • MySQL :8.0.31
  • 如果還沒安裝 VMware 虛擬機軟件和 CentOS 7 的小伙伴可以移步到我的這篇博文進行學習——《Linux系統CentOS7虛擬機VMware安裝保姆級教程》。
  • 如果不知道在 CentOS 7 如何安裝 MySQL 的小伙伴可以移步到我的這篇博文進行學習——《Linux下如何安裝MySQL以及遠程登錄保姆級教程》。

一、 介紹


  • 面對日益增加的系統訪問量,數據庫的吞吐量面臨著巨大瓶頸。對于同一時刻有大量并發讀操作和較少寫操作類型的應用系統來說,將數據庫拆分為主庫和從庫,主庫負責處理事務性的增刪改操作,從庫負責處理查詢操作,能夠有效的避免由數據更新導致的行級鎖,使得整個系統的查詢性能得到極大的改善。這就稱為讀寫分離。


二、 主從復制


1. 原理

  • MySQL 主從復制是一個異步的復制過程,底層是基于 MySQL 數據庫自帶的二進制日志 (Binlog) 功能。就是一臺或多臺 MySQL 數據庫 (slave,即從庫) 從另一臺 MySQL 數據庫 (master,即主庫) 進行日志的復制然后再解析日志并應用到自身,最終實現從庫的數據和主庫的數據保持一致。MySQL 主從復制是 MySQL 數據庫自帶功能,無需借助第三方工具。
  • MySQL 復制過程分成三步:
    • master 將改變記錄到二進制日志 (binary log) ;
    • slave 將 master 的 binary log 拷貝到它的中繼日志 (relay log) ;
    • slave 重做中繼日志中的事件,將改變應用到自己的數據庫中。



2. 克隆從機

  • 首先要準備兩臺 Linux 虛擬機,筆者已經安裝過一臺虛擬機作為主機,IP 地址為 192.168.148.100 (server100) ,現在我們通過 VMware 軟件的 “克隆” 功能來克隆出第二臺 Linux 虛擬機作為從機,IP 地址設置為 192.168.148.101 。

  • 首先關閉 server100 :

  • 然后左側右擊 server100 –> 管理 –> 克隆:

  • 點擊 “下一頁” :

  • 保持默認,下一頁:

  • 選擇 “創建完整克隆” ,點擊下一頁:

  • 改名、改存放路徑:

  • 開始克隆:

  • 克隆完成:

  • 克隆完成后,要修改四個位置。第一個是網絡,雙擊 server101 的網絡適配器:

  • 點擊 “高級” :

  • 點擊 “生成” 來修改 MAC 地址,確保兩臺虛擬機的 MAC 地址不同:

  • 然后,開機 server101 ,登錄 root 用戶:

  • 修改主機名稱。命令如下:

    vim /etc/hostname

    記得 :wq 保存退出。

  • 重命名后需要重啟:

    reboot

  • 重啟完再以 root 用戶登錄,下一步是更改 IP 地址:

    vim /etc/sysconfig/network-scripts/ifcfg-ens33
  • 改兩個地方,一個是 UUID ,確保和 server100 不同即可;另一個是 IPADDR ,我修改為 192.168.148.101 。

    修改好后按 :wq 保存退出。

  • 然后重啟網絡:

    systemctl restart network
  • 這樣,一臺虛擬機就克隆完成了。重要的是,里面曾經安裝的 JDK、MySQL、Redis 等軟件和數據都是跟 server100 保持一致的。這就省去了我們重復安裝和配置的麻煩了。


3. 克隆從機大坑

  • 克隆的方式生成的虛擬機 (包含 MySQL Server),則克隆的虛擬機 MySQL Server 的 UUID 相同 (此 UUID 是 MySQL 服務的 UUID,和前面修改的 Linux 網絡配置的 UUID 不是同一個東西) ,必須修改,否則在有些場景會報錯。比如: show slave status\G ,報如下的錯誤:

    Last_IO_Error: Fatal error: The slave I/0 thread stops because master and slave have equal MySQL server UUIDs; these UUIDS must be different for replication to work.
  • 解決方法:

    修改 MySQL Server 的 UUID 方式:

    vim /var/lib/mysql/auto.cnf

    自己隨便改,與 server 100 不同即可。

  • 然后,重啟 MySQL 服務即可:

    systemctl restart mysqld

4. 遠程登陸

  • 筆者采用 MobaXTerm 遠程登陸:

  • 新建連接:

  • 成功遠程連接:

  • 此時,server100 也可以開機了:

  • server100 作為主機、server101 作為從機,一主一從實現讀寫分離。

  • SQLyog 遠程登錄 - 教程詳見我的這篇博文的第 4 章《4. SQLyog遠程連接》。


5. 主機配置

  • 建議 MySQL 版本一致且后臺以服務運行,主從所有配置項都配置在[mysqld] 節點下,且都是小寫字母。具體參數配置如下:

  • 必選:

    # [必須]主服務器唯一ID server-id=100# [必須]啟用二進制日志,指名路徑。比如:自己本地的路徑/log/mysqlbin log-bin=ouc-bin
  • 可選:

    # [可選] 0(默認)表示可讀可寫(主機),1表示只讀(從機) read-only=0# 設置日志文件保留的時長,單位是秒 binlog_expire_logs_seconds=6000# 控制單個二進制日志大小。此參數的最大和默認值是1GB max_binlog_size=200M# [可選]設置不要復制的數據庫 binlog-ignore-db=test# [可選]設置需要復制的數據庫,默認全部記錄。比如: binlog-do-db=atguigu_master_slave binlog-do-db=需要復制的主數據庫名字# [可選]設置binlog格式 binlog_format=STATEMENT
  • 重啟后臺 MySQL 服務,使配置生效。

【注意】

  • 先搭建完主從復制,再創建數據庫。MySQL 主從復制起始時,從機不繼承主機數據。
  • 進入主機 server100 ,輸入以下命令進入 biglog 配置文件:

    vim /etc/my.cnf
  • 在第 3 行左右,修改成如下的樣子:

    按 :wq 保存并退出。

  • 然后重啟 MySQL 服務:

    systemctl restart mysqld

6. 從機配置

  • 從機 server101 也如法炮制。

  • 要求主從所有配置項都配置在 /etc/my.cnf 的 [mysqld] 欄位下,且都是小寫字母。

  • 必選:

    [mysqld] # [必須]從服務器唯一ID,要與主服務器不同 server-id=101
  • 可選:

    # [可選]啟用中繼日志 relay-log=mysql-relay

  • 重啟后臺 mysql 服務,使配置生效。

    systemctl restart mysqld

【注意】

  • 主、從機都要開放 MySQL 端口號 3306 的防火墻。

7. 主機:建立賬戶并授權

  • 如果你使用的是 MySQL 5.7 ,只需執行下面一條指令即可:

    -- MySQL 5.7專用 GRANT REPLICATION SLAVE ON *.* TO 'slave101'@'從機器數據庫IP' IDENTIFIED BY 'xsh981104';

    其中,‘slave101’ 是你自己起的從機名稱。

  • 注意,筆者使用的是 MySQL 8.0 ,在主機端進入 MySQL root 用戶,輸入以下命令創建名為 slave101 的賬戶,用于主機和從機之間的通信:

    mysql> CREATE USER 'slave101'@'%' IDENTIFIED BY 'xsh981104';
  • 我創建的時候報了一個錯誤:

    ERROR 1396 (HY000): Operation CREATE USER failed for 'slave101'@'%'
  • 原因是這個用戶之前創建過,但刪除了,沒有刷新權限。解決方法是先刪除這個用戶,然后再刷新權限,再次創建即可。

    -- 刪除用戶 DROP USER 'slave101';-- 刷新權限 FLUSH PRIVILEGES;-- 再次創建用戶 CREATE USER 'slave101'@'%' IDENTIFIED BY 'xsh981104';
  • 成功創建用戶 slave101 :

  • 然后,賦予用戶 slave101 權限:

    GRANT REPLICATION SLAVE ON *.* TO 'slave101'@'%';

    其中,REPLICATION 指的是主從復制的權限、*.* 表示任何數據庫下的任何表、'slave101'@'%' 表示授予權限的用戶。

  • 授權后,可以用下面的命令來查看用戶 slave101 擁有的所有權限:

    SHOW GRANTS FOR 'slave101'@'%';

  • 然后,如果你是 MySQL 8.0 ,下面的語句必須執行。否則出問題:

    ALTER USER 'slave101'@'%' IDENTIFIED WITH mysql_native_password BY 'xsh981104';

【注意】

  • 上面這句不執行,從機執行 show slave status\G 時會報下面的錯誤:

Last_IO_Error: error connecting to master ‘slave1@192.168.1.150:3306’ - retry-time: 60 retries: 1 message: Authentication plugin ‘caching_sha2_password’ reported error: Authentication requires secure connection.

  • 刷新權限:

    FLUSH PRIVILEGES;

  • 接下來是比較重要的步驟:查詢 Master 的狀態,并記錄下 File 和 Position 的值:

    SHOW MASTER STATUS;

    記錄下 File 和 Position 的值。注意執行完此步驟后不要再操作主服務器,防止主服務器狀態值變化。

  • 到這里,主庫的配置就完成了。


8. 從機:配置需要復制的主機

  • 步驟1-從機上,進入 MySQL ,開始復制主機:

    CHANGE MASTER TO MASTER_HOST='主機的IP地址', MASTER_USER='主機用戶名', MASTER_PASSWORD='主機用戶名的密碼', MASTER_LOG_FILE='ouc-bin.00000X', MASTER_LOG_POS=主機的Position值;
  • 舉例:

    CHANGE MASTER TO MASTER_HOST='192.168.148.100',MASTER_USER='slave101',MASTER_PASSWORD='xsh981104',MASTER_LOG_FILE='ouc-bin.000002',MASTER_LOG_POS=1805;

  • 步驟2-啟動 slave 同步:

    START SLAVE;


  • 疑難雜癥 1 - 有的小伙伴在步驟一時遇到類似下面的報錯:

    ERROR 3021 (HY000): This operation cannot be performed with a runing slave io thread; run STOP SLAVE IO_THREAD FOR CHANNEL '' first.

    這是因為從庫之前已經配置過主從復制,必須先停掉原來的:

    STOP SLAVE;

    再重新執行步驟 1 和 2 即可。


  • 疑難雜癥 2 - 有的小伙伴還遇到下面的報錯:

    ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository

    這是因為之前你開啟過中繼日志,又關掉了。解決方法是重置一下即可:

    RESET SLAVE;
  • 接著,查看從庫的同步狀態:

    SHOW SLAVE STATUS\G;

  • 這樣,主從復制就搭建完畢了。


9. 測試

  • 用 SQLyog 遠程連接至主庫和從庫。

  • 在主庫 192.168.148.100 中創建一個新的數據庫 test1 :

    CREATE DATABASE IF NOT EXISTS test1 CHARACTER SET 'utf8';
  • 使用該數據庫,在該數據庫下創建數據表 students :

    CREATE TABLE IF NOT EXISTS students( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, last_name VARCHAR(15) NOT NULL );
  • 在該表下插入數據:

    INSERT INTO students(last_name) VALUES('Tom'), ('Amy');
  • 查看主庫:

    SELECT * FROM students;

  • 打開從庫 192.168.148.101 ,再沒有任何操作的情況下,發現已經把主庫的數據庫 test1 以及數據表 students 復制過來了:

  • 且數據表 students 中的數據也是完全相同的:

    SELECT * FROM students;

  • 說明主從復制搭建成功。


10. 停止主從同步

  • 如果你想停止主從同步,只需在從庫輸入下面指令即可:

    STOP SLAVE;

三、 讀寫分離


1. Sharding-JDBC介紹

  • Sharding-JDBC 定位為輕量級 Java 框架,在Java的 JDBC 層提供的額外服務。它使用客戶端直連數據庫,以 jar 包形式提供服務,無需額外部署和依賴,可理解為增強版的 JDBC 驅動,完全兼容 JDBC 和各種 ORM 框架。使用 Sharding-JDBC 可以在程序中輕松的實現數據庫讀寫分離。

    • 適用于任何基于 JDBC 的 ORM 框架,如: JPA、Hibernate、 Mybatis、Spring JDBC Template 或直接使用 JDBC。
    • 支持任何第三方的數據庫連接池,如: DBCP、 C3PO、 BoneCP、Druid、 HikariCP 等。
    • 支持任意實現 JDBC 規范的數據庫。目前支持 MySQL、 Oracle、 SQLServer、 PostgreSQL 以及任何遵循 SQL92 標準的數據庫。
  • 與 Spring Boot 結合使用時,只需要添加 Maven 依賴坐標即可:

    <!-- Sharding-JDBC --> <dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.0.1</version> </dependency>

2. 一主一從

  • 在實現讀寫分離之前,要把 MySQL 的主從復制的結構搭建好。

  • 筆者的主庫 IP 地址為 192.168.148.100 ,從庫 IP 地址為 192.168.148.101 。版本都是 MySQL 8.0.31 。

  • 如果你的 MySQL 數據庫安裝在 Windows 電腦上,把 Windows 電腦上的數據庫備份成 .sql 文件,恢復到主庫上即可。不知道的小伙伴可以轉到我的這篇博文中學習——《如何把Windows上的MySQL數據庫遷移到Linux服務器上》。


3. 一主一從讀寫分離


3.1 實現步驟

  • 使用 Sharding-JDBC 實現讀寫分離只需要三步:
  • 導入 Sharding-JDBC 的 Maven 坐標;
  • 在配置文件 application.yml 中配置讀寫分離規則;
  • 在配置文件 application.yml 中配置允許 bean 定義覆蓋配置項。

  • 3.2 配置讀寫分離規則

    • 打開 Spring Boot 的配置文件 application.yml 。在 spring: 節點下添加下面的配置:

      spring:# 配置Sharding-JDBC讀寫分離規則shardingsphere:# 指定數據源datasource:names:master,slave # 一主一從# 配置主庫數據源master: # 必須跟上面names對應type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.148.100:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: xsh981104# 配置從庫數據源slave: # 必須跟上面names對應type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.148.101:3306/reggie?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: xsh981104# 讀寫分離配置masterslave:load-balance-algorithm-type: round_robin # 多個從庫的負載均衡策略:輪詢name: dataSource # 最終的數據源名稱master-data-source-name: master # 主庫數據源名稱slave-data-source-names: slave # 從庫數據源名稱列表,多個逗號分隔props:sql:show: true # 開啟SQL顯示,默認false
    • 大家根據自己的主、從庫的 IP 地址和密碼作相應的修改即可。

    • 如果有爆紅的情況,那就把 pom.xml 中的 Duird 的 Maven 坐標改成下面即可:

      <!-- Druid數據庫連接池 --> <dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.8</version> </dependency>
    • 然后,清除 IDEA 緩存并重啟 IDEA 即可正常啟動 Spring Boot 項目:


    3.3 允許bean定義覆蓋配置項

    • 為什么要配置這一項呢?是因為 Sharding-JDBC 和 Druid 都會創建一個 DataSource 的 bean ,這樣兩個重名的 bean 就會發生沖突。因此必須在 Spring Boot 配置文件 application.yml 中配置允許 bean 定義覆蓋為 true ,這樣,后定義的 bean 就會覆蓋前面定義的 bean ,從而解決了 bean 沖突的問題。

      spring:main:# 允許bean定義覆蓋allow-bean-definition-overriding: true
    • 這樣,基于 MySQL 主從復制實現讀寫分離就成功實現了。

    3.4 啟動項目測試

    • 啟動 Spring Boot 項目,可以看到啟動日志里生成了兩個數據源:

    • 打開瀏覽器來測試一下,在瀏覽器地址欄輸入你項目的地址,筆者這里是黑馬的《瑞吉外賣》的后臺管理系統。

    • 從日志中可以看到,讀取員工表是從 slave 從庫中讀取的:

    • 我們來測試一下寫操作,編輯一下員工信息:

    • 可以看到,寫操作是主庫 master 操作的:

    • 至此,基于 MySQL 主從復制實現讀寫分離就成功開發完畢了!

    • 如果你還有任何疑問,歡迎隨時在下方評論或者私信我,我會盡快給大家解答。

    總結

    以上是生活随笔為你收集整理的【MySQL】Spring Boot项目基于Sharding-JDBC和MySQL主从复制实现读写分离(8千字详细教程)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。