MySQL主從復(fù)制與讀寫分離的使用示例
概述:
在企業(yè)應(yīng)用中,成熟的業(yè)務(wù)通常數(shù)據(jù)量都比較大。
單臺mysql在安全性、高可用性和高并發(fā)方面都無法滿足實際的需求。
配置多臺主從數(shù)據(jù)服務(wù)器以實現(xiàn)讀寫分離。
主從復(fù)制:解決高可用問題
讀寫分離:解決高并發(fā)的問題
一、主從復(fù)制原理
1、MySql支持從復(fù)制類型
基于語句的復(fù)制(statement)
在主服務(wù)器上執(zhí)行的sql語句,在從服務(wù)器執(zhí)行同樣的語句。mysql默認采用的方式。效率高。
基于行的復(fù)制 (ROW)
把改變的內(nèi)容復(fù)制過去。
基于混合類型復(fù)制 (MIXED)
默認采用基于語句的復(fù)制,一旦發(fā)現(xiàn)基于語句無法精確復(fù)制時,就會采用基于行的復(fù)制。
2、主從復(fù)制的原理
- 首先client端(tomcat)將數(shù)據(jù)寫入到master節(jié)點的數(shù)據(jù)庫中,master節(jié)點會通知存儲引擎提交事務(wù),同時會將數(shù)據(jù)以(基于行、基于SQL、基于混合)的方式保存在二進制文件中。
- slave節(jié)點會開啟 I/O 線程,用于監(jiān)聽master的二進制日志的更新,一旦發(fā)生更新內(nèi)容,則向master的dump線程發(fā)出同步請求。
- master的dump線程在接收到salve的I/O請求后,會讀取二進制日志文件中更新的數(shù)據(jù),并發(fā)送給slave的I/O線程。
- slave的I/O線程接收到數(shù)據(jù)后,會保存在slave節(jié)點的中繼日志中。
- 同時,slave節(jié)點中的SQL線程,會讀取中繼日志中的數(shù)據(jù),更新在本地的mysql數(shù)據(jù)庫中
- 最終,完成slave---> 復(fù)制master數(shù)據(jù),達到主從同步的效果。
中繼日志通常會位于OS緩存中,所以中繼日志的開銷很小。
復(fù)制過程有一個很重要的限制,即復(fù)制在slave上時串行化的,也就是說,master上的并行更新操作不能再slave上并行操作。
兩日志
- 二進制文件: 記錄數(shù)據(jù)庫變動的信息(語句、變動記錄)
- 中繼日志文件: 用于臨時存放二進制文件內(nèi)容。
三線程
- dump線程: ①監(jiān)聽I/O線程請求。②將二進制日志文件更新的數(shù)據(jù)發(fā)送給slave的I/O線程。
- I/O線程: ①監(jiān)聽master主機的二進制文件。②向master的dump線程發(fā)出同步請求
- SQL線程: 讀取中繼日志中的文件,更新到本機的數(shù)據(jù)庫。
3、mysql主從復(fù)制延遲
- master服務(wù)器高并發(fā),形成大量事務(wù)
- 網(wǎng)絡(luò)延遲主
- 從硬件設(shè)備導(dǎo)致(cpu主頻、內(nèi)存io、硬盤io)
- mysql默認使用異步復(fù)制。 可以優(yōu)化mysql參數(shù)。 比如增大innodb_buffer_pool_size,讓更多操作在mysql內(nèi)存中完成。 從庫還可以使用高性能主機 ,包括cpu強悍、內(nèi)存加大,避免使用虛擬云主機,使用物理主機,這樣升級了I/O方面性。 還可以將從庫使用SSD磁盤。 網(wǎng)絡(luò)優(yōu)化,。避免跨機房使用。
異步、同步、半同步復(fù)制:
異步復(fù)制
MySQL復(fù)制默認是異步復(fù)制,Master將事件寫入binlog,提交事務(wù),自身并不知道slave是否接收是否處理;
缺點:不能保證所有事務(wù)都被所有slave接收。
同步復(fù)制
Master提交事務(wù),直到事務(wù)在所有slave都已提交,才會返回客戶端事務(wù)執(zhí)行完畢信息;
缺點:完成一個事務(wù)可能造成延遲。
半同步復(fù)制
介于異步復(fù)制和全同步復(fù)制之間,主庫在執(zhí)行完客戶端提交的事務(wù)后不是立刻返回給客戶端,而是等待至少一個從庫接收到并寫到relay log中才返回給客戶端。
缺點:造成了一定程度的延遲。半同步復(fù)制最好在低延時的網(wǎng)絡(luò)中使用。
二、搭建主從復(fù)制:
實驗前提:
關(guān)防火墻和安全機制
1.時間同步:
1.主節(jié)點: yum -y install chrony #時間同步協(xié)議,下載資源包 vim /etc/chrony.conf server ntp.aliyun.com allow 192.168.88.0/24 30行添加 允許同步的網(wǎng)段 systemctl start chrony #重啟natp服務(wù) 2. 兩臺從節(jié)點: yum -y install chrony systemctl start chrony /usr/sbin/ntpdate 192.168.88.100 #時間同步指向主master服務(wù)器 crontab -e */30 * * * * /usr/sbin/ntpdate 192.168.88.100 #寫入周期計劃任務(wù),每30分鐘同步一次時間
2.master主服務(wù)設(shè)置:
vim /etc/my.cnf server-id=1 #server-id不能重復(fù) log-bin=master-bin #添加,主服務(wù)器開啟二進制文件 binlog_format = MIXED #指定二進制日志的格式為MIXED log-slave-updates=true #添加,允許從服務(wù)器更新二進制文件 systemctl restart mysqld #重啟mysqld服務(wù) mysql -uroot -p #登錄數(shù)據(jù)庫 grant replication slave on *.* to 'myslave'@'192.168.88.%' identified by '123456'; #允許192.168.88.0網(wǎng)段的所有主機使用myslave賬號和123456密碼登錄并使用庫和表 flush privileges; #將用戶和權(quán)限配置保存在內(nèi)存中 show master status; #查看master服務(wù)器當前正在執(zhí)行的二進制日志位置,和列偏移量
3.slave從服務(wù)器的配置:
兩臺從配置都一樣,注意,server-id #修改,id不能相同
vim /etc/my.cnf server-id=2 #修改,id不能與master相同,兩個slave也不能相同 relay-log=relay-log-bin #添加,開啟中繼日志,從服務(wù)器上同步master服務(wù)器日志文件到本地 relay-log-index=slave-relay-bin.index #添加,定義中繼日志文件的位置和名稱 relay_log_recovery=1 #選配項 #當 slave 從庫宕機后,假如 relay-log 損壞了,導(dǎo)致一部分中繼日志沒有處理,則自動放棄所有未執(zhí)行的 relay-log,并且重新從 master 上獲取日志,這樣就保證了relay-log 的完整性。默認情況下該功能是關(guān)閉的,將 relay_log_recovery 的值設(shè)置為 1 時, 可在 slave 從庫上開啟該功能,建議開啟 systemctl restart mysqld #啟動mysqld服務(wù)器 mysql -uroot -p123456 #登錄數(shù)據(jù)庫 change master to master_host='192.168.88.100',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603; #配置同步,注意master_log_file 和master_log_pos的值要與master查詢的一致。 start slave; #開啟同步,如有報錯執(zhí)行 reset slave; show slave status\G #查看slave狀態(tài)(查看I/O和SQL都為YES)
4.驗證:
主創(chuàng)建表,并寫入數(shù)據(jù):
從進行了復(fù)制:
三、讀寫分離原理
讀寫分離就是只在主服務(wù)器上寫,只在從服務(wù)器上讀,
基本的原理是讓主數(shù)據(jù)庫處理事務(wù)操作,而從數(shù)據(jù)庫處理select查詢,數(shù)據(jù)庫復(fù)制被用來把主數(shù)據(jù)庫上事務(wù)性操作導(dǎo)致的變更同步到集群中的從數(shù)據(jù)庫。
1、讀寫分離存在的意義
- 因為數(shù)據(jù)庫的 “寫” (寫10000條數(shù)據(jù)可能要3分鐘),操作是比較耗時的。
- 但是數(shù)據(jù)庫的 “讀” (讀10000條數(shù)據(jù)可能只要5秒中)。
- 所謂讀寫分離,解決的是,數(shù)據(jù)庫的寫入,影響了查詢的效率。
- 還可能因為鎖表的原因,進行讀寫分離。
2、什么時候要讀寫分離?
數(shù)據(jù)庫不一定要讀寫分離,如果程序使用數(shù)據(jù)庫較多時,而更新少,查詢多的情況下會考慮使用,利用數(shù)據(jù)庫主從同步,再通過讀寫分離可以分擔數(shù)據(jù)庫的壓力,提高性能。
3、主從復(fù)制與讀寫分離
在實際的生產(chǎn)環(huán)境中,對數(shù)據(jù)庫的讀和寫都在同一個數(shù)據(jù)庫服務(wù)器中,是不能滿足實際需求的。無論時在安全性,高可能性還是高并發(fā)等各個方面都不是完全不能滿足實際需求的。因此,通過主從復(fù)制的方式來同步數(shù)據(jù),再通過讀寫分離來提升數(shù)據(jù)庫的并發(fā)負載能力。優(yōu)點類似于rsync,但是不同的是rsync是對磁盤文件做備份,而mysql主從復(fù)制時對數(shù)據(jù)庫中的數(shù)據(jù)、語句做備份。
4、MySql讀寫分離類型
4.1 基于程序代碼內(nèi)部實現(xiàn)
在代碼中根據(jù)select、insert進行路由分類, 這類方法也是目前生產(chǎn)環(huán)境應(yīng)用最廣泛的。優(yōu)點:性能較好,因為在程序代碼中實現(xiàn),不需要增加額外的設(shè)備為硬件開支。缺點:是需要開發(fā)人員來實現(xiàn),運維人員無從下手。但是并不是所有的應(yīng)用都適合在程序代碼中實現(xiàn)讀寫分離,像一些大型的java應(yīng)用,如果在程序代碼中實現(xiàn)讀寫分離對代碼改動就較大。
4.2 基于中間代理層實現(xiàn)
代理一般位于客戶端和服務(wù)器之間,代理服務(wù)器接收到客戶端請求后通過判斷后轉(zhuǎn)發(fā)到后端數(shù)據(jù)庫,有以下代表程序。
1、MySql-Proxy 、MySql-Proxy為MySQL開源項目,通過其自帶的lua腳本進行判斷。
2、Atlas 是由奇虎360的web平臺部基礎(chǔ)架構(gòu)團隊開發(fā)維護的一個基于mysql協(xié)議的數(shù)據(jù)中間層項目,它是在mysql-proxy0.8.2版本的基礎(chǔ)上。對于進行了優(yōu)化,增加了一些新的功能特性,360內(nèi)部使用atlas運行mysql業(yè)務(wù),每條承受的讀寫請求數(shù)達幾十億條,支持事務(wù)以及存儲過程。
3、Amoeba。 由陳思儒開發(fā),作者曾就職于阿里巴巴,該程序由java語言進行開發(fā),阿里巴巴將其應(yīng)用于生產(chǎn)環(huán)境,但它不支持事務(wù)和存儲過程。
Amoeba:是一個以mysql為底層的數(shù)據(jù)存儲,并對應(yīng)提供mysql協(xié)議接口的proxy(代理),外號變形蟲。
- 讀取請求發(fā)送給從服務(wù)器是采用輪詢調(diào)度算法。
- amoeba使用的java語言編寫,配置文件為xml
- amoeba主要負責對外的一個代理ip
- 訪問這個ip時,發(fā)送的請求為“寫”請求,則會轉(zhuǎn)給主服務(wù)器。
- 當發(fā)送的請求為“讀”時,會通過調(diào)度轉(zhuǎn)發(fā)給從服務(wù)器,使用輪詢算法,輪流分配給兩臺從服務(wù)器。
- amoeba可以視為調(diào)度器,如果主服務(wù)器掛掉(單點故障),則會有HMA解決這個問題。
四、讀寫分離實驗
做讀寫分離必須要做好主從復(fù)制的的環(huán)境,因為讀寫分離是基于主從復(fù)制的基礎(chǔ)上去執(zhí)行的架構(gòu)。
實驗環(huán)境:
主服務(wù)器:192.168.88.100
從服務(wù)器1:192.168.88.101
從服務(wù)器2:192.168.88.103
Amoeba 服務(wù)器:192.168.88.104
因為前面的主服務(wù)器和兩臺從服務(wù)器在前面主從復(fù)制的時候,已經(jīng)部署好了,現(xiàn)在進行部署Amoeba代理服務(wù)器。
1.JDK環(huán)境安裝:
Amoeba服務(wù)時基于jdk1.5開發(fā)的,所有要使用jdk1.5或jdk1.6的版本,不建議使用高版本。
cp jdk-6u14-linux-x64.bin /usr/local #將jdk安裝包復(fù)制到/usr/local目錄下 cd /usr/local/ #進入local目錄 chmod +x jdk-6u14-linux-x64.bin #給安裝包執(zhí)行文件 ./jdk-6u14-linux-64.bin #安裝jdk(按空格到最后一行,輸入yes按回車) mv jdk1.6.0_14 jdk1.6 #安裝好之后在本地目錄下生成jdk1.6.0_14目錄,將其該名,方便后續(xù)操作 vim /etc/profile #編輯全局配置文件 export JAVA_HOME=/usr/local/jdk1.6 #輸出定義java的工作目錄 export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib #輸出指定的java類文件 export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin #將java加入工作環(huán)境 export AMOEBA_HOME=/usr/local/amoeba #輸出定義的amoeba工作目錄 export PATH=$PATH:$AMOEBA_HOME/bin #加入路徑環(huán)境變量 source /etc/profile #執(zhí)行群居配置文件 java -version #查看java版本信息
2.安裝 Amoeba軟件:
mkdir /usr/local/amoeba #創(chuàng)建amoeba的安裝目錄 tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba #將amoeba的安裝包解壓到/usr/local/amoeba目錄中 chmod -R 775 /usr/local/amoeba #給amoeba目錄所有的權(quán)限 /usr/local/amoeba/bin/amoeba #開啟amoeba(如果顯示amoeba start |stop,則說明完成)
3. 三臺mysql主從服務(wù)器設(shè)置權(quán)限:
先在Master、Slave1、Slave2 的mysql上開放權(quán)限給 Amoeba 訪問
grant all on *.* to 'amoeba-wzw'@'192.168.88.%' identified by '123123';
4. 配置amoeba服務(wù):
vim /usr/local/amoeba/conf/amoeba.xml #修改amoeba配置文件 --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> vim /usr/local/amoeba/conf/dbServers.xml #修改數(shù)據(jù)庫配置文件 --23行--注釋掉 作用:默認進入test庫 以防m(xù)ysql中沒有test庫時,會報錯 <!-- <property name="schema">test</property> --> --26--修改 <property name="user">amoeba-wzw</property> --28-30--去掉注釋 <property name="password">123123</property> --45--修改,設(shè)置主服務(wù)器的名Master <dbServer name="master" parent="abstractServer"> --48--修改,設(shè)置主服務(wù)器的地址 <property name="ipAddress">192.168.88.101</property> --52--修改,設(shè)置從服務(wù)器的名slave1 <dbServer name="slave1" parent="abstractServer"> --55--修改,設(shè)置從服務(wù)器1的地址 <property name="ipAddress">192.168.88.103</property> --58--復(fù)制上面6行粘貼,設(shè)置從服務(wù)器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> /usr/local/amoeba/bin/amoeba start& #啟動Amoeba軟件,按ctrl+c 返回 netstat -anpt | grep java #查看8066端口是否開啟,默認端口為TCP 8066
5.測試:
讀節(jié)點關(guān)閉slave
在主服務(wù)器上寫入一條111數(shù)據(jù):
到此這篇關(guān)于MySQL主從復(fù)制與讀寫分離的使用示例的文章就介紹到這了,更多相關(guān)MySQL主從復(fù)制與讀寫分離內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL中的GROUP_CONCAT()函數(shù)詳解與實戰(zhàn)應(yīng)用小結(jié)(示例詳解)
本文介紹了MySQL中的GROUP_CONCAT()函數(shù),詳細解釋了其基本語法、應(yīng)用示例以及ORDERBY和SEPARATOR參數(shù)的使用方法,此外,還提到了該函數(shù)的性能限制和注意事項,感興趣的朋友一起看看吧2025-02-02Mysql 本地計算機無法啟動 mysql 服務(wù) 錯誤 1067:進程意外終止。
初學(xué)php接觸mysql,遇到一些問題,卸載重裝后,無法啟動mysql服務(wù),網(wǎng)絡(luò)上有很多種說法,我這里將我解決這個問題的辦法提出2009-12-12mysql 主從數(shù)據(jù)不一致,提示: Slave_SQL_Running: No 的解決方法
這篇文章主要介紹了mysql 主從數(shù)據(jù)不一致,提示: Slave_SQL_Running: No 的解決方法,總結(jié)分析了MySQL主從數(shù)據(jù)不一致的原因與常見處理技巧,需要的朋友可以參考下2020-02-02阿里云ECS centos6.8下安裝配置MySql5.7的教程
阿里云默認yum命令下的MySQL是5.17****,安裝mysql5.7之前先卸載以前的版本。下面通過本文給大家介紹阿里云ECS centos6.8下安裝配置MySql5.7的教程,需要的的朋友參考下吧2017-07-07快速解決MySQL服務(wù)無法啟動顯示:系統(tǒng)出錯,發(fā)生系統(tǒng)錯誤1067, 進程意外終止的兩種方法
本人因為phpstudy的MySQL數(shù)據(jù)庫與我的電腦上的MySQL數(shù)據(jù)庫發(fā)生沖突,當我將MySQL服務(wù)器的服務(wù)名從MySQL改為MySQL5后,啟動MySQL5服務(wù)后就報錯:系統(tǒng)出錯, 發(fā)生系統(tǒng)錯誤 1067, 進程意外終止,現(xiàn)在將這個解決方法分享給大家,需要的朋友可以參考下2024-06-06