网易云IM云服务的稳定原来是这样实现的
你們都知道,我們網(wǎng)易云的IM云服務(wù)是賣得很火的。
人紅壓力大,為了能給百萬商家億級(jí)終端用戶提供便捷的即時(shí)通信服務(wù),保證我們的業(yè)務(wù)系統(tǒng)能承受住各種大壓力的考驗(yàn),如何保障系統(tǒng)的穩(wěn)定運(yùn)行,支撐更大的并發(fā),提供真正的可擴(kuò)展的IM云服務(wù)是一個(gè)很重要的問題。
這個(gè)問題,網(wǎng)易云首席DBA、網(wǎng)易資深數(shù)據(jù)運(yùn)維工程師在上周一次分享中是這樣說的:
●●●
分布式數(shù)據(jù)庫架構(gòu)介紹
作為互聯(lián)網(wǎng)的一支老牌勁旅,我們?cè)诖蟛l(fā)海量互聯(lián)網(wǎng)系統(tǒng)構(gòu)建方面也有著非常深厚的積累與經(jīng)驗(yàn)。在數(shù)據(jù)庫選擇上我們使用了網(wǎng)易私有云中的分布式數(shù)據(jù)庫服務(wù)(云DDB),其架構(gòu)圖如下:
云DDB主要包括五個(gè)組件: NLB、SQL Proxy、DBN、Master、SYSDB。
??NLB是負(fù)載均衡服務(wù),基于LVS打造,負(fù)責(zé)將應(yīng)用請(qǐng)求轉(zhuǎn)發(fā)到后端SQL Proxy, 同時(shí)定時(shí)檢測(cè)后端SQL Proxy的可用性,及時(shí)將故障機(jī)器從集群中摘除。
SQL Proxy實(shí)現(xiàn)了MySQL協(xié)議,接收客戶端請(qǐng)求,同時(shí)負(fù)責(zé)將請(qǐng)求路由到具體的后端數(shù)據(jù)庫節(jié)點(diǎn),并返回?cái)?shù)據(jù)給客戶端。如果數(shù)據(jù)請(qǐng)求分布在多個(gè)節(jié)點(diǎn),則可能使用2PC協(xié)議進(jìn)行分布式事務(wù)(保障數(shù)據(jù)一致性)。
DBN則是底層真正負(fù)責(zé)數(shù)據(jù)存取的服務(wù),通常是一個(gè)關(guān)系型數(shù)據(jù)庫,目前支持MySQL、Oracle。
?Master是管理服務(wù),負(fù)責(zé)管理集群,比如新建表、設(shè)置數(shù)據(jù)路由策略、設(shè)置客戶端連接池參數(shù)、DBN切換、配置變更通知等,操作結(jié)果(集群元數(shù)據(jù))將持久化到SYSDB。
?SYSDB是一個(gè)數(shù)據(jù)庫,負(fù)責(zé)存儲(chǔ)分布式數(shù)據(jù)庫的元數(shù)據(jù)信息,包括表、字段、權(quán)限、數(shù)據(jù)路由等信息。
DBN與SYSDB使用的是網(wǎng)易私有云RDS,其它組件則部署在使用云主機(jī)上,云DDB服務(wù)的核心組件SQL Proxy以及DBN都是可擴(kuò)展的,并且高可用的。
DDB處理邏輯簡單來說就是應(yīng)用請(qǐng)求通過NLB轉(zhuǎn)發(fā)到具體SQL Proxy上,SQL Proxy解析SQL生成執(zhí)行計(jì)劃,下發(fā)請(qǐng)求至底層節(jié)點(diǎn),收到DBN數(shù)據(jù)后做一定的處理返回給客戶端。
●●●
高可用分布式DB服務(wù)構(gòu)建指南
網(wǎng)易IM云服務(wù)目標(biāo)是支持彈性擴(kuò)展、消息必達(dá),那就需要在保證高吞吐、高性能的同時(shí),那就需要數(shù)據(jù)的高可用性:簡單而言就是數(shù)據(jù)存儲(chǔ)服務(wù)要高可用并且數(shù)據(jù)不丟失。
因?yàn)殛P(guān)系型數(shù)據(jù)庫發(fā)展幾十年在穩(wěn)定性方面對(duì)比其他數(shù)據(jù)存儲(chǔ)方案來說存在非常大的優(yōu)勢(shì),基于此,業(yè)務(wù)很多對(duì)數(shù)據(jù)一致性的場景都是直接依賴于DB。
比如為了保證消息準(zhǔn)確到達(dá),發(fā)送方的消息需要先持久化到DB,再發(fā)送到接收方,接收方收到之后更新為已接收狀態(tài),因此對(duì)數(shù)據(jù)庫是重度依賴。
對(duì)關(guān)系型數(shù)據(jù)庫來說高性能高可用跟數(shù)據(jù)不丟失又往往是魚跟熊掌的關(guān)系,要保證數(shù)據(jù)完全不丟失的話,數(shù)據(jù)必然是要同時(shí)寫入到主庫與從庫才算完成,此時(shí)如果從機(jī)異常,數(shù)據(jù)寫入將失敗,這將導(dǎo)致數(shù)據(jù)庫服務(wù)不可用,相信很少有人能接受。
所以通常在數(shù)據(jù)一致性與服務(wù)可用性上會(huì)做一定的妥協(xié),即正常情況下表現(xiàn)為主從強(qiáng)一致性模式,異常情況下則退化為異步模式。這在MySQL里面我們稱之為Semi sync復(fù)制,Oracle 復(fù)制(DataGuard) 里面則為最大保護(hù)模式。
在保證數(shù)據(jù)服務(wù)高性高吞吐的情況下盡量避免數(shù)據(jù)丟失,我們對(duì)網(wǎng)易云DDB底層DBN做了如下設(shè)置:
將sync_binlog與innodb_flush_log_at_trx_commit同時(shí)設(shè)置為1,每次數(shù)據(jù)庫寫操作都會(huì)持久化binlog與redo log到磁盤上,保證數(shù)據(jù)的持久性。
開啟VSR(virtual sync replication),保證主從能實(shí)時(shí)一致。
開啟Group Commit,以及從庫的并行復(fù)制,提升主從性能。
第2點(diǎn)里的VSR,這個(gè)是網(wǎng)易MySQL分支InnoSQL的一個(gè)特性,InnoSQL在官方半同步復(fù)制(semi sync)基礎(chǔ)上做了部分改進(jìn),改善了主庫宕機(jī)時(shí)主從數(shù)據(jù)不一致問題,實(shí)現(xiàn)機(jī)制如圖所示:
簡單來說,MySQL5.5版本中官方semi sync是在binlog與redo都寫完后再將binlog傳輸?shù)綇膸?#xff0c;而vsr則是在binlog寫完后與redolog寫之前傳輸binlog,這樣做的好處是可以避免事務(wù)日志提交后主庫宕機(jī)恢復(fù)后數(shù)據(jù)幻讀問題。(在官方MySQL5.7中這個(gè)問題得到解決,見rpl_semi_sync_master_wait_point參數(shù)解釋)。
當(dāng)然這樣做也有缺點(diǎn),事務(wù)需要等待數(shù)據(jù)傳輸?shù)綇膸旌笤俜颠€,肯定會(huì)增加一定的延遲時(shí)間,針對(duì)這個(gè)問題,優(yōu)化方法就是第三點(diǎn)開啟group commit。開啟后多個(gè)事務(wù)的binlog一次性提交到磁盤跟傳輸至從庫,這樣可以減少磁盤fsync次數(shù)并提升吞吐量。
以下是sync_group (vsr+group commit) 與原生semi sync、 sync(vsr) 、async(不開啟semi sync) 之間性能對(duì)比圖,可以看到 vsr + group commit性能與異步復(fù)制幾無差別:
同時(shí)為了從庫及時(shí)同步數(shù)據(jù),我們?cè)趶膸焐洗蜷_并行復(fù)制,主庫上事務(wù)并行提交從庫上也可以并行恢復(fù),這樣大并發(fā)寫入下從庫沒有基本延時(shí)。
隨著業(yè)務(wù)的暴漲,數(shù)據(jù)量規(guī)模及QPS也暴漲幾百倍,經(jīng)過多次擴(kuò)容后,為了提升DDB性能及容量,我們將IM云底層DBN節(jié)點(diǎn)從RDS遷移到物理機(jī),并且使用大量的SSD作為底層存儲(chǔ)。遷出RDS后DDB底層節(jié)點(diǎn)便不再擁有高可用這一特性,為此我們自己開發(fā)了一套DDB底層節(jié)點(diǎn)監(jiān)控與切換工具DDB Monitor,此時(shí)DB高可用架構(gòu)圖變成:
DDBMonitor可用于執(zhí)行日常數(shù)據(jù)庫擴(kuò)容切換、故障切換、狀態(tài)監(jiān)控等工作。
故障切換模式下會(huì)定時(shí)(幾秒) 做如下事情:
?狀態(tài)檢測(cè),包括檢測(cè)DBN存活狀態(tài),主從復(fù)制關(guān)系,binlog位置點(diǎn),semi狀態(tài)等;
?模擬數(shù)據(jù)寫入,檢查主庫是否可寫。
在判斷MySQL主從何時(shí)可以切換方面,與其它開源工具可能有些不同,需要滿足以下情況才可能觸發(fā)故障切換:
DBN主節(jié)點(diǎn)無法連接,錯(cuò)誤號(hào)為2000-3000間指定幾個(gè)(避免maxconnection等服務(wù)端反回的錯(cuò)誤號(hào)造成誤判);
DBN主節(jié)點(diǎn)指定時(shí)間內(nèi)重試多次仍無法寫入;
從庫接收到的binlog已經(jīng)應(yīng)用完成或者在若干秒時(shí)間內(nèi)應(yīng)用完成;
上一次數(shù)據(jù)庫vsr(semi sync)狀態(tài)正常或上一次從庫收到的binglog落后主庫若干字節(jié)內(nèi) (根據(jù)業(yè)務(wù)數(shù)據(jù)重要程度設(shè)置);
如果主庫無法連接,從庫show slave status中Slave_IO_Running狀態(tài)需為NO (從庫與DDB Monitor工具同時(shí)監(jiān)控主庫是否宕機(jī),避免腦裂問題);
從庫Slave_SQL_Running狀態(tài)需為 Yes。
其中條件1與條件2需要滿足至少1者。 4中表示如果對(duì)主從一致性要求很高需要滿足上次檢測(cè)vsr(semi sync)正常才能切換,而如果可以容忍一定的數(shù)據(jù)丟失那么可以設(shè)置檢測(cè)上次主從同步binlog差值在指定范圍內(nèi)即可切換。
故障切換后,SQL Proxy收到Master消息會(huì)重新建立到正確DBN的連接,主庫宕機(jī)情況下基本可以在秒級(jí)別完成切換。
當(dāng)然除了上面這些說的這些部署上保障高可用外之外,加強(qiáng)數(shù)據(jù)庫設(shè)計(jì)與監(jiān)控也是保障數(shù)據(jù)庫穩(wěn)定運(yùn)行非常重要的一環(huán)。
數(shù)據(jù)庫設(shè)計(jì)方面的措施主要有:
?按照數(shù)據(jù)庫設(shè)計(jì)規(guī)范進(jìn)行表、SQL設(shè)計(jì)。表設(shè)計(jì)盡量精簡,從數(shù)據(jù)訪問角度設(shè)計(jì)表結(jié)構(gòu),在范式與反范式間要做合理的取舍;
?數(shù)據(jù)請(qǐng)求盡量精簡快,并減少跨節(jié)點(diǎn)訪問,提升數(shù)據(jù)庫真正的服務(wù)時(shí)間;
?高頻查詢需要添加緩存,用戶配置、群信息配置等少更新高訪問請(qǐng)求走要緩存;
對(duì)數(shù)據(jù)一致性要求不高以及數(shù)據(jù)分析統(tǒng)計(jì)類的請(qǐng)求放到從庫查詢;
非核心功能、核心但數(shù)量少頻次低模塊走RDS,避免相互影響;
與應(yīng)用合作,添加對(duì)DB沖擊較大業(yè)務(wù)場景(比如聊天室)提供限流支持。
數(shù)據(jù)庫監(jiān)控方面我們主要做了如下以下幾個(gè)方面:
?DDB各個(gè)組件的網(wǎng)絡(luò)、系統(tǒng)層面通用性指標(biāo)監(jiān)控;
SQL Proxy、DDB Master jvmgc信息、連接數(shù)、cpu、請(qǐng)求量、響應(yīng)時(shí)間內(nèi)存使用率日志等監(jiān)控;
DBN節(jié)點(diǎn)(MySQL) Global status、processlist、innodb engine status、slowlog、數(shù)據(jù)增長率、表分區(qū)、文件句柄等監(jiān)控;
數(shù)據(jù)運(yùn)維平臺(tái)上報(bào)表展示基于海量監(jiān)控?cái)?shù)據(jù)下通過一定算法得到數(shù)據(jù)庫容量、運(yùn)行狀態(tài)、重要指標(biāo)不同時(shí)間同比環(huán)比,風(fēng)險(xiǎn)點(diǎn)分析提示,風(fēng)險(xiǎn)SQL指示等。
一套DDB內(nèi)通常包含幾百個(gè)維度的指標(biāo)監(jiān)控及幾十個(gè)維度的報(bào)警項(xiàng)。
●●●
多機(jī)房高可用實(shí)踐
在過往的運(yùn)維經(jīng)歷中,我們遇到過機(jī)柜掉電、機(jī)房大面積故障等事情,這種情況的發(fā)生會(huì)嚴(yán)重影響產(chǎn)品可用性。所以對(duì)于云信等重要產(chǎn)品,單機(jī)房高可用顯然無法滿足業(yè)務(wù)追求
多機(jī)房是個(gè)非常復(fù)雜的工程,不僅需要在部署上有多機(jī)房部署,在應(yīng)用層面也需要支持多機(jī)房架構(gòu),雖然我們?cè)诋a(chǎn)品發(fā)展初期就開始了多機(jī)房高可用建設(shè),但到目前我們并沒有完全做到自動(dòng)化故障切換。
這里介紹下我們做的工作也是拍磚引玉,希望大家提出寶貴意見。
我們多機(jī)房高可用主要做到的工作:
備機(jī)房距主機(jī)房至少需隔兩百公里距離,機(jī)房間必須有專線;
服務(wù)入口多機(jī)房,客戶端請(qǐng)求根據(jù)流量配置轉(zhuǎn)發(fā)到不同機(jī)房服務(wù)器;
應(yīng)用與依賴組件多機(jī)房高可用部署(MQ、Hbase、對(duì)象存儲(chǔ)服務(wù)等),部分組件需要應(yīng)用雙寫多機(jī)房,比如Hbase、對(duì)象存儲(chǔ)的寫入等;
應(yīng)用訪問數(shù)據(jù)服務(wù)通過配置管理服務(wù)(DISCONF)獲取,數(shù)據(jù)庫與緩存通過使用功能(MySQL)或復(fù)制工具(緩存) 做跨機(jī)房數(shù)據(jù)復(fù)制;
監(jiān)控多機(jī)房組件的可用性,PE與DBA部署好自動(dòng)化切換工具;
確定基于binlog與應(yīng)用日志的重要數(shù)據(jù)校驗(yàn)與補(bǔ)償機(jī)制。
最后數(shù)據(jù)庫高可用架構(gòu)圖:
人工切換始終會(huì)存在一定的延時(shí),不過我們運(yùn)維部強(qiáng)大的運(yùn)維協(xié)作工具Stone支持移動(dòng)端執(zhí)行服務(wù)器命令,可以隨時(shí)隨地執(zhí)行切換操作:
●●●
QA環(huán)節(jié)
Q1:有什么好的方案能在保證業(yè)務(wù)不中斷的情況下實(shí)現(xiàn)跨機(jī)房大數(shù)據(jù)庫遷移,在這過程中又如何保證數(shù)據(jù)的實(shí)時(shí)性呢?
A1: 數(shù)據(jù)庫的實(shí)時(shí)性 可以有專線網(wǎng)絡(luò) + DB復(fù)制 來保障, 不終端服務(wù)實(shí)現(xiàn)跨機(jī)房的話 就需要系統(tǒng)相關(guān)的所有組件都支持跨機(jī)房高可用,并且需要實(shí)現(xiàn)自動(dòng)化切換。補(bǔ)充一點(diǎn), 跨機(jī)房服務(wù)部終端,會(huì)犧牲一定的數(shù)據(jù)一致性。需要補(bǔ)充的是,跨機(jī)房的服務(wù)部終端,會(huì)犧牲一定的數(shù)據(jù)一致性。
Q2:請(qǐng)問你們都有哪些自己研發(fā)的模塊開源呢?很想學(xué)習(xí)下。
A2:網(wǎng)易InnoSQL是開源的,另外redis復(fù)制遷移工具 redis-migration也是開源的。
Q3:關(guān)系型數(shù)據(jù)庫MySQL很流行,但是也有不足,我們最近在考慮有沒有替換的方案。能否將它和其他的對(duì)比一下?你們是怎樣做的選擇?
A3:首先我覺得最好是選擇你最熟悉的,能搞定的數(shù)據(jù)庫。GitLab數(shù)據(jù)丟失事故 我認(rèn)為很大的原因是因?yàn)樗麄兊墓こ處煂?duì)postgresql 不是很懂。另外MySQL發(fā)展其實(shí)非常快的,5.7 有很多非常好的特性,很多東西都借鑒了Oracle。
Q4:你們有什么開源的跨機(jī)房數(shù)據(jù)實(shí)時(shí)同步工具嗎。
A4:我們網(wǎng)易內(nèi)部有一套自己開發(fā)的數(shù)據(jù)復(fù)制工具DTS,目前還沒有開源, 緩存復(fù)制工具有開源是 redis-migration,GitHub 上大家可以搜一下。
Q5:你們的數(shù)據(jù)訪問高峰是什么時(shí)候呢?還是說一直比較平緩?還有,有沒有大規(guī)模遷移數(shù)據(jù)庫的經(jīng)歷,可以講一講嗎?
A5:業(yè)務(wù)肯定有高峰低估的,一般晚上黃金時(shí)段是高峰期,凌晨是低谷。數(shù)據(jù)遷移的話其實(shí)做好工具后,數(shù)據(jù)大小量沒有太大的差別,數(shù)據(jù)量大的話需要做限流。
Q6:從技術(shù)上選擇MySQL和PG有什么區(qū)別?選擇他們的時(shí)候你們是選了最熟悉的還是做了技術(shù)選型的調(diào)研?
A6:我們選擇了最熟悉并且最適合我們的,PG跟MySQL都非常優(yōu)秀,性能上也差不多。
Q7:能不能講講上次大規(guī)模故障的事情?多長時(shí)間內(nèi)完成恢復(fù)?有哪些措施?數(shù)據(jù)如何備份?
A7: 故障恢復(fù)通常需要做好預(yù)案, 比如當(dāng)你無法做到自動(dòng)化切換的時(shí)候,就需要有一套切換的腳本,另外故障切換后通常需要做好一定的限流,不能切完再掛。數(shù)據(jù)備份方面:我們一套數(shù)據(jù)庫備份系統(tǒng), 數(shù)據(jù)庫的備份會(huì)備份到存儲(chǔ)服務(wù)上。
Q8:你們的采用分布式數(shù)據(jù)庫與單節(jié)點(diǎn)數(shù)據(jù)庫能完全兼容嗎?
A8:大部分都能兼容,少數(shù)極端的case不兼容。
Q9:你們線上業(yè)務(wù)單表數(shù)據(jù)量能去到多少?是如何對(duì)這些表進(jìn)行優(yōu)化?
A9:一般我們都會(huì)分表, 一張大表可能有幾十到幾百張字表,百億級(jí)表很多的,比如我們的消息表。表優(yōu)化: 1 將歷史數(shù)據(jù)遷移到離線數(shù)據(jù)庫 2 精確好字段長度 3 盡量以primary key 或者聯(lián)合索引去訪問表。
Q10:為什么不在sql proxy層使用mycat?最近使用了mycat感覺還不錯(cuò)
A10:SQL Proxy跟我們DDB各組件是集成在一起的, DDB是2006年開始研發(fā)的,比市面上任何一款分庫分表工具都悠久,我們對(duì)比過SQL Proxy跟mycat, ?各有優(yōu)缺點(diǎn)。
——【特別推薦】——
為什么你的工作經(jīng)驗(yàn)不值錢
總結(jié)
以上是生活随笔為你收集整理的网易云IM云服务的稳定原来是这样实现的的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于假冒网站仿冒网易云信官网相关情况的声
- 下一篇: 今天网易云有大事发生?!