標籤:mysql複製
1,為什麼需要mysql複製技術,有什麼用?
單台資料庫伺服器的能力總是有限的。根據專業人士的經驗,一台8核心32G配置的伺服器,承受50~200的並發串連請求,算是很好了。mysql複製是提升資料存放區層面能力的一種方式。
2,怎麼提升資料庫效能?
那麼提升資料庫效能有兩個途徑:1,提升硬體設定。2,增加伺服器數量。
對於1,性價比很低。這個屬於垂直擴充,專業名字叫scale up
對於2,就是叢集技術,屬於水平擴充,也叫scale out
叢集技術是一種把多台伺服器當做一台來使用的技術。應用程式層面與儲存層分離,不需要考慮儲存層的變化對應用程式層的影響。那資料庫可以做叢集嗎?
3,資料存放區層面的怎麼擴充?
其實我們公司目前的設計,是在應用程式層把不同的使用者的訪問請求定位到不同的資料庫伺服器。應用程式層面直接去找使用者對應的資料庫伺服器ip,建立串連進行訪問。一般來說,單個使用者有一定數量的終端裝置。每個裝置與通訊伺服器建立串連(通訊伺服器這裡可做叢集擴充),通訊伺服器與資料存放區層互動。
我們給每一個使用者建立一個資料庫,在這個資料庫下面給使用者擁有的每一個終端裝置,建立一張表。在資料庫的層面分流負載。
這個設計的問題:
我們的設計中,通訊伺服器與資料庫伺服器之間需要預先建立一定數量的串連(或者改為動態?)。
1,比如有一台通訊伺服器,一台mysql伺服器。通訊伺服器與資料庫預伺服器先建立30個串連。這是OK的。隨著訪問請求的增長,一般資料庫的承受能力先到上限,考慮增加資料庫的數量,分流負載。
2,一台通訊伺服器,多台mysql伺服器。通訊伺服器與每一個資料庫伺服器都建立30個串連。(通訊伺服器承受能力>資料庫的承受能力)。訪問請求繼續增長,通訊伺服器的承受能力也到了上限,考慮增加通訊伺服器數量。
3,多台通訊伺服器,多台mysql伺服器。每一個通訊伺服器與每一個資料庫伺服器建立30個串連。
這裡就要考慮mysql最多可以有多少個並發串連,效能會不會下降,下降多少?這裡可能是一個限制條件。比如3台通訊伺服器,每個資料庫就有3*30=90個串連。這個會不會有問題。
負載測試:
1,邏輯上,一台通訊伺服器,一台mysql伺服器。物理上,可以在一台機器上,也可以在兩台機器上。分兩種情況測試。觀察網路負載,cpu,記憶體,磁碟I/O的使用方式。得出這個架構可以承受的最大終端數。
2,同上
3,同上
這是題外話,先繼續吧。。。
4. mysql的複製技術
4.1 mysql複製的結構
其實通過mysql複製,只可以提升資料存放區層對於讀請求的響應能力,無法提升對於寫請求的響應能力。
結構:
1,一主一從
主----->從
2,一主多從
主----->從
|-->從
|-->從
主節點網路IO,磁碟IO的壓力看起來比較大
3,層級結構
主----->從----->從
|-->從 |-->從
主節點的複製工作量相對一主多從,要輕一些
主節點可讀可寫,從節點只能讀。
4.2 從節點多了產生的問題
從節點多了之後,應用程式對從節點的讀操作,也需要做負載平衡啊。
對於mysql這種有緩衝的應用,做負載平衡會又面臨一個快取命中的問題。
4.2.1 負載平衡與緩衝命中
mysql緩衝,是用來提高響應速度。因為記憶體的訪問速度遠遠大過磁碟。把一部分經常用到
的資料預先放入記憶體裡面,大部分的查詢只要在記憶體裡面讀取資料,那就不用每一次查詢都去讀磁碟的檔案,那太耗費時間了。比如100次的查詢操作,有90次在記憶體裡面讀資料,10次去磁碟讀資料,那快取命中率就是90%了。
畢竟記憶體的大小,相對於磁碟的大小還是比較小的,資料量一直也在增長。不可能說把磁碟裡的資料全部都緩衝到記憶體中,那樣命中率就100%了。記憶體空間畢竟有限,只能緩衝一定量的資料。如果這一定量的資料比較穩定,變動不是很大,那樣命中率就能高一點。所以多個從節點,各自有一些分工的話,各自應對某一類的查詢,就可以提高這個命中率。
出於這個考慮,根據sql語句進行分類,分配到各個從節點。
4.2.1.1 提高快取命中的方式:
分類有幾種方式:
1,模數
對sql語句做散列運算得出特徵值,用這個值對節點數模數,比如有三個節點,模數可能得到0,1,2。0,1,2分別對應著一個節點。這個sql查詢就被分配到這個模數結果對應的節點了。
計算式:sql語句特徵值/節點數 =0~2 ------> 0節點
|---> 1節點
|---> 2節點
缺點:
節點數一旦變化,如新加一個節點,或因為節點失效刪除一個節點,計算式“sql語句的特徵值/節點數” 所得到的結果都可能產生變化,sql的分配大範圍變化,所有節點上原來已經比較穩定的緩衝,需要一定時間才能重新穩定下來。這期間的整體響應效能就不太穩定了。
2,一致性hash
對於節點增刪引起的緩衝抖動,一致性hash可以把這個抖動限制在一個較小的範圍。
計算式:sql語句特徵值/(2^32)= 0 ~ 2^32-1
節點特徵值/(2^32)= 0 ~ 2^32-1
節點和sql語句都落在一個0 ~ 2^32-1的環上。
一個節點失效的話,影響範圍縮小到這個節點和逆時針方向上一個節點之間的sql語句。
缺點:節點分布不均,導致節點的承受的負載不均。
3,虛擬節點
真實節點虛擬成多個虛擬節點,均勻分布在0 ~ 2^32-1的環上。節點的負載更均勻。
ps: 數學是短板啊,死腦細胞。
公用緩衝memcached:
以上是在程式層面考慮,提高快取命中的方法。
另外有一種公用緩衝的方式:memcached, 具體不清楚,Crowdsourced Security Testing道有這樣一種方法吧。。
應用程式層面跟資料存放區層面,耦合度最好小一點,應用程式層就不需要太關心資料存放區層的變化,
不受太多影響,這裡引出下面一個話題:mysql讀寫分離工具。
4.3 mysql讀寫分離工具(有哪些?):
其實就是在應用程式層和資料存放區層之間增加一個中介層,它可以理解sql語句是讀還是寫,
然後把寫的操作分配到主節點,把讀的操作分配到從節點。就像一個sql語句的路由器。
4.4 那mysql複製可以解決一些什麼問題?
擴充和負載平衡
高可用
資料分布
資料備份
mysql升級測試,不可能在主節點去做測試吧。。
Crowdsourced Security Testing道有這樣一些概念,具體還講不太清楚。
4.5 mysql複製架構有什麼缺陷?
前面也提到過,從節點只能讀,不能寫,所以這個架構對於寫入的能力沒有提升的效果。
而且,主節點是單節點,如果主節點掛了,怎麼恢複?從節點倒沒什麼,掛了只是會影響訪問速度。
解決方案:
1,表分散到不同的節點(垂直分割)
2,當一個表的訪問量很大的時候,對錶做分區(水平分割)
怎麼分呢,是根據一個欄位來分,比如1~10000分到節點1,10001~20000分到節點2
自然也需要有一個全域管理者,知道哪些範圍的資料在哪個節點。
寫入操作涉及的節點越多,寫入速度會越快,因為寫入負載被分散
查詢操作涉及的節點越多,查詢就越慢,因為要把各個分散的資料集中讀取到記憶體,再
排序,返回結果,比較的麻煩。
這裡也不應該忘記sql語句的設計,不要太糟糕。。
簡單來說,mysql複製可以提供讀的擴充,而寫的擴充,需要分表,或分區。
最後,來說說mysql複製的工作原理吧。
4.6 mysql複製是怎麼實現的?
mysql複製需要主節點開啟二進位日誌。
二進位日誌(記錄所有寫入,更新,刪除等引起資料發生變動的操作):
記錄方式:
1,statment語句記錄
記錄sql語句,問題:now()函數等
2,raw行記錄
問題:導致記錄量增加
比如某一個更新操作涉及1000行資料,一個sql語句可以表達出來
但記錄行的話,就要增加1000條記錄。
3,mix混合方式記錄
綜合前兩種方式,盡量避免各自的問題。由mysql來判斷什麼時候
使用語句記錄,什麼時候使用行記錄。
複製是如何進行的:
從節點的IO線程會去主節點的3306連接埠,請求讀取二進位日誌事件對應的資料。
主節點這時啟動dump線程,從二進位日誌中讀取資料,讀取一條,發一條,發給
從節點的IO線程。
從節點收到資料後,寫入本地的中繼日誌。從節點的sql線程,從中繼日誌中讀取資料,
讀取一條,在本地執行一次。從節點一般關閉二進位日誌,避免額外的開銷。
二進位日誌中,會記錄產生這個事件的伺服器的id號。
複製架構裡面,每個節點有各自不同的id號。
要知道複製是非同步,因為主節點的資料寫入,如果要等待從節點複製完成,再返回,
那響應速度恐怕不太好。
問題:從節點的資料可能落後與主節點的資料。
從節點可以多個主節點嗎?
不行,只能有一個。
(MariaDB支援多主複製,但不是複製同一個資料庫,從不同主節點複製不同的資料庫)
雙主複製模型:
兩個節點,又是主節點,又是從節點。
問題:
1,自增長id,一個id為奇數,一個為偶數,id增長步進為2,可避免id衝突。
2,資料不同步,同一時間,同一條記錄被修改
年齡 工資
A 40, +1000
B <3000, -2
41歲,工資2800
A 41,3800
B 39,2800
造成資料不同步
雙主模型的作用:
高可用
讀操作負載平衡
寫操作則沒有起到均衡效果(因為每一個寫操作在兩邊都會發生,區別在於直接寫
還是通過複製寫)
本文出自 “古二娃” 部落格,請務必保留此出處http://guli3057.blog.51cto.com/6809117/1591354
mysql複製是怎麼一回事