摘要:負載均衡器的作用是將請求的連接路由到最空閑的可用服務器上。負載均衡有五個常見目的可擴展性。靈活的負載均衡方案能夠大幅提高服務的可用性。連接池和長連接可能會阻礙負載均衡器分發(fā)連接請求。
負載均衡的基本思路很簡單:
在一個服務器集群中盡可能地的平均負載量。
基于這個思路,我們通常的做法是在服務器前端設置一個負載均衡器。負載均衡器的作用是將請求的連接路由到最空閑的可用服務器上。如圖 1,顯示了一個大型網(wǎng)站負載均衡設置。其中一個負責 HTTP 流量,另一個用于 MySQL 訪問。
負載均衡有五個常見目的:
可擴展性。負載均衡對某些擴展很有幫助,比如讀寫分離時從備庫讀數(shù)據(jù)。
高效性。負載均衡因為能夠控制請求被路由到何處,因此有助于更有效的使用資源。
可用性。靈活的負載均衡方案能夠大幅提高服務的可用性。
透明性??蛻舳藷o需知道是否存在負載均衡器,也不需要關系在負載均衡器的背后有多少機器。呈現(xiàn)給客戶端看到的就是一個透明的服務器。
一致性。如果應用是有狀態(tài)的(數(shù)據(jù)庫事務、網(wǎng)站會話等),那么負載均衡器就可以將相關的查詢指向同一個服務器,以防止狀態(tài)丟失。
而對于負載均衡的實現(xiàn),一般有兩種方式:直接連接和引入中間件。
1 直接連接有些人認為負載均衡就是配置在應用和 MySQL 服務器直接東西,但實際上這并不是唯一的負載均衡方法。接下來我們就討論一下常見的應用直連的方法,及其相關注意事項。
1.1 復制的讀寫分離此種方式下,容易出現(xiàn)一個最大的問題:臟數(shù)據(jù)。一個典型的例子是,當用戶評論了一篇博文,然后重新加載頁面,卻沒有看到新增的評論。
當然,我們也不能因為臟數(shù)據(jù)的問題,就將讀寫分離棄之不用。實際上,對于很多應用,可能對臟數(shù)據(jù)的容忍度比較高,此時就可以大膽的引入此種方式。
那么對于臟數(shù)據(jù)的容忍度比較低的應用,如何進行讀寫分離呢?接下來,我們對讀寫分離再進一步區(qū)分,相信你總能找到適合自己的一款策略。
1) 基于查詢分離
如果應用只有少數(shù)數(shù)據(jù)不能容忍臟數(shù)據(jù),我們可以將所有不能容忍臟數(shù)據(jù)的讀和寫都分配到 master 上。其它的讀查詢分配的 slave 上。該策略很容易實現(xiàn),但如果容忍臟數(shù)據(jù)的查詢比較少,很可能會出現(xiàn)不能有效使用備庫的情況。
2) 基于臟數(shù)據(jù)分離
這是對基于查詢分離策略的小改進。需要做一些額外的工作,比如讓應用檢查復制延遲,以確定備庫數(shù)據(jù)是否最新。許多報表類應用都可以使用這個策略:只需要晚上加載的數(shù)據(jù)復制到備庫接口,并不關心是不是完全跟上了主庫。
3) 基于會話分離
這個策略比臟數(shù)據(jù)分離策略更深入 一些。它是判斷用戶是否修改了數(shù)據(jù),用戶不需要看到其他用戶的最新數(shù)據(jù),只需要看到自己的更新。
具體可以在會話層設置一個標記位,表明用戶是否做了更新,用戶一旦做了更新,就將該用戶的查詢在一段時間內(nèi)指向主庫。
這種策略在簡單和有效性之間做了很好的妥協(xié),是一種較為推薦的策略。
當然,如果你的想法夠多,可以把基于會話的分離策略和復制延遲監(jiān)控策略結合起來。如果用戶在 10 秒前更新了數(shù)據(jù),而所有備庫延遲在 5 秒內(nèi),就可以大膽的從備庫中讀取數(shù)據(jù)。要注意的是,記得為整個會話選擇同個備庫,否則一旦多個備庫的延遲不一致,就會給用戶造成困擾。
4) 基于全局版本 / 會話分離
通過記錄主庫日志坐標和備庫已復制的坐標對比,確認備庫是否更新數(shù)據(jù)。當應用指向寫操作時,在提交事務后,執(zhí)行一次 SHOW MASTER STATUS 操作,然后將主庫日志坐標存儲在緩存中,作為被修改對象或者會話的版本號。當應用連接到備庫時,執(zhí)行 SHOW SLAVE STATUS,并將備庫上的坐標和緩存中的版本號對比。如果備庫比主庫記錄點更新,就表明備庫已更新對應數(shù)據(jù),可放心的使用。
實際上,很多讀寫分離策略都需要監(jiān)控復制延遲來決定讀查詢的分配。不過要注意的是,SHOW SLAVE STATUS 得到的 Seconds_behind_master 列的值并不能精確的表示延遲。我們可以使用 Percona Toolkit 中的 pt-heartbeat 工具更好的監(jiān)控延遲。
1.2 修改 DNS 名對于一些比較簡單的應用,可以為不同目的創(chuàng)建 DNS。最簡單的方法是只讀服務器擁有一個 DNS 名(read.mysql-db.com),給負責寫操作的服務器起另外一個 DNS 名(write.mysql-db.com)。如果備庫能夠跟得上主庫,就把只讀 DNS 名指向到備庫,否則,就指向到主庫。
這種策略非常容易實現(xiàn),但有個很大的問題是:無法完全控制 DNS。
修改 DNS 并不是立刻生效的,也不是原子性的。將 DNS 的變化傳遞到整個網(wǎng)絡或者網(wǎng)絡間傳播都需要比較長的時間。
DNS 數(shù)據(jù)會在各個地方緩存下,它的過期時間是建議性質,而非強制的。
可能需要應用或服務器重啟才能使修改后的 DNS 完全生效。
這種策略較為危險,即使可以通過修改 /etc/hosts 文件來避免 DNS 無法完全控制的問題,但仍不失理想策略。
1.3 轉移 IP 地址通過在服務器間轉移虛擬地址,來實現(xiàn)負載均衡。是不是感覺和修改 DNS 很像?但實際上完全是兩碼事。轉移 IP 地址允許 DNS 名保持不變,我們可以通過 ARP 命令(不了解 ARP,看這里)強制使 IP 地址的更改快速而且原子性的通知到局域網(wǎng)絡上。
一個比較方便的技術是為每個物理服務器分配一個固定的 IP 地址。該 IP 地址固定在服務器上,不再改變。然后可以為每個邏輯上的 “服務”(可以理解為容器)使用一個虛擬 IP 地址。
這樣,IP 就能夠很方便的在服務器間轉移,無需重新配置應用,實現(xiàn)也更加容易。
2 引入中間件上面的策略都是假定應用是和 MySQL 服務器之間連接的,但是許多負載均衡都會引入一個中間件,作為網(wǎng)絡通信的代理。它一邊接受所有的通信,另一邊將這些請求分發(fā)的指定服務器上,并將執(zhí)行結果發(fā)送回請求機器。圖 2 展示了此種架構。
現(xiàn)在有許多負載均衡硬件和軟件,但很少有專門為 MySQL 服務器設計的。Web 服務器通常更需要負載均衡,因此許多多用途的負載均衡設備都會支持 HTTP,而對其他用途則只有一些很少的基本特性。
MySQL 連接只是正常的 TCP/IP 連接,所以可以在 MySQL 上使用多用途負載均衡器。但由于缺少 MySQL 專有的特性,因此會多一些限制:
分發(fā)請求是可能無法做到很好的負載均衡。
對 MySQL 會話支持不足,可能不知道如何把所有從單個 HTTP 會話發(fā)送的連接請求 “固定” 到一個 MySQL 服務器上。
連接池和長連接可能會阻礙負載均衡器分發(fā)連接請求。
不能很好的對 MySQL 服務器做健康和負載檢查。
2.2 負載均衡算法有很多算法用來決定哪個服務器接受下一個連接。每個廠商都有各自不同的算法,有以下常用方法:
隨機分配。從可用的服務器池中隨機選擇一個服務器來處理請求。
輪詢。以循環(huán)順序發(fā)送請求到服務器,例如:A、B、C、A、B、C。
哈希。通過連接的源 IP 地址進行哈希,將其映射到池中的同一個服務器上。
最快響應。將連接分配給能夠最快處理請求的服務器上。
最少連接數(shù)。將連接分配給擁有最少活躍連接的服務器上。
權重。根據(jù)機器的性能等條件,給不同機器配置不同的權重,以便讓高性能的機器能處理更多的連接。
上述各種方法沒有最好,只有最適合的,這取決于具體的工作負載。
另外,我們只描述了即時處理的算法。但有時候使用排隊算法可能會更有效。例如,一個算法可能只維護給定的數(shù)據(jù)庫服務器并發(fā)數(shù)量,同一時刻只允許不超過 N 個活躍事務。如果有太多的活躍事務,就將新的請求放到一個隊列里,然后讓可用服務器列表來處理。
2.3 一主多備間的負載均衡最常見的復制結構就是一個主庫加多個備庫。這種架構的擴展性較差,但我們可以通過一些方法結合負載均衡來獲得更好的效果。
功能分區(qū)。對于廠家的功能包括報表、分析、數(shù)據(jù)倉庫以及全文索引,配置一個或一組備庫來擴展單個功能的容量。
保證備庫跟上主庫。備庫存在的問題就是臟數(shù)據(jù)。對于此,我們可以使用函數(shù) MASTER_POS_WAIT() 阻塞主庫的操作,直到備庫趕上了設置的主庫同步點。另外,我們還可以使用復制心跳來檢查延遲情況。
我們不能也不應該在應用的開始就就想著把架構做成阿里那樣的架構。最好的方式是實現(xiàn)應用當前所明確需要的,并為可能的快速增長做好預先規(guī)劃。
另外,為可擴展性制定一個數(shù)字目標是很有意義的,就像我們?yōu)樾阅苤贫艘粋€精確目標,滿足 10K 或 100K 并發(fā)一樣。這樣可以通過相關理論避免諸如序列化或交互操作的開銷問題帶入到我們的應用中。
在 MySQL 擴展策略方面,典型的的應用在增長到非常龐大時,通常先從單個服務器轉移到向外擴展的擁有備庫的架構,再到數(shù)據(jù)分片或按功能分區(qū)。這里要注意的是,我們不提倡諸如 “盡早分片,盡量分片” 的建議。實際上,分片很復雜,而且成本很高,最主要的是很多應用可能根本不需要。與其花大成本去分片,還不如先去看看新的硬件和新版本的 MySQL 有哪些變化,也許這些新變化會給你帶來驚喜。
總結直接連接重 "分離",均衡器和算法有局限。
為擴展性量化指標。
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://systransis.cn/yun/74287.html
摘要:負載均衡器的作用是將請求的連接路由到最空閑的可用服務器上。負載均衡有五個常見目的可擴展性。靈活的負載均衡方案能夠大幅提高服務的可用性。連接池和長連接可能會阻礙負載均衡器分發(fā)連接請求。 負載均衡的基本思路很簡單: 在一個服務器集群中盡可能地的平均負載量。 基于這個思路,我們通常的做法是在服務器前端設置一個負載均衡器。負載均衡器的作用是將請求的連接路由到最空閑的可用服務器上。如圖 1,顯示...
摘要:均衡負載多臺服務器執(zhí)行程序,將大量請求分攤給多臺服務器無論如何,一臺服務器的進程是有限的,我們不可能無限制的把一臺服務器的加到個,把內(nèi)存加到,則是不可能的。 在生產(chǎn)環(huán)境中,一個網(wǎng)站或服務端應用出現(xiàn)響應遲緩的時候,就應該考慮是否由于用戶量太多,導致服務器難以處理的情況,并應該考慮花錢來解決這個問題。當然,這里首先會想到廉價的解決方式,比如通過調整服務器配置,優(yōu)化代碼性能等,但這些方式技術...
摘要:均衡負載多臺服務器執(zhí)行程序,將大量請求分攤給多臺服務器無論如何,一臺服務器的進程是有限的,我們不可能無限制的把一臺服務器的加到個,把內(nèi)存加到,則是不可能的。 在生產(chǎn)環(huán)境中,一個網(wǎng)站或服務端應用出現(xiàn)響應遲緩的時候,就應該考慮是否由于用戶量太多,導致服務器難以處理的情況,并應該考慮花錢來解決這個問題。當然,這里首先會想到廉價的解決方式,比如通過調整服務器配置,優(yōu)化代碼性能等,但這些方式技術...
閱讀 3155·2021-10-08 10:04
閱讀 1098·2021-09-30 09:48
閱讀 3466·2021-09-22 10:53
閱讀 1684·2021-09-10 11:22
閱讀 1697·2021-09-06 15:00
閱讀 2156·2019-08-30 15:56
閱讀 719·2019-08-30 15:53
閱讀 2288·2019-08-30 13:04