新聞中心
現(xiàn)在有一個架構(gòu)圖如下所示:

創(chuàng)新互聯(lián)建站堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都網(wǎng)站設(shè)計、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的民和網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
圖片
在這種情況下,咱們的數(shù)據(jù)庫仍然是單機部署。根據(jù)一些云廠商的基準測試結(jié)果,使用4核8GB的機器運行MySQL 5.7時,大約可以支持每秒500個事務(wù)(TPS)和每秒10,000個查詢(QPS)。然而,現(xiàn)在運營團隊正在準備雙十一活動,并且公司計劃在全渠道推廣中繼續(xù)投資,這顯然會導(dǎo)致查詢量突然增加的問題。因此,今天我們將探討如何通過主從分離來應(yīng)對查詢請求的增加。
主從讀寫分離
實際上,許多系統(tǒng)都面臨著讀取操作遠多于寫入操作的情況,讀寫請求的數(shù)量差距可能達到幾個數(shù)量級。
這并不難理解,因為瀏覽朋友圈的請求肯定比發(fā)布朋友圈的請求多,而在線商店中,一個商品的瀏覽量肯定遠遠超過下單量。因此,我們首先考慮如何使數(shù)據(jù)庫能夠處理更多的查詢請求,而為此,首先需要將讀取流量和寫入流量分開,這就是我們所說的主從讀寫分離。
實際上,這是一種流量分流的策略,可以將其比作道路交通控制,其中一個有四個車道的主干道中有三個車道供領(lǐng)導(dǎo)和外賓使用,而另一個車道供一般市民使用,以確保領(lǐng)導(dǎo)和外賓能夠優(yōu)先通過。這個策略是一種常規(guī)做法,即使在大型項目中,也是應(yīng)對數(shù)據(jù)庫突發(fā)讀取流量增加的有效方法。
在我目前的項目中,我們曾經(jīng)遇到前端流量突然增加導(dǎo)致從數(shù)據(jù)庫副本負載過高的問題,數(shù)據(jù)庫管理員首先擴展了從數(shù)據(jù)庫,這樣讀取流量就分散到多個從數(shù)據(jù)庫上,從而降低了從數(shù)據(jù)庫的負載。接下來,開發(fā)團隊再考慮如何在數(shù)據(jù)庫層之上采取措施來處理這一流量。
主從讀寫的兩個技術(shù)關(guān)鍵點
通常,在主從讀寫分離機制中,我們復(fù)制一個數(shù)據(jù)庫的數(shù)據(jù)到一個或多個其他數(shù)據(jù)庫服務(wù)器上,并將原始數(shù)據(jù)庫稱為主庫,其主要任務(wù)是處理數(shù)據(jù)寫入操作,而復(fù)制到的目標數(shù)據(jù)庫稱為從庫,主要用于支持數(shù)據(jù)查詢操作。主從讀寫分離涉及兩個關(guān)鍵技術(shù)點:首先,數(shù)據(jù)的拷貝,這稱為主從復(fù)制;其次,在主從分離的情況下,如何屏蔽應(yīng)用訪問數(shù)據(jù)庫時的變化,以使開發(fā)人員感覺就像在使用單一數(shù)據(jù)庫一樣。
1. 主從復(fù)制
讓我用不同的表達方式來解釋MySQL的主從復(fù)制過程。MySQL的主從復(fù)制是依賴于二進制日志(binlog)的技術(shù)。二進制日志記錄了MySQL上的所有數(shù)據(jù)變化,并以二進制形式保存在磁盤上的日志文件中。主從復(fù)制的目標是將主庫中的binlog數(shù)據(jù)傳輸?shù)綇膸焐?,通常這個過程是異步的,也就是說,主庫上的操作不需要等待binlog同步完成。
主從復(fù)制的過程如下:首先,從庫連接到主庫時會創(chuàng)建一個I/O線程,用于請求主庫上的binlog數(shù)據(jù),并將接收到的binlog信息寫入一個名為"relay log"的日志文件中。與此同時,主庫也會創(chuàng)建一個"log dump"線程來將binlog數(shù)據(jù)發(fā)送給從庫。此外,從庫還會創(chuàng)建一個SQL線程,用于讀取"relay log"中的內(nèi)容,并在從庫上進行回放,從而實現(xiàn)主從庫的數(shù)據(jù)一致性。
這種主從復(fù)制方式的優(yōu)點在于,它使用了獨立的"log dump"線程,這是一種異步方式,避免了對主庫的主要數(shù)據(jù)更新流程產(chǎn)生影響。此外,從庫在接收到binlog信息后,并不會直接寫入從庫的實際存儲中,而是將數(shù)據(jù)寫入"relay log",這可以避免寫入從庫存儲的延遲,從而減少主從庫之間的數(shù)據(jù)同步延遲。
圖片
主從復(fù)制是一種在性能考慮下實現(xiàn)的數(shù)據(jù)庫同步機制,其中主庫負責數(shù)據(jù)寫入,而從庫負責數(shù)據(jù)讀取。主庫的寫入操作通常不會等待主從同步完成就返回結(jié)果,這意味著在極端情況下,如主庫上的binlog數(shù)據(jù)還未來得及刷新到磁盤時發(fā)生磁盤損壞或機器掉電,可能會導(dǎo)致binlog數(shù)據(jù)丟失,進而引起主從數(shù)據(jù)不一致的問題。盡管這種情況出現(xiàn)的概率很低,對于互聯(lián)網(wǎng)項目來說是可以接受的。
一旦進行了主從復(fù)制,就可以實現(xiàn)寫請求只寫主庫,讀請求只讀從庫的策略。這意味著即使寫請求鎖定了表或記錄,也不會影響讀請求的執(zhí)行。此外,在讀流量較大的情況下,可以部署多個從庫來共同處理讀流量,這被稱為"一主多從"部署方式,可以用來應(yīng)對高并發(fā)讀取流量,比如在您的垂直電商項目中。
此外,從庫還可以用作備份庫,以防止主庫發(fā)生故障導(dǎo)致數(shù)據(jù)丟失。然而,需要注意的是,增加從庫的數(shù)量并不是無限制的,因為隨著從庫數(shù)量的增加,主庫需要處理更多的IO線程和log dump線程,這可能會對主庫的資源消耗和網(wǎng)絡(luò)帶寬造成影響。通常情況下,一個主庫最多可以連接3到5個從庫。
盡管主從復(fù)制提供了許多好處,例如負載均衡和容錯性,但它也有一些缺點,包括引入部署復(fù)雜性和可能導(dǎo)致主從同步延遲。這種延遲有時會對某些業(yè)務(wù)產(chǎn)生影響,例如在微博發(fā)布中,主從同步延遲可能會影響后續(xù)異步操作的正常流程,如將微博信息發(fā)送給審核系統(tǒng)。
圖片
這個問題解決的思路有很多,核心思想就是盡量不去從庫中查詢信息,純粹以上面的例子來說,我就有三種解決方案:
- 數(shù)據(jù)冗余方案: 在將消息發(fā)送到消息隊列時,不僅發(fā)送微博ID,還將隊列處理機所需的完整微博信息一并發(fā)送,以避免從數(shù)據(jù)庫重新查詢數(shù)據(jù)。這可以確保數(shù)據(jù)一致性,但可能會增加單條消息的大小,從而增加消息傳輸?shù)膸捄蜁r間成本。
- 緩存方案: 同步寫入數(shù)據(jù)庫的同時,將微博數(shù)據(jù)寫入Memcached緩存。這樣,隊列處理機在獲取微博信息時首先嘗試從緩存中獲取,以提高查詢速度和減輕數(shù)據(jù)庫負擔。這種方法特別適用于新增數(shù)據(jù)的場景,但在更新數(shù)據(jù)時需要小心,因為同時更新緩存和數(shù)據(jù)庫可能導(dǎo)致數(shù)據(jù)不一致,特別是在并發(fā)更新時。
- 查詢主庫方案: 在隊列處理機中直接查詢主庫而不是從庫。這是一種可行的方法,但需要謹慎使用,因為如果查詢量很大,可能會給主庫帶來過大的壓力。這種方式適用于查詢量較小且在主庫負載可承受范圍內(nèi)的情況。
最終,我會傾向于選擇數(shù)據(jù)冗余方案,因為它相對簡單,但可能會導(dǎo)致消息的大小增加以及消息傳輸?shù)膸捄蜁r間成本的增加。緩存方案適用于新增數(shù)據(jù)的情況,但需要小心處理數(shù)據(jù)一致性。查詢主庫方案是一種可行的備選方案,但需要謹慎使用以避免對主庫造成過大的壓力。
主從同步延遲是一個容易被忽略的問題,特別在排查問題時。有時候,當我們遇到從數(shù)據(jù)庫中無法獲取信息的奇怪問題時,我們可能會首先懷疑代碼中是否有一些邏輯會導(dǎo)致數(shù)據(jù)被刪除。但隨著時間的推移,我們又發(fā)現(xiàn)之前丟失的數(shù)據(jù)突然又能夠查詢到,這通常是主從同步延遲導(dǎo)致的問題。因此,我們通常將從庫的數(shù)據(jù)落后時間作為一個關(guān)鍵的數(shù)據(jù)庫性能指標來監(jiān)控和設(shè)置警報。正常情況下,數(shù)據(jù)同步延遲應(yīng)該在毫秒級別,一旦延遲達到秒級別,就需要觸發(fā)警報,以及時發(fā)現(xiàn)和解決潛在的問題。
2. 如何訪問數(shù)據(jù)庫
第一類中間件,以淘寶的TDDL(Taobao Distributed Data Layer)為代表,通常以代碼形式嵌入到應(yīng)用程序內(nèi)部運行??梢詫⑺暈閿?shù)據(jù)源的代理,它管理著多個數(shù)據(jù)源,每個數(shù)據(jù)源對應(yīng)一個數(shù)據(jù)庫,可以是主庫也可以是從庫。當應(yīng)用程序發(fā)起數(shù)據(jù)庫請求時,這種中間件會將SQL語句路由到特定的數(shù)據(jù)源進行處理,然后返回處理結(jié)果。
這種中間件的優(yōu)點在于它的簡單和易用,而且沒有額外的部署成本,因為它與應(yīng)用程序一起運行,適合運維能力較弱的小團隊使用。然而,它的缺點在于缺乏多語言支持。目前,這類主流解決方案如TDDL和早期的網(wǎng)易DDB,它們都是用Java開發(fā)的,無法支持其他編程語言。另外,版本升級也需要使用方主動更新,相對較為困難。
第二類中間件方案是單獨部署的代理層,代表性的有早期的阿里巴巴開源項目Cobar、基于Cobar開發(fā)的Mycat、360開源的Atlas,以及美團開源的基于Atlas開發(fā)的DBProxy等等。這些中間件獨立部署在專用服務(wù)器上,業(yè)務(wù)代碼可以像使用單一數(shù)據(jù)庫一樣與它交互,盡管實際上它內(nèi)部管理著多個數(shù)據(jù)源。當應(yīng)用程序發(fā)起數(shù)據(jù)庫請求時,這些中間件會對SQL語句進行必要的改寫,然后將其發(fā)送到指定的數(shù)據(jù)源。它們通常使用標準的MySQL通信協(xié)議,因此可以很好地支持多種編程語言。
由于這些中間件是獨立部署的,因此比較容易進行維護和升級,適合具有一定運維能力的大中型團隊使用。然而,它們的缺點在于所有SQL語句需要跨越兩次網(wǎng)絡(luò):從應(yīng)用到代理層,然后從代理層到數(shù)據(jù)源,因此在性能方面可能會有一些損耗。
圖片
這些中間件,對你而言,可能并不陌生,但是我想讓你注意到是,在使用任何中間件的時候一定要保證對于中間件有足夠深入的了解,否則一旦出了問題沒法快速地解決就悲劇了。
需要明確的要點主要有:
- 主從復(fù)制是一種存儲節(jié)點之間相互復(fù)制數(shù)據(jù)的技術(shù),它實現(xiàn)了數(shù)據(jù)冗余,用于備份和提高橫向擴展性。在使用主從復(fù)制時,需要權(quán)衡一致性和寫入性能。如果要確保所有從節(jié)點都成功寫入,寫入性能可能會受到影響。如果只寫入主節(jié)點并立即返回成功,從節(jié)點可能出現(xiàn)數(shù)據(jù)同步失敗的情況,導(dǎo)致主從不一致。在互聯(lián)網(wǎng)項目中,通常更注重性能而不是強一致性。
- 主從復(fù)制的延遲問題是一個關(guān)鍵的監(jiān)控指標,可能會導(dǎo)致無法立刻讀取數(shù)據(jù)的問題。很多奇怪的讀取不到數(shù)據(jù)的情況可能與主從延遲有關(guān)。因此,在遇到這類問題時,首先要考慮檢查主從延遲的數(shù)據(jù)。
- 業(yè)界存在多種方案來屏蔽主從復(fù)制后數(shù)據(jù)庫訪問的細節(jié),使開發(fā)人員能夠像訪問單一數(shù)據(jù)庫一樣使用它們。這些方案包括嵌入應(yīng)用內(nèi)部的解決方案(如TDDL、Sharding-JDBC)和獨立部署的代理方案(如Mycat)。不同的方案適用于不同的場景和需求。
這種思想和技術(shù)在許多存儲組件中都有應(yīng)用,如Redis使用主從復(fù)制實現(xiàn)讀寫分離,Elasticsearch中的索引分片可以被復(fù)制到多個節(jié)點,HDFS中的文件會被復(fù)制到多個DataNode。盡管不同組件對復(fù)制的一致性和延遲要求不同,但這種設(shè)計思想是通用的,對于理解和學(xué)習(xí)其他存儲組件非常有幫助。
網(wǎng)頁題目:并發(fā)的查詢請求增加時,數(shù)據(jù)架構(gòu)部分如何做主從分離?
URL標題:http://m.fisionsoft.com.cn/article/ccishgj.html


咨詢
建站咨詢
