wordpress做下載型網(wǎng)站6騰訊廣告代理商加盟
目錄
相關知識:
1. 主從復制和讀寫分離
2. mysql 支持的復制類型
對比:
一. 主從復制
1. 原理和工作過程
工作過程:
注意:
中繼日志(Relay Log):
2. 一些理解問題
2.1 為什么要復制
2.2 誰復制誰
2.3 數(shù)據(jù)放在什么地方
3. 主從復制的搭建
① 主從服務器時間同步
② 主服務器的 mysql 配置
③從服務器的mysql配置
④ 測試驗證
4. 總結:
二. 讀寫分離
1. 相關知識
1.1 什么是讀寫分離
1.2?為什么要讀寫分離
1.3 什么時候要讀寫分離
2. 原理
3. MySQL讀寫分離方式
3.1 基于程序代碼內(nèi)部實現(xiàn)
3.2 基于中間代理層實現(xiàn)
4. 讀寫分離的搭建
① amoeba 服務器安裝java環(huán)境
② 安裝amoeba軟件
③ 配置 amoeba 讀寫分離
④ 客戶端測試:
相關知識:
1. 主從復制和讀寫分離
在實際的生產(chǎn)環(huán)境中,對數(shù)據(jù)庫的讀和寫都在同一個數(shù)據(jù)庫服務器中,是不能滿足實際需求的。無論是在安全性、高可用性還是高并發(fā)等各個方面都是完全不能滿足實際需求的。因此,通過主從復制的方式來同步數(shù)據(jù),再通過讀寫分離來提升數(shù)據(jù)庫的并發(fā)負載能力。有點類似于rsync,但是不同的是rsync是對磁盤文件做備份,而mysql主從復制是對數(shù)據(jù)庫中的數(shù)據(jù)、語句做備份。
2. mysql 支持的復制類型
① STATEMENT
基于語句的復制。在服務器上執(zhí)行sql語句,在從服務器上執(zhí)行同樣的語句,mysql默認采用基于語句的復制,執(zhí)行效率高。
② ROW
基于行的復制。把改變的內(nèi)容復制過去,而不是把命令在從服務器上執(zhí)行一遍。
③ MIXED
混合類型的復制。默認采用基于語句的復制,一旦發(fā)現(xiàn)基于語句無法精確復制時,就會采用基于行的復制。
對比:
STATEMENT:
- 傳輸效率高,減少延遲。
- 在從庫更新不存在的記錄時,語句賦值不會失敗。而行復制會導致失敗,從而更早發(fā)現(xiàn)主從之間的不一致。
- 設表里有一百萬條數(shù)據(jù),一條sql更新了所有表,基于語句的復制僅需要發(fā)送一條sql,而基于行的復制需要發(fā)送一百萬條更新記錄
row:
- 不需要執(zhí)行查詢計劃。
- 不知道執(zhí)行的到底是什么語句。
一. 主從復制
1. 原理和工作過程
主從復制基于主mysql服務器和從mysql服務器的三個線程和兩個日志展開進行的:
兩個日志:二進制日志(bin log)?、中繼日志(Relay log)
三個線程:dump線程、I/O線程、SQL線程
工作過程:
(1)Master 節(jié)點將數(shù)據(jù)的改變記錄成二進制日志(bin log),當Master上的數(shù)據(jù)發(fā)生改變時,則將其改變寫入二進制日志中。
(2)Slave節(jié)點會在一定時間間隔內(nèi)對 Master 的二進制日志進行探測其是否發(fā)生改變,如果發(fā)生改變,則開始一個I/O線程請求 Master的二進制事件。
(3)同時 Master 節(jié)點為每個I/O線程啟動一個dump線程,用于向其發(fā)送二進制事件,并保存至Slave節(jié)點本地的中繼日志(Relay log)中,Slave節(jié)點將啟動SQL線程從中繼日志中讀取二進制日志,在本地重放,即解析成 sql 語句逐一執(zhí)行,使得其數(shù)據(jù)和 Master節(jié)點的保持一致,最后I/O線程和SQL線程將進入睡眠狀態(tài),等待下一次被喚醒。
注意:
- 中繼日志通常會位于 OS 緩存中,所以中繼日志的開銷很小。
- 復制過程有一個很重要的限制,即復制在 Slave上是串行化的,也就是說 Master上的并行更新操作不能在 Slave上并行操作。
中繼日志(Relay Log):
在MySQL的主從復制架構中,中繼日志(Relay Log)扮演著至關重要的角色。當一個MySQL服務器充當從服務器時,它會從主服務器接收二進制日志(Binlog)事件,并將這些事件存儲在其自身的中繼日志中。中繼日志的主要功能是:
-
存儲主服務器的更改: 主服務器的二進制日志記錄了所有的數(shù)據(jù)變更事件,這些事件通過主從復制傳輸?shù)綇姆掌骱?#xff0c;被暫時存儲在中繼日志中。
-
異步處理: 從服務器不需要實時同步主服務器的所有更改,而是先將這些更改存放在中繼日志中,然后按照事件發(fā)生的順序依次執(zhí)行。
-
故障恢復和數(shù)據(jù)一致性: 如果從服務器在處理過程中發(fā)生中斷,重啟后可以從上次執(zhí)行完的位置繼續(xù)讀取并執(zhí)行中繼日志中的事件,從而保持與主服務器數(shù)據(jù)的一致性。
-
多級復制: 在復雜的多級復制架構中,從服務器也會將接收到的主服務器二進制日志事件轉存為自己的中繼日志,以便傳遞給下一級別的從服務器。
中繼日志文件通常位于從服務器的特定目錄下,并按照一定的命名規(guī)則(如主機名加時間戳)創(chuàng)建。MySQL的IO線程負責從主服務器讀取二進制日志事件并寫入中繼日志,SQL線程則負責讀取中繼日志并執(zhí)行這些事件以更新從服務器的數(shù)據(jù)。
優(yōu)點:
-
數(shù)據(jù)分布:通過復制將數(shù)據(jù)分布到不同地理位置
-
負載均衡:讀寫分離以及將讀負載到多臺從庫
-
備份:可作為實時備份
-
高可用性:利用主主復制實現(xiàn)高可用
2. 一些理解問題
2.1 為什么要復制
保證數(shù)據(jù)的完整性
2.2 誰復制誰
slave(從)?角色復制 master(主)角色的數(shù)據(jù)
2.3 數(shù)據(jù)放在什么地方
二進制文件 mysql-bin-000001--->記錄完整的sql,slave復制二進制文件到本地節(jié)點,保存為中繼日志文件方式,最后基于這個中繼日志進行恢復操作,將執(zhí)行的 sql 同步到自己的數(shù)據(jù)庫當中做中達到與 master 數(shù)據(jù)一致性
3. 主從復制的搭建
① 主從服務器時間同步
主服務器:
[root@master ~]#yum install ntp -y
[root@master ~]#vim /etc/ntp.confserver 127.127.10.0
fudge 127.127.10.0 stratum 8
[root@master ~]#service ntpd start
從服務器:
[root@slave1 ~]#yum install ntp ntpdate -y
[root@slave1 ~]#service ntpd start
#進行時間同步
[root@slave1 ~]#/usr/sbin/ntpdate 192.168.44.60#創(chuàng)建計劃任務
[root@slave1 ~]#crontab -e
*/30 * * * * /usr/sbin/ntpdate 192.168.44.60#查看計劃任務
[root@slave1 ~]#crontab -l
另一個從同理
② 主服務器的 mysql 配置
[root@master ~]#vim /etc/my.cnf[mysqld]
....
server-id = 1
log-bin=master-bin
binlog_format=MIXED
log-slave-updates=true
[root@master ~]#systemctl restart mysqld.service
mysql> grant replication slave on *.* to 'myslave'@'192.168.44.%' identified by '123';
#給從服務器授權mysql> flush privileges;
#刷新
mysql> show master status;
③從服務器的mysql配置
[root@slave1 ~]#vim /etc/my.cnf
[mysqld]
.....
server-id = 2
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery=1relay_log_recovery = 1
##當 slave 從庫宕機后,假如 relay-log 損壞了,導致一部分中繼日志沒有處理,則自動放棄所有未執(zhí)行的 relay-log,并且重新從 master 上獲取日志,這樣就保證了relay-log 的完整性。默認情況下該功能是關閉的,將 relay_log_recovery 的值設置為 1 時, 可在 slave 從庫上開啟該功能,建議開啟。
[root@slave1 ~]#mysql -uroot -p123#配置同步
mysql> change master to master_host='192.168.44.60',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=603;
mysql> start slave;
#查看slave狀態(tài)
mysql> show slave status\GSlave_IO_Running: Yes #負責與主機的io通信
Slave_SQL_Running: Yes #負責自己的slave mysql進程
另一臺同理,只要 server-id 不一樣即可
[root@slave2 ~]#vim /etc/my.cnf
[mysqld]
....
server-id = 3
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
relay_log_recovery=1#重啟服務
systemctl restart mysqldmysql -uroot -p123mysql> change master to master_host='192.168.44.60',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=603;mysql> start slave;mysql> show slave status\G
④ 測試驗證
先在主服務器上執(zhí)行操作:
在從服務器查看:
4. 總結:
主從復制核心部分 兩個日志 三個線程
mysql主從復制原理就是通過主數(shù)據(jù)庫變化記錄到二進制日志(bin1og)中,然后從庫讀取主二進制日志來去存放到本地最后 sql 線程 把數(shù)據(jù)導入到自己二進制(類似)中保持主從數(shù)據(jù)一致
4.1 MySQL 主從復制的幾個同步模式
(1)異步復制(Asynchronous replication)
MySQL默認的復制即是異步的,主庫在執(zhí)行完客戶端提交的事務后會立即將結果返給客戶端,并不關心從庫是否已經(jīng)接收并處理,這樣就會有一個問題,主如果crash掉了,此時主上已經(jīng)提交的事務可能并沒有傳到從上,如果此時,強行將從提升為主,可能導致新主上的數(shù)據(jù)不完整。
(2)全同步復制(Fully synchronous replication)
指當主庫執(zhí)行完一個事務,所有的從庫都執(zhí)行了該事務才返回給客戶端。因為需要等待所有從庫執(zhí)行完該事務才能返回,所以全同步復制的性能必然會收到嚴重的影響。
(3)半同步復制(Semisynchronous replication)
介于異步復制和全同步復制之間,主庫在執(zhí)行完客戶端提交的事務后不是立刻返回給客戶端,而是等待至少一個從庫接收到并寫到relay log中才返回給客戶端。相對于異步復制,半同步復制提高了數(shù)據(jù)的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步復制最好在低延時的網(wǎng)絡中使用。
二. 讀寫分離
1. 相關知識
1.1 什么是讀寫分離
讀寫分離,基本的原理是讓主數(shù)據(jù)庫處理事務性增、改、刪操作(INSERT、UPDATE、DELETE),而從數(shù)據(jù)庫處理SELECT查詢操作。數(shù)據(jù)庫復制被用來把事務性操作導致的變更同步到集群中的從數(shù)據(jù)庫。
1.2?為什么要讀寫分離
因為數(shù)據(jù)庫的“寫”(寫10000條數(shù)據(jù)可能要3分鐘)操作是比較耗時的。
但是數(shù)據(jù)庫的“讀”(讀10000條數(shù)據(jù)可能只要5秒鐘)。
所以讀寫分離,解決的是,數(shù)據(jù)庫的寫入,影響了查詢的效率。
1.3 什么時候要讀寫分離
數(shù)據(jù)庫不一定要讀寫分離,如果程序使用數(shù)據(jù)庫較多時,而更新少,查詢多的情況下會考慮使用。利用數(shù)據(jù)庫主從同步,再通過讀寫分離可以分擔數(shù)據(jù)庫壓力,提高性能。
2. 原理
讀寫分離就是只在主服務器上寫,只在從服務器上讀?;镜脑硎亲屩鲾?shù)據(jù)庫處理事務性操作,而從數(shù)據(jù)庫處理 select 查詢。數(shù)據(jù)庫復制被用來把主數(shù)據(jù)庫上事務性操作導致的變更同步到集群中的從數(shù)據(jù)庫。
3. MySQL讀寫分離方式
3.1 基于程序代碼內(nèi)部實現(xiàn)
在代碼中根據(jù) select、insert 進行路由分類,這類方法也是目前生產(chǎn)環(huán)境應用最廣泛的。
優(yōu)點是性能較好,因為在程序代碼中實現(xiàn),不需要增加額外的設備為硬件開支;缺點是需要開發(fā)人員來實現(xiàn),運維人員無從下手。
但是并不是所有的應用都適合在程序代碼中實現(xiàn)讀寫分離,像一些大型復雜的Java應用,如果在程序代碼中實現(xiàn)讀寫分離對代碼改動就較大。
3.2 基于中間代理層實現(xiàn)
代理一般位于客戶端和服務器之間,代理服務器接到客戶端請求后通過判斷后轉發(fā)到后端數(shù)據(jù)庫,有以下代表性程序。
(1)MySQL-Proxy。MySQL-Proxy 為 MySQL 開源項目,通過其自帶的 lua 腳本進行SQL 判斷。
(2)Atlas。是由奇虎360的Web平臺部基礎架構團隊開發(fā)維護的一個基于MySQL協(xié)議的數(shù)據(jù)中間層項目。它是在mysql-proxy 0.8.2版本的基礎上,對其進行了優(yōu)化,增加了一些新的功能特性。360內(nèi)部使用Atlas運行的mysql業(yè)務,每天承載的讀寫請求數(shù)達幾十億條。支持事物以及存儲過程。
(3)Amoeba。由陳思儒開發(fā),作者曾就職于阿里巴巴。該程序由Java語言進行開發(fā),阿里巴巴將其用于生產(chǎn)環(huán)境。但是它不支持事務和存儲過程。
(4)mycat?
Mycat是一款開源的、面向企業(yè)級的數(shù)據(jù)庫中間件,主要用于解決大并發(fā)、大數(shù)據(jù)量下的數(shù)據(jù)庫訪問問題,尤其適用于MySQL數(shù)據(jù)庫集群。Mycat作為分布式數(shù)據(jù)庫系統(tǒng),能夠實現(xiàn)MySQL數(shù)據(jù)庫的讀寫分離、分庫分表、數(shù)據(jù)路由等功能,從而提高數(shù)據(jù)庫的整體性能和擴展性。
4. 讀寫分離的搭建
① amoeba 服務器安裝java環(huán)境
因為 Amoeba 基于是 jdk1.5 開發(fā)的,所以官方推薦使用 jdk1.5 或 1.6 版本,高版本不建議使用。?
[root@amoba opt]#chmod +x jdk-6u14-linux-x64.bin
[root@amoba opt]#./jdk-6u14-linux-x64.bin
[root@amoba opt]#vim /etc/profileexport JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
② 安裝amoeba軟件
#創(chuàng)建amoeba 的解壓目錄
[root@amoba opt]#mkdir /usr/local/amoeba[root@amoba opt]#tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/#增加目錄權限
[root@amoba opt]#chmod -R 755 /usr/local/amoeba/
#開啟amoeba
[root@amoba opt]#/usr/local/amoeba/bin/amoeba
③ 配置 amoeba 讀寫分離
主服務器授權:
mysql> grant all on *.* to test@'192.168.44.%' identified by '123';
從服務器授權:
mysql> grant all on *.* to test@'192.168.44.%' identified by '123';
另一臺
amomeba 主機amoeba.xml 配置文件的修改:
vim amoeba.xml--30行--
<property name="user">amoeba</property>
--32行--
<property name="password">123</property>
--115行--
<property name="defaultPool">master</property>
--117-去掉注釋-
<property name="writePool">master</property>
<property name="readPool">slaves</property>
再進行另一個備份
?Aomeba 主機 dbServers.xml 配置文件的設置:
vim dbServers.xml--23行--注釋掉 作用:默認進入test庫 以防m(xù)ysql中沒有test庫時,會報錯
<!-- <property name="schema">test</property> -->
--26--修改
<property name="user">test</property>
--28-30--去掉注釋
<property name="password">123</property>
--45--修改,設置主服務器的名Master
<dbServer name="master" parent="abstractServer">
--48--修改,設置主服務器的地址
<property name="ipAddress">192.168.44.60</property>
--52--修改,設置從服務器的名slave1
<dbServer name="slave1" parent="abstractServer">
--55--修改,設置從服務器1的地址
<property name="ipAddress">192.168.44.50</property>
--58--復制上面6行粘貼,設置從服務器2的名slave2和地址
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.44.40</property>
--65行--修改
<dbServer name="slaves" virtual="true">
--71行--修改
<property name="poolNames">slave1,slave2</property>
啟動
/usr/local/amoeba/bin/amoeba start &
#后臺啟動Amoeba軟件,按ctrl+c 返回
查看端口
netstat -anpt | grep java或者
lsof -i:8066
④ 客戶端測試:
安裝mariadb?
啟動
連接數(shù)據(jù)庫
[root@amoba ~]#mysql -uamoeba -p123 -h192.168.44.30 -P8066
主服務器:
先在主從之間是開啟主從同步的,從里面也創(chuàng)建了class表
然后,我們停掉兩臺從服務器
然后在主服務器里面插入數(shù)據(jù)
mysql> insert into class values(1,'master','run');
從里面插入數(shù)據(jù)
然后我們?nèi)タ蛻舳瞬樵?/p>
然后開啟主從復制
問題:
① 主從同步復制原理
主從復制基于主mysql服務器和從mysql服務器的三個線程和兩個日志展開進行的:
兩個日志:二進制日志(bin log)?、中繼日志(Relay log)
三個線程:dump線程、I/O線程、SQL線程
工作過程:
(1)Master 節(jié)點將數(shù)據(jù)的改變記錄成二進制日志(bin log),當Master上的數(shù)據(jù)發(fā)生改變時,則將其改變寫入二進制日志中。
(2)Slave節(jié)點會在一定時間間隔內(nèi)對 Master 的二進制日志進行探測其是否發(fā)生改變,如果發(fā)生改變,則開始一個I/O線程請求 Master的二進制事件。
(3)同時 Master 節(jié)點為每個I/O線程啟動一個dump線程,用于向其發(fā)送二進制事件,并保存至Slave節(jié)點本地的中繼日志(Relay log)中,Slave節(jié)點將啟動SQL線程從中繼日志中讀取二進制日志,在本地重放,即解析成 sql 語句逐一執(zhí)行,使得其數(shù)據(jù)和 Master節(jié)點的保持一致,最后I/O線程和SQL線程將進入睡眠狀態(tài),等待下一次被喚醒。
② 讀寫分離使用什么方式
通過amoeba代理服務器,實現(xiàn)只在主服務器上寫,只在從服務器上讀;
主數(shù)據(jù)庫處理事務性查詢,從數(shù)據(jù)庫處理select 查詢;
數(shù)據(jù)庫復制被用來把事務查詢導致的變更同步的集群中的從數(shù)據(jù)庫
③ 如何查看主從同步狀態(tài)是否成功
在從服務器上內(nèi)輸入 show slave status\G 查看主從信息查看里面有IO線程的狀態(tài)信息,還有master服務器的IP地址、端口事務開始號。
當 Slave_IO_Running和Slave_SQL_Running都是YES時 ,表示主從同步狀態(tài)成功
④ 如果I/O不是yes,如何排查
首先排查網(wǎng)絡問題,使用ping 命令查看從服務器是否能與主服務器通信
再查看防火墻和核心防護是否關閉(增強功能)
接著查看從服務slave是否開啟
兩個從服務器的server-id 是否相同導致只能連接一臺
master_log_file master_log_pos的值跟master值是否一致
⑤ show slave status 可以看到哪些信息
IO線程的狀態(tài)信息
master服務器的IP地址、端口、事務開始的位置
最近一次的錯誤信息和錯誤位置
最近一次的I/O報錯信息和ID
最近一次的SQL報錯信息和id
⑥ 主從復制慢(延遲)會有哪些可能?怎么解決?
- 主服務器的負載過大,被多個睡眠或 僵尸線程占用,導致系統(tǒng)負載過大,從庫硬件比主庫差,導致復制延遲
- 主從復制單線程,如果主庫寫作并發(fā)太大,來不及傳送到從庫,就會到導致延遲
- 慢sql語句過多
- 網(wǎng)絡延遲
怎么解決:
(1)硬件方面
從庫配置更好的硬件,提升隨機寫的性能。比如原本是機械盤,可以考慮更換為ssd固態(tài)。升級核心數(shù)更強的cpu、加大內(nèi)存。避免使用虛擬云主機,使用物理主機
(2)網(wǎng)絡方面?
? 將從庫分布在相同局域網(wǎng)內(nèi)或網(wǎng)絡延遲較小的環(huán)境中。盡量避免跨機房,跨網(wǎng)域進行主從數(shù)據(jù)庫服務器的設置
(3)架構方面
在事務當中盡量對主庫讀寫,其他非事務中的讀在從庫。消除一部分延遲帶來的數(shù)據(jù)庫不一致。增加緩存降低一些從庫的負載。?
(4)mysqld服務配置方面?
該配置設置針對mysql主從復制性能優(yōu)化最大化,安全性并不高。如果從安全的角度上考慮的話,就要設置雙一設置
追求安全性的雙一設置:
innodb_flush_log_at_trx_commit=1
sync_binlog=1
追求性能化設置:
sync_binlog=0
innodb_flush_log_at_trx_commit=2
logs-slave-updates=0
增大 innodb_buffer_pool_size