mysql 硬负载_为啥单机MySQL又遭遇瓶颈?MySQL主从复制替你解决单机问题
成長是一棵樹,總是在你不知不覺的情況下快樂長大;成長是一株草,總是在你不知不覺的情況下長滿大地;成長是一朵花,總是在你不知不覺的情況下開滿山頭。
這不,隨著時(shí)間的遷移。項(xiàng)目網(wǎng)站的用戶量、數(shù)據(jù)量持續(xù)上升,普通模式下的單機(jī)MySQL即將面臨被請(qǐng)求壓力打垮的情景。老早就被急的像熱鍋上螞蟻一樣的產(chǎn)品經(jīng)理,把我給叫了過去,看著那誠懇的小眼神兒。心理甚是開心。
你說,早知道會(huì)遇到這樣的事兒,以前咋不見他好好說話,朝令夕改的需求,感覺就不要欠錢似的直接堆過來,今天終于輪到我 農(nóng)民翻身把歌唱 啦。
自己首先就是一副處變不驚的表情,抽根煙,喝口茶。對(duì)產(chǎn)品說到:“不急不急,一切盡在我們團(tuán)隊(duì)的預(yù)料之中”。 由我一一道來,這下咱真的是腿不酸了,腰板兒也硬朗了。好不容易,你撞我槍口上來了,還不得殺殺你的銳氣。 也讓你知道知道咋的手段。
隨著網(wǎng)站的發(fā)展,在面對(duì)高并發(fā)請(qǐng)求的時(shí)候。單機(jī)下面的MySQL肯定是會(huì)遇到性能的瓶頸。因?yàn)槟銌螜C(jī)無論是磁盤的存儲(chǔ)、I/O的開銷上都是會(huì)有資源上限。沒辦法支持網(wǎng)站后續(xù)的發(fā)展。畢竟雙拳難敵四手。正是因?yàn)檫@樣我們才會(huì)構(gòu)建大規(guī)模、高性能的應(yīng)用。基于“水平擴(kuò)展”的方式來滿足項(xiàng)目發(fā)展的需要。這也是搭建高可用、可擴(kuò)展性、災(zāi)難恢復(fù)、備份及數(shù)據(jù)倉庫等工作的基礎(chǔ)。
在有規(guī)模的網(wǎng)站中,程序員往往都是避免不了這類型的話題。
為什么使用MySQL主從復(fù)制?
1、自身不足:解決單機(jī)下的瓶頸問題
為什么隨著公司的發(fā)展,需要越來越多的人,而不應(yīng)該人數(shù)越少越好好嗎?那是因?yàn)楣驹桨l(fā)展業(yè)務(wù)會(huì)增多,相關(guān)的事情也會(huì)越來越多。如果都交給一個(gè)人,那必定精力是有限。根本不能完成每天的工作。
單機(jī)MySQL也是一樣。它的磁盤、內(nèi)存、I/O、CPU等資源都是有限制。
注:單機(jī)MySQL指在一臺(tái)物理服務(wù)器上安裝一臺(tái)MySQL,專門只提供數(shù)據(jù)庫的服務(wù)。單機(jī)多實(shí)例指在一臺(tái)物理服務(wù)器上可以安裝多臺(tái)MySQL實(shí)例
一般中、大型網(wǎng)站的數(shù)據(jù)量可能達(dá)到幾百GB、幾個(gè)TB的數(shù)據(jù),甚至是更高。而你單機(jī)下面的磁盤容量可能才是幾十個(gè)GB。它能夠支持?jǐn)?shù)據(jù)存儲(chǔ)的容量嗎?
網(wǎng)站項(xiàng)目規(guī)模過大,那必定你業(yè)務(wù)的請(qǐng)求量肯定是十分巨大的,在這么大的情況下面,少說也得億級(jí)的PV的用戶請(qǐng)求吧。這樣的條件下,你的I/O訪問的頻率過高,CPU切換忙都忙不過來,一直都是高負(fù)載的情況。它能搞的贏?
因?yàn)橄到y(tǒng)的軟件運(yùn)行是由CPU每隔一個(gè)時(shí)間片切換后才能執(zhí)行程序的。這樣服務(wù)器的壓力會(huì)異常的大,一直都高負(fù)荷運(yùn)行狀態(tài)。從而導(dǎo)致宕機(jī)。 同時(shí)你在這樣的條件下,每一個(gè)請(qǐng)求走到MySQL后,都需要給每一個(gè)請(qǐng)求分配一個(gè)線程去執(zhí)行該請(qǐng)求里面的SQL語句。那線程的資源開銷也是需要內(nèi)存的啊。就算你是單機(jī)的MySQL。那你的內(nèi)存也有上限,難道可以分配幾千個(gè)線程?
這不,葛優(yōu)大爺出演的電影《甲方乙方》也說道了,"地主家也沒有余糧啊"
并且,你磁盤I/O的讀寫也是需要時(shí)間的,請(qǐng)求越多,你磁盤讀寫機(jī)會(huì)也機(jī)會(huì)多,而從數(shù)據(jù)庫的數(shù)據(jù)是需要從磁盤里面讀取到內(nèi)存中,然后在響應(yīng)給客戶端的。那所有的請(qǐng)求都要做磁盤尋址。那這個(gè)消耗也是很大的。
磁盤獲取數(shù)據(jù)過程的時(shí)間:訪問時(shí)間+傳輸時(shí)間- 移動(dòng)磁頭到磁盤面上的正確位置(訪問時(shí)間)
- 等待磁盤旋轉(zhuǎn),使得所需要的數(shù)據(jù)在磁頭之下(訪問時(shí)間)
- 等待磁盤旋轉(zhuǎn)過去,所有需要的數(shù)據(jù)都被磁頭讀出(傳輸速度)
后面出一篇詳細(xì)的數(shù)據(jù)庫數(shù)據(jù)載入原理,這里大家先給一個(gè)總結(jié)
2、壓力分擔(dān):讓請(qǐng)求負(fù)載均衡給多臺(tái)數(shù)據(jù)庫
做了主從復(fù)制后最明顯的特點(diǎn)就是,把相關(guān)的讀寫請(qǐng)求分離。主庫針對(duì)寫請(qǐng)求,從庫針對(duì)讀請(qǐng)求,這樣能夠在業(yè)務(wù)上面把各個(gè)數(shù)據(jù)庫的職責(zé)劃分開。對(duì)后續(xù)的一切客戶端的請(qǐng)求,我們可以根據(jù)讀或者是寫直接交給對(duì)應(yīng)的數(shù)據(jù)庫。
一般項(xiàng)目絕大多數(shù)都是讀操作,通過MYSQL復(fù)制將讀操作分布到多個(gè)服務(wù)器上,從而實(shí)現(xiàn)對(duì)密集性應(yīng)用的優(yōu)化,通過Nginx簡單的代碼修改就能實(shí)現(xiàn)基本負(fù)載均衡。
對(duì)于小規(guī)模的網(wǎng)站,可以對(duì)機(jī)器名做硬編碼或使用DNS輪詢(將一個(gè)機(jī)器名指定到多個(gè)IP地址),當(dāng)然也可以選擇復(fù)雜的方法,采用LVS網(wǎng)絡(luò)的負(fù)載均衡來實(shí)現(xiàn)網(wǎng)絡(luò)的情求的分擔(dān)。
業(yè)務(wù)上針請(qǐng)求類型來劃分。在讀請(qǐng)求上,針對(duì)負(fù)載均衡實(shí)施到多個(gè)數(shù)據(jù)庫中,你說這個(gè)手段怎么樣? 要得不呢? 咱程序員也不是吃素的。嗓子干了,喝口水再來
3、數(shù)據(jù)備份與數(shù)據(jù)分布
對(duì)于數(shù)據(jù)備份。這應(yīng)當(dāng)是每個(gè)網(wǎng)站中都需要考慮的環(huán)節(jié),從而保證線上環(huán)境因?yàn)檎`刪而導(dǎo)致數(shù)據(jù)庫不能追蹤回來。但是這里的主從復(fù)制和我們常說的備份不一樣。
主從復(fù)制是通過把主庫的數(shù)據(jù)復(fù)制到從庫中,雖然是復(fù)制的過程,但也可以達(dá)到備份的效果,就像你的電影從D盤復(fù)制到E盤,就存在2份了,刪除一份,另一份還在。
對(duì)于主從復(fù)制的過程中,可以選擇在不同的地理位置來分布數(shù)據(jù),不同的數(shù)據(jù)中心內(nèi),即使不穩(wěn)定的網(wǎng)絡(luò)條件下,遠(yuǎn)程復(fù)制也是進(jìn)行的。這樣我們能夠讓數(shù)據(jù)庫有多個(gè)數(shù)據(jù)中心節(jié)點(diǎn),分布到各地。異地多活就是自在。
4、高可用和故障遷移
復(fù)制能夠幫助應(yīng)用程序避免MySQL單點(diǎn)失敗。一個(gè)包含復(fù)制的設(shè)計(jì)良好的故障切換系統(tǒng)能夠顯著的縮短宕機(jī)時(shí)間。這也就是主從復(fù)制為什么可以做到高可用的特點(diǎn)。
假如我的服務(wù)器因?yàn)闄C(jī)房停電了,這臺(tái)服務(wù)器就沒法使用了,但是它的數(shù)據(jù)都被Copy到另外的服務(wù)器中,這樣我可以直接從庫里直接選擇一臺(tái)服務(wù)器來替代沒法工作的服務(wù)器。從而繼續(xù)提供服務(wù)。
總結(jié)一下,備份的操作就是做為高可用的首選條件。
如何使用MySQL主從復(fù)制
前面經(jīng)過經(jīng)過各方面的問題以及主從復(fù)制做了詳細(xì)的解析,大家需要自己匯總下主從復(fù)制的特點(diǎn)與解決到了單機(jī)什么的問題,因?yàn)槊嬖囉袝r(shí)候就喜歡問一些你對(duì)于業(yè)務(wù)特點(diǎn)的理解和底層原理,那前面是問題的理解,這個(gè)實(shí)現(xiàn)原理怎么來辦? 放心,作為暖男的我,下面就給大家一 一道明。
主從復(fù)制原理解析
MySQL主從復(fù)制上的復(fù)制,總的來說,有三個(gè)過程來實(shí)現(xiàn)數(shù)據(jù)的復(fù)制操作。
- 在主從上把數(shù)據(jù)更新記錄的SQL語句記錄到二進(jìn)制日志(Binary Log)中,這些記錄被稱之為二進(jìn)制日志
注:更新記錄的SQL語句為與DDL和DML類型語句。DDL語句就是對(duì)數(shù)據(jù)庫、表層面的操作,如CREATE、ALTER、DROP;DML就是對(duì)表中數(shù)據(jù)的增刪改查,如SELECT、UPDATE、INSERT、DELETE操作的語句。但是在二進(jìn)制中SELECT不會(huì)記錄進(jìn)去。
- 從庫將主庫上的日志復(fù)制到自己的中繼日志中(Relay Log)中
- 從庫讀取中繼日志的中SQL記錄,將其數(shù)據(jù)重放到備庫上
以上就是大概的描述,下面來個(gè)圖進(jìn)行詳細(xì)過程梳理。
主從復(fù)制大家步驟
前面咱們了解到原理,現(xiàn)在就著手來搭建主從復(fù)制。
復(fù)制前的準(zhǔn)備工作:
主從數(shù)據(jù)庫版本最好一致主從數(shù)據(jù)庫內(nèi)數(shù)據(jù)保持一致在每臺(tái)服務(wù)器上都創(chuàng)建復(fù)制賬號(hào)配置主庫與從庫通知備庫連接到主庫并從主庫復(fù)制數(shù)據(jù)主數(shù)據(jù)庫:10.16.1.118 從數(shù)據(jù)庫:10.16.1.119創(chuàng)建用戶
MySQL會(huì)賦予一些特殊的權(quán)限給復(fù)制線程,在備庫運(yùn)行IO線程會(huì)建立一個(gè)到主庫的TCP/IP連接,這意味著必須在主庫創(chuàng)建一個(gè)用戶,并賦予其合適的權(quán)限,備庫I/O線程一該用戶名連接到主庫并讀取其二進(jìn)制文件。
在每臺(tái)服務(wù)器上都創(chuàng)建復(fù)制用戶賬號(hào),并授權(quán):用戶:test 密碼:test1
# 創(chuàng)建用戶create user 'test'@'10.16.1.118' identified by 'test1';# 授權(quán),只授予復(fù)制和客戶端訪問權(quán)限grant replication slave on *.* to 'test'@'10.16.1.119';#分配權(quán)限為什么每臺(tái)服務(wù)器都創(chuàng)建復(fù)制賬號(hào)呢?
用于監(jiān)控和管理復(fù)制賬號(hào)的權(quán)限,主庫賬號(hào)用于從庫連接并進(jìn)行日志復(fù)制使用,而從庫賬號(hào),用于當(dāng)主庫宕機(jī)時(shí),把從庫切換為主庫時(shí),自身所需的配置。
配置主庫與從庫
找到主數(shù)據(jù)庫的配置文件my.cnf,默認(rèn)在 /etc/my.cnf
vi /etc/my.cnf在[mysqld]部分插入
[mysqld]log-bin=mysql-bin #開啟二進(jìn)制日志server-id=1 #設(shè)置server-id,必須唯一配置說明
log-bin:設(shè)置二進(jìn)制日志文件的基本名;log-bin-index:設(shè)置二進(jìn)制日志索引文件名;binlog_format:控制二進(jìn)制日志格式,進(jìn)而控制了復(fù)制類型,三個(gè)可選值? -STATEMENT:語句復(fù)制,默認(rèn)選項(xiàng)? -ROW:行復(fù)制? -MIXED:混和復(fù)制server-id:服務(wù)器設(shè)置唯一ID,默認(rèn)為1,推薦取IP最后部分;sync-binlog:默認(rèn)為0,為保證不會(huì)丟失數(shù)據(jù),需設(shè)置為1,用于強(qiáng)制每次提交事務(wù)時(shí),同步二進(jìn)制日志到磁盤上。打開mysql會(huì)話shell
mysql -uroot -p查看master狀態(tài)
記錄二進(jìn)制文件名(mysql-bin.000013)和位置(8369):
mysql> show master status;+------------------+----------+--------------+------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+------------------+----------+--------------+------------------+-------------------+| mysql-bin.000013 | 8369 | | | |+------------------+----------+--------------+------------------+-------------------+1 row in set (0.00 sec)配置從庫Slave
找到從數(shù)據(jù)庫的配置文件my.cnf,默認(rèn)在/etc/my.cnf
vi /etc/my.cnf在[mysqld]部分插入
[mysqld]server-id=2 #設(shè)置server-id,必須唯一relay-log=/var/lib/mysql/mysql-relay-bin #指定中繼日志的位置和命名啟動(dòng)主從復(fù)制
重啟從mysql,打開從mysql會(huì)話,在從數(shù)據(jù)庫上執(zhí)行同步SQL語句(需要主服務(wù)器主機(jī)名,登陸憑據(jù),二進(jìn)制文件的名稱和位置):
mysql> CHANGE MASTER TO -> MASTER_HOST='10.16.1.118 ', -> MASTER_USER='test', -> MASTER_PASSWORD='test1', -> MASTER_LOG_FILE='mysql-bin.000013', -> MASTER_LOG_POS=8369;Query OK, 0 rows affected, 2 warnings (0.02 sec)啟動(dòng)slave同步進(jìn)程
mysql>start slave;查看slave狀態(tài)
mysql> show slave statusG*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 10.16.1.118 Master_User: test Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-relay-bin.000002 Read_Master_Log_Pos: 8369 Relay_Log_File:relay-bin.000002 Relay_Log_Pos: 640 Relay_Master_Log_File: mysql-bin.000013 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: ......當(dāng)Slave_IO_Running和Slave_SQL_Running都為YES的時(shí)候就表示主從同步設(shè)置成功了。
測試:
- 主數(shù)據(jù)庫
- 從服務(wù)器
注:數(shù)據(jù)庫復(fù)制同步之前,兩者的數(shù)據(jù)庫、表一定要同步,不然的話會(huì)導(dǎo)致同步之前,并沒有把相關(guān)更新操作執(zhí)行的SQL存儲(chǔ)到binlog日志,到時(shí)候就會(huì)導(dǎo)致數(shù)據(jù)不一致而報(bào)錯(cuò)。
架構(gòu)原理對(duì)我們的啟發(fā)
上面針對(duì)于原理上的解析,但是這個(gè)東西使用的模式設(shè)計(jì),我們從中可以的得到什么啟發(fā)?并運(yùn)用自己的業(yè)務(wù)系統(tǒng)中,這個(gè)是我們學(xué)習(xí)的另一個(gè)重點(diǎn)。作為暖男的我,豈能不幫助大家呢?
這種主從的復(fù)制架構(gòu)實(shí)現(xiàn)了日志獲取和數(shù)據(jù)重放的解耦,允許這兩個(gè)過程是異步進(jìn)行處理的,也就是l/O線程能夠獨(dú)立于SQL線程之外點(diǎn)的工作。
大家都知道異步的好處就是實(shí)現(xiàn)業(yè)務(wù)上的解耦,然后對(duì)業(yè)務(wù)進(jìn)行針對(duì)性的操作,從而來提升執(zhí)行的效率。這里面線程的職責(zé)分別是獲取與重放的單一職責(zé)處理。同時(shí)也方便后面系統(tǒng)的管理。
注:默認(rèn)的主從方式為異步模式,后面出一篇詳細(xì)的同步方式和復(fù)制常見問題解決。盡請(qǐng)期待
假如,如果說從庫只有一個(gè)工作I/O完成所有的復(fù)制工作,那么就會(huì)阻塞日志讀取,在來進(jìn)行重放,并且重放過程中,SQL語句執(zhí)行時(shí),還會(huì)進(jìn)行語法、詞法分析等。這樣就導(dǎo)致復(fù)制效率降低,從而引發(fā)延遲問題。所以這也是為什么在這里要涉及業(yè)務(wù)分析的原因。現(xiàn)在大家對(duì)你們的業(yè)務(wù)有優(yōu)化的考慮嗎? 歡迎留言討論
但這種架構(gòu)也限制了復(fù)制的過程,其中一點(diǎn)在主庫上并發(fā)運(yùn)行的操作在備庫只能串行化執(zhí)行。因?yàn)橹挥幸粋€(gè)SQL線程來重放中繼日志。在5.7以上有了多線程的模式。
總結(jié)一下:MySQL主從可以解決單機(jī)性能、存儲(chǔ)不足的問題,所以主從復(fù)制是通過擴(kuò)容的思路來進(jìn)行數(shù)據(jù)的分布,從而劃分請(qǐng)求來抵御過大的用戶請(qǐng)求。對(duì)于從庫實(shí)現(xiàn)的原理分為三大階段,分別是記錄日志、寫入到中繼日志、重放日志。對(duì)于架構(gòu)模式考慮上,也需要代入我們的業(yè)務(wù)場景中來做分析使用
大家如果有什么需求,也是可以留言的。如有感悟,歡迎關(guān)注@PHP智慧與能力
大冬天的,作為暖男的我,也希望能夠給大家溫暖下去。關(guān)注下,咳咳咳咳。如果需要欠缺實(shí)戰(zhàn)的同學(xué)可以購買專欄額。
總結(jié)
以上是生活随笔為你收集整理的mysql 硬负载_为啥单机MySQL又遭遇瓶颈?MySQL主从复制替你解决单机问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 捷信金融不还款会怎样
- 下一篇: opencv画框返回坐标 python_