魔獸爭霸細節4月4日
一、介紹
MySQL主從複製是一個非同步的複製過程,底層是基於MySQL資料庫自帶的二進位制日誌功能。就是一臺或者多型MySQL資料庫(slave,即從庫)從另一臺MySQL資料庫(master,即主庫)進行日誌的複製然後再解析日誌並應用到自身,最終實現 從庫的資料和 主庫的資料保持一直。MySQL主從複製是 MySQL資料庫自帶功能,無需藉助第三方工具
1.1 一個mysql資料庫處理資料存在的問題
我們如果使用一個數據庫後臺管理系統及移動端的使用者,在進行資料訪問時,都是直接操作資料庫MySQL的:
1). 讀和寫所有壓力都由一臺資料庫承擔,壓力大
2). 資料庫伺服器磁碟損壞則資料丟失,單點故障
1.2 解決方案
為了解決上述提到的兩個問題,我們可以準備兩臺MySQL,一臺主(Master)伺服器,一臺從(Slave)伺服器,主庫的資料變更,需要同步到從庫中(主從複製)。而使用者在訪問我們專案時,如果是寫操作(insert、update、delete),則直接操作主庫;如果是讀(select)操作,則直接操作從庫(在這種讀寫分離的結構中,從庫是可以有多個的),這種結構我們稱為 讀寫分離 。
1.3 MySQL複製過程分為三步
- master將改變 記錄到二進位制日誌 (binary log)
- slave將 master的binary log拷貝到它的中繼日誌(relay log)
- slave重做 中繼日誌中的事件,將改變應用到自己的資料庫中
二進位制日誌:
二進位制日誌(BINLOG)記錄了所有的 DDL(資料定義語言)語句和 DML(資料操縱語言)語句,但是不包括資料查詢語句。此日誌對於災難時的資料恢復起著極其重要的作用,MySQL的主從複製, 就是通過該binlog實現的。預設MySQL是未開啟該日誌的。
主從複製原理:
MySQL複製過程分成三步:
1). MySQL master 將資料變更寫入二進位制日誌( binary log)
2). slave將master的binary log拷貝到它的中繼日誌(relay log)
3). slave重做中繼日誌中的事件,將資料變更反映它自己的資料
二、搭建主從複製
2.1 伺服器準備工作
1.2.1 準備工作
提前準備兩臺伺服器,並且在伺服器中安裝MySQL,伺服器的資訊如下:
資料庫 | IP | 資料庫版本 |
---|---|---|
Master | 192.168.6.130 | 5.7.25 |
Slave | 192.168.6.131 | 5.7.25 |
並在兩臺伺服器上做如下準備工作:
1). 防火牆開放3306埠號
firewall-cmd --zone=public --add-port=3306/tcp --permanent
firewall-cmd --zone=public --list-ports
2). 並將兩臺資料庫伺服器啟動起來:
systemctl start mysqld
登入MySQL,並驗證是否正常啟動
2.2 配置-主庫Master
1).修改Mysql資料庫的配置檔案 /etc/my.cnf
[mysqld]
log-bin=mysql-bin #[必須]啟動二進位制日誌
server-id=130 #[必須] 伺服器唯一ID
2). 重啟Mysql服務
執行指令:
systemctl restart mysqld
3). 建立資料同步的使用者並授權
登入mysql,並執行如下指令,建立使用者並授權:
GRANT REPLICATION SLAVE ON *.* to 'testMasterSlave'@'%' identified by 'Root@123456';
注:上面SQL的作用是建立一個使用者 testMasterSlave ,密碼為 Root@123456 ,並且給testMasterSlave使用者授予REPLICATION SLAVE許可權。常用於建立複製時所需要用到的使用者許可權,也就是slave必須被master授權具有該許可權的使用者,才能通過該使用者複製。
MySQL密碼複雜程度說明
目前mysql5.7預設密碼校驗策略等級為 MEDIUM , 該等級要求密碼組成為: 數字、小寫字母、大寫字母 、特殊字元、長度至少8位
4). 登入Mysql資料庫,檢視master同步狀態
執行下面SQL,記錄下結果中File和Position的值
show master status;
注:上面SQL的作用是檢視Master的狀態,執行完此SQL後不要再執行任何操作
2.3 配置-從庫Slave
1). 修改Mysql資料庫的配置檔案/etc/my.cnf
server-id=131 #[必須]伺服器唯一ID 需要主和從唯一就可
2). 重啟Mysql服務
systemctl restart mysqld
3). 登入Mysql資料庫,設定主庫地址及同步位置
change master to master_host='192.168.6.130',master_user='testMasterSlave',master_password='Root@123456',master_log_file='mysql-bin.000001',master_log_pos=441;
start slave;
引數說明:
A. master_host : 主庫的IP地址
B. master_user : 訪問主庫進行主從複製的使用者名稱(上面在主庫建立的)
C. master_password : 訪問主庫進行主從複製的使用者名稱對應的密碼
D. master_log_file : 從哪個日誌檔案開始同步(上述查詢master狀態中展示的有)
E. master_log_pos : 從指定日誌檔案的哪個位置開始同步(上述查詢master狀態中展示的有)
4). 檢視從資料庫的狀態
show slave status;
然後通過狀態資訊中的 Slave_IO_running 和 Slave_SQL_running 可以看出主從同步是否就緒,如果這兩個引數全為Yes,表示主從同步已經配置完成。 其實就是Slave的io執行緒 和 sql執行緒是否開啟了
2.4測試
主從複製的環境,已經搭建好了,接下來,我們可以通過Navicat連線上兩臺MySQL伺服器,進行測試。測試時,我們只需要在主庫Master執行操作,檢視從庫Slave中是否將資料同步過去即可。
1). 在master中建立資料庫test-user, 重新整理slave檢視是否可以同步過去
2). 在master的test-user資料下建立user表, 重新整理slave檢視是否可以同步過去
3). 在master的user表中插入一條資料, 重新整理slave檢視是否可以同步過去
三、讀寫分離案例
3.1 背景介紹
面對日益增加的系統訪問量,資料庫的吞吐量面臨著巨大瓶頸。 對於同一時刻有大量併發讀操作和較少寫操作型別的應用系統來說,將資料庫拆分為主庫和從庫,主庫負責處理事務性的增刪改操作,從庫負責處理查詢操作,能夠有效的避免由資料更新導致的行鎖,使得整個系統的查詢效能得到極大的改善。
通過讀寫分離,就可以降低單臺數據庫的訪問壓力, 提高訪問效率,也可以避免單機故障。
3.2 ShardingJDBC介紹
Sharding-JDBC定位為輕量級Java框架,在Java的JDBC層提供的額外服務。 它使用客戶端直連資料庫,以jar包形式提供服務,無需額外部署和依賴,可理解為增強版的JDBC驅動,完全相容JDBC和各種ORM框架。使用Sharding-JDBC可以在程式中輕鬆的實現資料庫讀寫分離。
Sharding-JDBC具有以下幾個特點:
1). 適用於任何基於JDBC的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
2). 支援任何第三方的資料庫連線池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
3). 支援任意實現JDBC規範的資料庫。目前支援MySQL,Oracle,SQLServer,PostgreSQL以及任何遵循SQL92標準的資料庫。
依賴:
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
3.3 資料庫環境
在主庫中建立一個數據庫rw, 並且建立一張表, 該資料庫及表結構建立完畢後會自動同步至從資料庫,SQL語句如下
create database rw default charset utf8mb4;
use rw;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
3.4 Springboot工程搭建
這裡搭建過程省略 => 使用mybatis-plus對user表增刪改查
3.5 讀寫分離配置
1). 在pom.xml中增加shardingJdbc的maven座標
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
2). 在application.yml中增加資料來源的配置
spring:
shardingsphere:
datasource:
names:
# 資料來源的名稱 master,slave可以任意定義
master,slave
# 主資料來源
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.130:3306/rw?characterEncoding=utf-8
username: root
password: root
# 從資料來源
slave:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.131:3306/rw?characterEncoding=utf-8
username: root
password: root
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
3). 在application.yml中增加配置
spring:
main:
# 允許bean定義覆蓋
allow-bean-definition-overriding: true
該配置項的目的,就是如果當前專案中存在同名的bean,後定義的bean會覆蓋先定義的
。