-
MySQL主從復制
-
讀寫分離案例
-
項目實現讀寫分離
-
Nginx-概述
-
Nginx-命令
-
Nginx-應用
我們如果使用一個數據庫后台管理系統及移動端的用戶,在進行數據訪問時,都是直接操作數據庫MySQL的:
2). 數據庫服務器磁盤損壞則數據丟失,單點故障
為了解決上述提到的兩個問題,我們可以准備兩台MySQL,一台主(Master)服務器,一台從(Slave)服務器,主庫的數據變更,需要同步到從庫中(主從復制)。而用戶在訪問我們項目時,如果是寫操作(insert、update、delete),則直接操作主庫;如果是讀(select)操作,則直接操作從庫(在這種讀寫分離的結構中,從庫是可以有多個的),這種結構我們稱為 讀寫分離 。

MySQL數據庫默認是支持主從復制的,不需要借助於其他的技術,我們只需要在數據庫中簡單的配置即可。接下來,我們就從以下的幾個方面,來介紹一下主從復制:
MySQL主從復制是一個異步的復制過程,底層是基於Mysql數據庫自帶的 二進制日志 功能。就是一台或多台MySQL數據庫(slave,即從庫)從另一台MySQL數據庫(master,即主庫)進行日志的復制,然后再解析日志並應用到自身,最終實現 從庫 的數據和 主庫 的數據保持一致。MySQL主從復制是MySQL數據庫自帶功能,無需借助第三方工具。
二進制日志:
二進制日志(BINLOG)記錄了所有的 DDL(數據定義語言)語句和 DML(數據操縱語言)語句,但是不包括數據查詢語句。此日志對於災難時的數據恢復起着極其重要的作用,MySQL的主從復制, 就是通過該binlog實現的。默認MySQL是未開啟該日志的。

1). MySQL master 將數據變更寫入二進制日志( binary log)
2). slave將master的binary log拷貝到它的中繼日志(relay log)
3). slave重做中繼日志中的事件,將數據變更反映它自己的數據
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,驗證是否正常啟動
192.168.6.130

192.168.6.131

注意事項
解決辦法,修改其中一台服務器的server-uuid,並保證server-uuid的格式正確,修改完成之后重啟Mysql服務就可以了
在修改配置文件之前,先登錄Mysql客戶端查看uuid,把返回的uuid復制,放到要修改的配置文件即可。
MySQL [hb3]> select uuid();
+--------------------------------------+
| uuid() |
+--------------------------------------+
| a39fd903-3a1c-11e8-ab46-000c29133368 |
+--------------------------------------+
1 row in set (0.00 sec)
修改uuid配置文件
# vim /data/mysql/auto.cnf //如過找不到 find -name auto.cnf 找一下路徑
[auto]
server-uuid=804f2ebe-3a1c-11e8-ab46-000c29133368 # 按照這個16進制格式,修改server-uuid,重啟mysql即可
服務器: 192.168.6.130
1). 修改Mysql數據庫的配置文件/etc/my.cnf
在最下面增加配置:
log-bin=mysql-bin #[必須]啟用二進制日志
server-id=130 #[必須]服務器唯一ID(唯一即可)

執行指令:
systemctl restart mysqld

登錄mysql,並執行如下指令,創建用戶並授權:
GRANT REPLICATION SLAVE ON *.* to 'xiaoming'@'%' identified by 'Root@123456';
==注:上面SQL的作用是創建一個用戶 xiaoming ,密碼為 Root@123456 ,並且給xiaoming用戶授予REPLICATION SLAVE權限。常用於建立復制時所需要用到的用戶權限,也就是slave必須被master授權具有該權限的用戶,才能通過該用戶復制。==
MySQL密碼復雜程度說明

執行下面SQL,記錄下結果中File和Position的值
show master status;

==注:上面SQL的作用是查看Master的狀態,執行完此SQL后不要再執行任何操作==
441 mysql-bin.000001
服務器: 192.168.6.131
server-id=131 #[必須]服務器唯一ID 這里我是和我的ip一致保證唯一 需要主和從唯一就可

2). 重啟Mysql服務
systemctl restart mysqld
3). 登錄Mysql數據庫,設置主庫地址及同步位置
change master to master_host='192.168.6.130',master_user='xiaoming',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線程是否開啟了

\G : 在MySQL的sql語句后加上\G,表示將查詢結果進行按列打印,可以使每個字段打印到單獨的行。即將查到的結構旋轉90度變成縱向;
主從復制的環境,已經搭建好了,接下來,我們可以通過Navicat連接上兩台MySQL服務器,進行測試。測試時,我們只需要在主庫Master執行操作,查看從庫Slave中是否將數據同步過去即可。
1). 在master中創建數據庫yang, 刷新slave查看是否可以同步過去


2). 在master的itcast數據下創建user表, 刷新slave查看是否可以同步過去
3). 在master的user表中插入一條數據, 刷新slave查看是否可以同步過去
2.1 背景介紹
面對日益增加的系統訪問量,數據庫的吞吐量面臨着巨大瓶頸。 對於同一時刻有大量並發讀操作和較少寫操作類型的應用系統來說,將數據庫拆分為主庫和從庫,主庫負責處理事務性的增刪改操作,從庫負責處理查詢操作,能夠有效的避免由數據更新導致的行鎖,使得整個系統的查詢性能得到極大的改善。

主從復制的結構,我們在第一節已經完成了,那么我們在項目中,如何通過java代碼來完成讀寫分離呢,如何在執行select的時候查詢從庫,而在執行insert、update、delete的時候,操作主庫呢?這個時候,我們就需要介紹一個新的技術 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>
在主庫中創建一個數據庫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;

我們本案例主要是演示一下讀寫分離操作,對於基本的增刪改查的業務操作,我們就不再去編寫了,我們可以直接導入一個簡單具有增刪改查的springBoot工程:

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:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.200.200: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.201: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:
allow-bean-definition-overriding: true
該配置項的目的,就是如果當前項目中存在同名的bean,后定義的bean會覆蓋先定義的。
