MySQL?讀寫分離的實(shí)現(xiàn)邏輯及步驟詳解
讀寫分離 是數(shù)據(jù)庫架構(gòu)優(yōu)化的一種常見策略,主要用于提高數(shù)據(jù)庫的吞吐能力和查詢性能。
MySQL 讀寫分離的核心思想是:
- 寫操作(INSERT、UPDATE、DELETE)只在 主庫(Master) 上執(zhí)行。
- 讀操作(SELECT)在 從庫(Slave) 上執(zhí)行。
- 通過 主從復(fù)制(Master-Slave Replication)保持?jǐn)?shù)據(jù)一致性。
一、讀寫分離的基本架構(gòu)
通常采用 一主多從(Master-Slave)的架構(gòu),即:
- Master(主庫) 負(fù)責(zé)處理所有寫請求,并將數(shù)據(jù)變更同步到從庫。
- Slave(從庫) 負(fù)責(zé)處理讀請求,提高查詢性能。
- 中間件或代理(如 MySQL Proxy、MyCat、ShardingSphere-Proxy)用于路由 SQL 請求。
二、MySQL 讀寫分離的實(shí)現(xiàn)步驟
1. 配置 MySQL 主從復(fù)制
(1)在主庫(Master)上配置
① 修改 MySQL 配置文件 (my.cnf 或 my.ini):
[mysqld] server-id=1 # 設(shè)置唯一的服務(wù)器ID log-bin=mysql-bin # 啟用二進(jìn)制日志(binlog),用于數(shù)據(jù)同步 binlog-format=ROW # 推薦使用行格式(ROW)以保證數(shù)據(jù)一致性
② 創(chuàng)建用于復(fù)制的賬號(hào):
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;
③ 查看 Master 的二進(jìn)制日志信息:
SHOW MASTER STATUS;
輸出示例:
±-----------------±---------±-------------±-----------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
±-----------------±---------±-------------±-----------------+
| mysql-bin.000001 | 157 | testdb | |
±-----------------±---------±-------------±-----------------+
記住 File 和 Position,稍后在從庫中使用。
(2)在從庫(Slave)上配置
① 修改 MySQL 配置文件 (my.cnf 或 my.ini):
server-id=2 # 每個(gè)從庫都需要唯一的 server-id relay-log=relay-bin # 設(shè)定 relay log 用于主從同步 read-only=1 # 設(shè)定為只讀,防止誤寫
② 配置從庫連接主庫:
CHANGE MASTER TO MASTER_HOST='主庫IP', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', -- Master 服務(wù)器上 SHOW MASTER STATUS 查詢得到的 File MASTER_LOG_POS=157; -- Master 服務(wù)器上 SHOW MASTER STATUS 查詢得到的 Position
③ 啟動(dòng)復(fù)制進(jìn)程:
START SLAVE;
④ 檢查主從同步狀態(tài):
SHOW SLAVE STATUS\G;
如果 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes,表示復(fù)制正常。
2. 配置讀寫分離
主從復(fù)制完成后,需要將 寫請求發(fā)往主庫,讀請求發(fā)往從庫。實(shí)現(xiàn)方式有:
- 應(yīng)用層代碼控制(手動(dòng)選擇數(shù)據(jù)庫連接)
- MySQL 代理中間件(MySQL Router、MyCat、ShardingSphere-Proxy)
- 數(shù)據(jù)庫連接池方案(如 C3P0、HikariCP)
(1)應(yīng)用層代碼控制
在 Java 代碼中,可以使用不同的數(shù)據(jù)源進(jìn)行讀寫分離:
// 寫操作 - 連接 Master try (Connection conn = masterDataSource.getConnection()) { String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, "Amy"); stmt.setString(2, "amy@example.com"); stmt.executeUpdate(); } } // 讀操作 - 連接 Slave try (Connection conn = slaveDataSource.getConnection()) { String sql = "SELECT * FROM users"; try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { while (rs.next()) { System.out.println("User: " + rs.getString("name")); } } }
(2)使用 MySQL Router
MySQL Router 是官方的讀寫分離代理工具:
安裝 MySQL Router:
sudo apt install mysql-router
配置路由規(guī)則(mysqlrouter.conf):
[routing:read_write] bind_address = 0.0.0.0 bind_port = 3306 routing_strategy = first-available destinations = master_ip:3306 [routing:read_only] bind_address = 0.0.0.0 bind_port = 3307 routing_strategy = round-robin destinations = slave1_ip:3306,slave2_ip:3306
應(yīng)用程序連接:
- 寫請求 連接 127.0.0.1:3306
- 讀請求 連接 127.0.0.1:3307
(3)使用 ShardingSphere-JDBC
Spring Boot 可使用 ShardingSphere-JDBC 進(jìn)行自動(dòng)讀寫分離:
spring: shardingsphere: datasource: names: master, slave master: url: jdbc:mysql://master_ip:3306/testdb username: root password: password slave: url: jdbc:mysql://slave_ip:3306/testdb username: root password: password rules: readwrite-splitting: data-sources: readwrite_ds: type: Static props: write-data-source-name: master read-data-source-names: slave
三、可能遇到的問題及解決方案
四、總結(jié)
主從復(fù)制通過 binlog 機(jī)制同步數(shù)據(jù),為讀寫分離提供基礎(chǔ)。
讀寫分離策略:
- 代碼層手動(dòng)控制
- 代理中間件(MySQL Router、MyCat)
- 數(shù)據(jù)庫連接池(ShardingSphere-JDBC)
優(yōu)化點(diǎn):
- 通過 負(fù)載均衡 分配從庫查詢壓力
- 避免 復(fù)制延遲 影響查詢結(jié)果
- 采用 事務(wù)管理策略,確保數(shù)據(jù)一致性
這樣可以大幅提高 MySQL 讀查詢性能,減少主庫壓力,提高整體數(shù)據(jù)庫系統(tǒng)的可擴(kuò)展性。
到此這篇關(guān)于MySQL 讀寫分離的實(shí)現(xiàn)邏輯的文章就介紹到這了,更多相關(guān)MySQL 讀寫分離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mysql?中的備份恢復(fù),分區(qū)分表,主從復(fù)制,讀寫分離
- 最新MySql8.27主從復(fù)制及SpringBoot項(xiàng)目中的讀寫分離實(shí)戰(zhàn)教程
- MySQL讀寫分離原理詳細(xì)解析
- 分享MySQL?主從延遲與讀寫分離的七種解決方案
- springboot結(jié)合mysql主從來實(shí)現(xiàn)讀寫分離的方法示例
- SpringBoot+Mybatis-Plus實(shí)現(xiàn)mysql讀寫分離方案的示例代碼
- Springboot + Mysql8實(shí)現(xiàn)讀寫分離功能
- springboot基于Mybatis mysql實(shí)現(xiàn)讀寫分離
相關(guān)文章
MySQL ERROR 1045 (28000): Access denied for user ''root''@''
這篇文章主要介紹了MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 的原因分解決辦法的相關(guān)資料,需要的朋友可以參考下2016-05-05Mysql?InnoDB引擎中的數(shù)據(jù)頁結(jié)構(gòu)詳解
這篇文章主要為大家介紹了Mysql?InnoDB引擎中的數(shù)據(jù)頁結(jié)構(gòu)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05xampp中修改mysql默認(rèn)空密碼(root密碼)的方法分享
以前開發(fā)我一直都是用的phpnow做php開發(fā)環(huán)境,phpnow的特點(diǎn)就是一鍵安裝,安裝的時(shí)候會(huì)要求用戶輸入mysql的root密碼。今天由于客戶機(jī)器使用的xampp作為開發(fā)環(huán)境,所以碰到了修改mysql默認(rèn)空密碼的問題2014-04-04簡單了解mysql InnoDB MyISAM相關(guān)區(qū)別
這篇文章主要介紹了簡單了解mysql InnoDB MyISAM相關(guān)區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Mysql誤操作后利用binlog2sql快速回滾的方法詳解
相信每個(gè)和數(shù)據(jù)庫打交道的程序員都會(huì)碰一個(gè)問題,MySQL誤操作后如何快速回滾?那么下面這篇文章主要給大家介紹了關(guān)于Mysql誤操作后利用binlog2sql快速回滾的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考下。2017-07-07prometheus監(jiān)控MySQL并實(shí)現(xiàn)可視化的操作詳解
mysqld_exporter?是一個(gè)用于監(jiān)控?MySQL?服務(wù)器的開源工具,它是由?Prometheus?社區(qū)維護(hù)的一個(gè)官方?Exporter,本文給大家介紹了prometheus監(jiān)控MySQL并實(shí)現(xiàn)可視化的操作,文中通過代碼和圖文講解的非常詳細(xì),需要的朋友可以參考下2024-04-04