洪亮
摘要:商用App因為使用人數(shù)較多,對于服務(wù)端數(shù)據(jù)庫訪問有著較高的要求。如果數(shù)據(jù)訪問架構(gòu)不合理,當(dāng)訪問請求較多時,容易出現(xiàn)訪問超時的情況。文中,主要就對商用App服務(wù)端數(shù)據(jù)訪問架構(gòu)改造進行了分析。
關(guān)鍵詞:商用App;服務(wù)端;數(shù)據(jù)訪問;架構(gòu)
中圖分類號:TP393 文獻標(biāo)識碼:A
文章編號:1009-3044(2020)21-0076-02
開放科學(xué)(資源服務(wù))標(biāo)識碼(0SID):
1 背景研究
1.1系統(tǒng)商用問題
某國某運營商的掌上App項目中,近期出現(xiàn)了用戶使用過程中App響應(yīng)慢,卡頓甚至系統(tǒng)崩潰的問題。經(jīng)過問題排查發(fā)現(xiàn)問題大概率出現(xiàn)在業(yè)務(wù)高峰期,并且隨著用戶量的增加,問題的出現(xiàn)概率越高。系統(tǒng)前端向服務(wù)端的請求出現(xiàn)超時。進而檢查服務(wù)端,發(fā)現(xiàn)超時的原因在于數(shù)據(jù)庫鏈接滿載,讀寫吞吐量達到瓶頸導(dǎo)致請求超時。
1.2系統(tǒng)服務(wù)端架構(gòu)分析
通過對目前系統(tǒng)服務(wù)端的架構(gòu)做分析,發(fā)現(xiàn)目前服務(wù)端是采用的單一數(shù)據(jù)訪問架構(gòu),服務(wù)端通過web項目將業(yè)務(wù)服務(wù)封裝為restful接口給前端App調(diào)用,服務(wù)端的業(yè)務(wù)類訪問單一的Mysql數(shù)據(jù)庫,當(dāng)讀寫數(shù)據(jù)量大時,業(yè)務(wù)類到Mysql的鏈接處就出現(xiàn)了瓶頸,出現(xiàn)了上面提到的問題。所以為了解決這個問題就必須改造現(xiàn)網(wǎng)系統(tǒng)服務(wù)端的數(shù)據(jù)訪問架構(gòu),從單一數(shù)據(jù)庫訪問改造為分布式或集群架構(gòu),用來擴展數(shù)據(jù)庫訪問效率和吞吐量,并可提升數(shù)據(jù)訪問的高可用性。
1.3 架構(gòu)選型
目前業(yè)界有多種Mysql數(shù)據(jù)庫的分布式/集群方案,通過對各種方案的優(yōu)劣并結(jié)合項目實際情況為本次的改造選擇使用MysqI+Mycat的架構(gòu),中間件對代碼影響最小,易于架構(gòu)改動,以及后期擴展。
2 架構(gòu)實現(xiàn)
第一部分的改造將一臺Mysql數(shù)據(jù)庫擴展為兩臺Mysql,一主一備,通過原生的復(fù)制機制實現(xiàn)雙向復(fù)制,加入Mycat中間件代理兩臺Mysql,實現(xiàn)讀寫的負載均衡,并且Mycat通過心跳機制檢測到主庫宕機后,自動切換到備機。業(yè)務(wù)測代碼不需要修改,只需要修改數(shù)據(jù)庫的連接由Mysql的地址切換到Mycat即可。
第二部分的改造也有兩種方案,第一種:將一臺Mycat擴展為兩臺,業(yè)務(wù)測訪問VIP(虛擬IP),兩臺keepalive競爭VIP,并由HAproxy轉(zhuǎn)發(fā)到其中一臺Mycat,實現(xiàn)負載均衡高可用。
第二種:Mycat依舊為兩臺,但是負載均衡不在服務(wù)端,而是放在客戶端(及業(yè)務(wù)代碼端),使用java原生提供的LoadBal-ancing協(xié)議,將對數(shù)據(jù)庫的讀寫請求負載在多個MYcat實例上實現(xiàn)Mycat的高可用。LoadBalancing原理:mysql connector/J驅(qū)動創(chuàng)建的LoadBalancedConnection是一個邏輯鏈接,其內(nèi)部持有一個物理鏈接列表,即與每個host建立一個Connection。url中的每個host都是平等的主host,當(dāng)客戶端獲取連接時會有兩種random(默認隨機)和bestResponseTime(最小響應(yīng)時間)兩種均衡策略,可以在參數(shù)** loadBalanceStrategy**中指定,架構(gòu)圖如圖1。
關(guān)于兩種方案的選擇,方案一自定義軟負載是自己實現(xiàn)的,功能單一,負載策略只有輪詢,而且健康檢查在很長一段時間出現(xiàn)連接泄露的問題,穩(wěn)定性不夠好,還需要做一些優(yōu)化和測試進行打磨;方案二是基于mysql的Java連接驅(qū)動做的負載均衡,是官方提供的方案,穩(wěn)定性和可用性更高,而且我們在經(jīng)過很長一段時間的壓測和容錯性測試,發(fā)現(xiàn)其性能很優(yōu)越,負載均衡策略也更豐富,使用過程更簡單,所以決定使用方案二。
3 環(huán)境搭建
3.1 Mycat+Mysql搭建
首先在兩臺Linux主機上安裝Mycat,然后再安裝兩臺Mysql,端口號分別為3301和3302,安裝方法這里不贅述。接著對兩臺Mycat進行配置,分別代理兩臺Mysql數(shù)據(jù)庫,分別對server.xml.schemas.xml做相應(yīng)的配置,實現(xiàn)代理一主一從兩個Mysql數(shù)據(jù)庫,并且從庫也為主庫的備用庫,注意schemas.xml中的balance類型設(shè)置為2,所有的主庫和從庫都參與讀操作的負載均衡。
3.2 功能驗證
3.2.1 負載均衡
啟動兩臺Mysql和兩臺Mycat,從任意一臺Mysql主機訪問Mycat,指令為:
mysql -h172.16.23.126 -P8066 -uroot -pmycat0001
端口指向其中一臺My at,用戶名密碼,執(zhí)行多次查詢操作,讀操作負載均衡日志中展示的結(jié)果,已實現(xiàn)了在主從庫中負載讀的操作。
3.2.2故障遷移
手動停掉主庫模擬數(shù)據(jù)庫宕機的情況,mycat自動將從庫切換為主庫,不影響讀寫操作,并且當(dāng)主庫故障恢復(fù)后,再次測試多次查詢操作,恢復(fù)到之前的負載均衡狀態(tài)。
3.2.3 主從復(fù)制
關(guān)于主從復(fù)制功能,因為目前一主一從的架構(gòu)下寫操作都在主庫,讀操作在主庫與從庫間負載,所以需要主從保持復(fù)制同步數(shù)據(jù)。這里使用Mysql原生的復(fù)制機制,通過bin log實現(xiàn)數(shù)據(jù)的同步。驗證過程:同樣登陸mycat,執(zhí)行插入,修改或刪除操作,首先數(shù)據(jù)會入主庫,查詢主庫表能夠查詢到寫操作的結(jié)果,這時再查詢從庫,發(fā)現(xiàn)數(shù)據(jù)和主庫一致,說明復(fù)制操作完成。當(dāng)停掉其中一個數(shù)據(jù)庫后,再次執(zhí)行插入,修改或刪除操作,然后手動恢復(fù)停掉的數(shù)據(jù)庫,再次查詢該數(shù)據(jù)庫的表數(shù)據(jù),發(fā)現(xiàn)兩庫數(shù)據(jù)保持一致,說明在故障恢復(fù)后,主從復(fù)制的機制仍然有效。
4 性能測試
4.1 測試前提準備
有一個重要的指標(biāo)需要注意,就是數(shù)據(jù)庫的最大連接數(shù),要模擬現(xiàn)網(wǎng)項目的真實場景,這個配置是至關(guān)重要的,所以首先需要將兩臺Mysql數(shù)據(jù)庫的最大連接數(shù)設(shè)置和現(xiàn)網(wǎng)項目保持一致,這里我們設(shè)置為2000。
4.2 采集樣本準備
準備兩組采集樣本,第一組采集對單例mysql讀操作的性能數(shù)據(jù),初始并發(fā)請求為0,每過10秒鐘增加100并發(fā)請求,一直增加到并發(fā)5000,然后保持60秒,然后每秒減少100并發(fā),直到并發(fā)為0。通過對上述場景下的mysql單例吞吐量,請求書,失敗率三個方面表現(xiàn)做觀察和分析。第二組則對Mycat架構(gòu)下一主一從的mysql做讀操作的性能數(shù)據(jù),同樣采用以上的遞增并發(fā)測試場景。
4.3 壓測工具準備
采用開源壓力測試工具JMeter作為本次的性能壓力測試工具,并創(chuàng)建壓測模板。新建兩個stepping thread group,一個是連接單例mysql,一個連接mycat,采用同樣的讀查詢SQL。
4.4 壓測結(jié)果分析
首先在對單例mysql的測試中我們可以看到剛開始時請求成功的TPS達到1700左右,然后隨著并發(fā)量的提升,TPS逐漸降低,到4分鐘時差不多降到1600左右,這個時候的并發(fā)請求快到了2000,后面繼續(xù)降低,并且開始出現(xiàn)請求錯誤的響應(yīng),繼續(xù)到9分鐘左右,并發(fā)到達峰值5000,成功請求TPS降到1500左右。
14分鐘總共處理請求數(shù)155萬,平均響應(yīng)時長1014ms,響應(yīng)錯誤率13.46%,也就是成功響應(yīng)的請求數(shù)為134萬。
然后看mycat代理2臺mysql負載均衡的測試結(jié)果,剛開始時請求成功的TPS達到3500左右,然后隨著并發(fā)量的提升,TPS逐漸降低,到4分鐘時差不多降到3300左右,這個時候的并發(fā)請求快到了2000,后面繼續(xù)降低,并且開始出現(xiàn)請求錯誤的響應(yīng),繼續(xù)到9分鐘左右,并發(fā)到達峰值5000,成功請求TPS降到3100左右。
14分鐘總共處理請求數(shù)337萬,平均響應(yīng)時長529ms,響應(yīng)錯誤率17.73%,也就是成功響應(yīng)的請求數(shù)為277萬。
綜合對比分析,可見在mycat的代理分布式mysql的環(huán)境下,不論從吞吐量,處理請求書,響應(yīng)延時以及成功請求數(shù)等各方面,幾乎提升了一倍的性能,效果比較理想。
5 穩(wěn)定性測試
為了保證在升級到新的架構(gòu)后數(shù)據(jù)庫訪問的穩(wěn)定性,所以要做穩(wěn)定性測試,在新的mycat代理2臺mysql環(huán)境下,繼續(xù)使用JMeter工具壓測,測試樣本調(diào)整為保持2000并發(fā)請求,并持續(xù)24小時,觀察新架構(gòu)下的數(shù)據(jù)訪問穩(wěn)定性,從測試結(jié)果可以看得出24個小時保持高并發(fā)下mycat+mysql表現(xiàn)穩(wěn)定,吞吐量保持在3200-3300左右,平均請求延時在600ms左右,總共的請求錯誤率在1.1%左右,可以說結(jié)果比較理想。
6 擴展性
目前為止已經(jīng)完成了將單例mysql擴展為2臺mysql負載均衡的架構(gòu),這里稱為擴容階段1。并且通過壓力測試結(jié)果可以得出性能確實提升的結(jié)論,所以再升級為新的架構(gòu)后,理論上可以有效緩解現(xiàn)網(wǎng)App客戶在使用時的卡頓、響應(yīng)慢、崩潰等問題。當(dāng)然考慮到用戶量的不斷增加,新的架構(gòu)也必須要考慮到良好的擴展性,對于后期的擴容本文也給出了響應(yīng)的架構(gòu)演進,擴容階段2將增加兩臺mysql,一共4臺,做雙主單從,兩主互為主備,相互復(fù)制,主從之前相互復(fù)制,讀操作在4臺中負載均衡,效率應(yīng)為階段1的兩倍左右。隨著用戶量繼續(xù)增加,再到擴容階段3再增加兩臺mysql,一共6臺,在雙主的情況下做雙主雙從,這時可以將負載均衡策略改為再除了當(dāng)前主機之外的其他5臺mysql做讀負載,主機只做寫,讀寫分離,讓主機寫效率更高。如果用戶量還在持續(xù)上升,那么架構(gòu)將演進到最終階段,架構(gòu)升級為N主N從,可以考慮將寫負載到N臺主庫上,所有從庫做讀負載均衡。
【通聯(lián)編輯:李雅琪】