天天看點

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

1.MySQL主從複制與讀寫分離

1.1主從複制與讀寫分離

mysql使用主從複制的原因大概由一下三點:

1、在業務複雜的系統中,有這麼一個情景,有一句sql語句需要鎖表,導緻暫時不能使用讀的服務,那麼就很影響運作中的業務,使用主從複制,讓主庫負責寫,從庫負責讀,這樣,即使主庫出現了鎖表的情景,通過讀從庫也可以保證業務的正常運作。

2、做資料的熱備

3、架構的擴充。業務量越來越大,I/O通路頻率過高,單機無法滿足,此時做多庫的存儲,降低磁盤I/O通路的頻率,提高單個機器的I/O性能。

mysql主從複制原理

1.2 主從複制的過程

在主從複制過程中涉及到總共3個線程,兩個日志

Master 二進制日志

SLAVE I/O線程

Master dump線程

SLAVE 中繼日志

SLAVE SQL線程

(1) Master節點将資料的改變記錄成二進制日志(bin log),當Master上的資料發生改變時,則将其改變寫入二進制日志中。

(2)Slave節點會在一定時間間隔内對Master的二進制日志進行探測其是否發生改變,如果發生改變,則開始一個I/o線程請求Master的二進制事件。

(3)同時Master 節點為每個I/o線程啟動一個dump線程,用于向其發送二進制事件,并儲存至slave節點本地的中繼日志(Relay log)中,Slave節點将啟動SQL線程從中繼日志中讀取二進制日志,在本地重放,即解析成sql語句逐一執行,使得其資料和Master節點的保持一緻,最後I/0線程和SQL線程将進入睡眠狀态,等待下一次被喚醒。

半同步模式:注意:5.7版本主多了一個ACK_collection線程接受從的ack确認資訊

1.3主從複制的同步模式

1.3.1 異步複制:

異步複制是mysql 預設的同步方式

在master為slave開通賬号密碼、ip授權之後,slave 可以從master進行資料同步,主要依賴的是master的binlog日志

slave會啟動兩個線程,IO Thread 和 SQL Thread

IO Thread 負責從master拉取binlog 日志,并寫入relay中繼日志

SQL Thread 負責将relay中繼日志中的變更進行重放,更新資料來達到跟master保持資料一緻的目的

這個過程中,slave通過IO線程拉取binlog,master無需關注是否有slave需要同步,隻做自己的事情,整個複制過程都是異步完成的,這個就是異步複制

異步複制的優勢是性能好,缺點是資料的安全性比較差

在某一刻主從之間的資料差異可能較大,主機挂掉之後從機接管,可能會丢失一部分資料。

1.3.2半同步複制

master更新操作寫入binlog之後會主動通知slave,slave接收到之後寫入relay log 即可應答,master隻要收到至少一個ack應答,則會送出事務

可以發現,相比較于異步複制,半同步複制需要依賴至少一個slave将binlog寫入relay log,在性能上有所降低,但是可以保證至少有一個從庫跟master的資料是一緻的,資料的安全性提高。

對于資料一緻性要求高的場景,可以采用半同步複制的同步政策,比如主庫挂掉時,準備接管的那一個從庫,對資料的一緻性要求很比較高。

半同步複制的優點是資料的安全性好,缺點是性能比異步複制稍低

1.3.3 全同步複制

全同步複制跟半同步複制的差別是,全同步複制必須收到所有從庫的ack,才會送出事務。

主庫的事務送出依賴于後面所有的從庫,這樣一來性能就會明顯得下降

除非是對所有從庫資料一緻性要求非常高的場景,否則我們一般不采用這種政策

全同步複制的資料一緻性最好,但是性能也是最差的

mysql主從同步的三種模式_吳小佳同學的部落格

2.實驗步驟

2.1主從複制配置

環境:centos7

mysql版本:5.7.37

mysql主節點:192.168.80.20

mysql從節點1:192.168.80.25

mysql從節點2:192.168.80.30

mysql主節點設定

1.ntp服務配置
[root@mysql_master ~]# yum install ntp -y······
[root@mysql_master ~]# vim /etc/ntp.conf--末尾添加--
server 127.0.0.1							#設定本地是時鐘源,注意修改網段,127.0.0.1是本地回環位址(127.網段中所有ip實際上都是本地回環位址)fudge 127.0.0.1 stratum 8	                #設定時間層級為8(限制在15内)--------------------------------------------------------------
2.mysql配置檔案
[root@mysql_master ~]# vim /etc/my.cnf[mysqld]
......
server-id = 1
log-bin=mysql-bin							#添加,主伺服器開啟二進制日志binlog_format = MIXED
log-slave-updates=true						#添加,允許slave從master複制資料時可以寫入到自己的二進制日志expire_logs_days = 7						#設定二進制日志檔案過期時間,預設值為0,表示logs不過期max_binlog_size = 500M						#設定二進制日志限制大小,如果超出給定值,日志就會發生滾動,預設值是1GB:wq
--------------------------------------------------------------
[root@mysql_master ~]# systemctl restart mysqld   #重新開機msyql服務,使配置生效[root@mysql_master ~]# mysql -uroot -p            #登入mysqlmysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.80.%' IDENTIFIED BY '123456';  #從服務授權mysql> FLUSH PRIVILEGES;

mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      603 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.01 sec)#File 列顯示日志名,Position 列顯示偏移量           

複制

mysql從節點1配置

1.ntp配置
[root@mysql_slave1 ~]# yum install ntp ntpdate -y[root@mysql_slave1 ~]# service ntpd start[root@mysql_slave1 ~]# /usr/sbin/ntpdate 192.168.80.20         #與主節點進行時間同步[root@mysql_slave1 ~]# crontab -e*/30 * * * * /usr/sbin/ntpdate 192.168.80.20
--------------------------------------------------------------
2.mysql配置
[root@mysql_slave1 ~]# vim /etc/my.cnfserver-id = 25								#修改,注意id與Master的不同,兩個Slave的id也要不同relay-log=relay-log-bin						#添加,開啟中繼日志,從主伺服器上同步日志檔案記錄到本地relay-log-index=slave-relay-bin.index		#添加,定義中繼日志檔案的位置和名稱,一般和relay-log在同一目錄relay_log_recovery = 1                      #選配項#當 slave 從庫當機後,假如 relay-log 損壞了,導緻一部分中繼日志沒有處理,則自動放棄所有未執行的 relay-log,并且重新從 master 上擷取日志,這樣就保證了 relay-log 的完整性。預設情況下該功能是關閉的,将 relay_log_recovery 的值設定為 1 時, 可在 slave 從庫上開啟該功能,建議開啟。:wq
--------------------------------------------------------------
[root@mysql_slave1 ~]# systemctl restart mysqld[root@mysql_slave1 ~]# mysql -uroot -pmysql> CHANGE master to master_host='192.168.80.20',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=603;           #日志名稱與偏移點應該與主status中的相同mysql> start slave;
mysql> show slave status\G                # 檢視從狀态//確定 IO 和 SQL 線程都是 Yes,代表同步正常。
Slave_IO_Running: Yes				#負責與主機的io通信Slave_SQL_Running: Yes				#負責自己的slave mysql程序#一般 Slave_IO_Running: No/CONNECTING 的可能性:1、網絡不通
2、my.cnf配置有問題
3、密碼、file檔案名、pos偏移量不對
4、防火牆沒有關閉           

複制

mysql從節點2配置需要修改server-id

實驗截圖

主節點配置

1.ntp服務相關配置

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

2.mysql配置檔案

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

[mysqld]下加入

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
mysql從節點配置:

1.ntp時間同步設定

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

2.mysql配置

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
主從複制效果驗證:
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

2.2 讀寫分離配置

環境:centos7

mysql版本:5.7.37

mysql主節點:192.168.80.20

mysql從節點1:192.168.80.25

mysql從節點2:192.168.80.30

Amoeba 伺服器:192.168.80.35 jdk1.6、Amoeba

Amoeba伺服器配置

實作準備jdk和amoeba包至opt目錄
1.配置java環境
[root@amoeba opt]# cd /opt[root@amoeba opt]# cp jdk-6u14-linux-x64.bin  /usr/local/[root@amoeba opt]# cd /usr/local/[root@amoeba opt]# chmod +x jdk-6u14-linux-x64[root@amoeba opt]# ./jdk-6u14-linux-x64.bin//按yes,按enter
[root@amoeba local]# mv jdk1.6.0_14/ /usr/local/jdk1.6[root@amoeba local]# vim /etc/profileexport JAVA_HOME=/usr/local/jdk1.6export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/libexport PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATHexport AMOEBA_HOME=/usr/local/amoebaexport PATH=$PATH:$AMOEBA_HOME/bin

[root@amoeba local]# source /etc/profile[root@amoeba local]# java -version2.配置Amoeba
[root@amoeba local]# cd /opt[root@amoeba opt]# mkdir /usr/local/amoeba[root@amoeba opt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/[root@amoeba opt]# chmod -R 755 /usr/local/amoeba/[root@amoeba opt]# /usr/local/amoeba/bin/amoeba##配置 Amoeba讀寫分離,兩個 Slave 讀負載均衡##先将一主兩從開放授權
grant all on *.* to test@'192.168.80.%' identified by '123.com';#再回到amoeba伺服器配置amoeba服務:[root@amoeba opt]# cd /usr/local/amoeba/conf/[root@amoeba opt]# cp amoeba.xml amoeba.xml.bak[root@amoeba opt]# vim amoeba.xml		--30行--
<property name="user">amoeba</property>
--32行-- 
<property name="password">123456</property>
--115行--
<property name="defaultPool">master</property>
--117-去掉注釋-
<property name="writePool">master</property>
<property name="readPool">slaves</property>

:wq
--------------------------------------------------------------
[root@amoeba opt]# cp dbServers.xml dbServers.xml.bak[root@amoeba opt]# vim dbServers.xml--23行--注釋掉  作用:預設進入test庫 以防mysql中沒有test庫時,會報錯
<!-- <property name="schema">test</property> -->
--26--修改
<property name="user">test</property>
--28-30--去掉注釋
<property name="password">123.com</property>
--45--修改,設定主伺服器的名Master
<dbServer name="master"  parent="abstractServer">
--48--修改,設定主伺服器的位址
<property name="ipAddress">192.168.80.10</property>
--52--修改,設定從伺服器的名slave1
<dbServer name="slave1"  parent="abstractServer">
--55--修改,設定從伺服器1的位址
<property name="ipAddress">192.168.80.11</property>
--58--複制上面6行粘貼,設定從伺服器2的名slave2和位址
<dbServer name="slave2"  parent="abstractServer">
<property name="ipAddress">192.168.80.12</property>
--65行--修改
<dbServer name="slaves" virtual="true">
--71行--修改
<property name="poolNames">slave1,slave2</property>

[root@amoeba opt]# /usr/local/amoeba/bin/amoeba start&    背景啟動amoeba	[root@amoeba opt]# netstat -anpt | grep java           

複制

實驗截圖

1.配置java環境

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

2.配置amoeba

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

先配置mysql一主兩從開放授權

grant all on *.* to test@'192.168.80.%' identified by '123.com';

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離
讀寫分離測試

主機通過Navicat連接配接資料庫

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

主伺服器上建立表

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

從1從2關閉主從複制

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

在slave1插入資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

在slave2插入資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

在master插入資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

Navicat檢視表資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

關閉表重新整理一次,在打開表test

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

插入一條資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

主檢視資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

從1檢視資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

從2檢視資料

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

隻有主能檢視到插入的資料。

從2打開主從複制

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

可以看到用戶端和主之前插入的資料了。

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

再次打開用戶端檢視,還是存在兩種表記錄的情況。

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離

主伺服器上還是隻有用戶端與主插入的資料。

Mysql-主從複制與讀寫分離1.MySQL主從複制與讀寫分離