騰訊計(jì)費(fèi)平臺部托管著公司90%以上的虛擬賬戶,如QB墨林、Q點(diǎn)赁酝、包月服務(wù)、游戲的二級賬戶等旭等,為了保證能順暢支撐公司各大業(yè)務(wù)的實(shí)時(shí)在線交易酌呆,并且在各種災(zāi)難場景下數(shù)據(jù)是一致并且可用的,對系統(tǒng)的可用性搔耕、一致性切換要求非常高隙袁,因此計(jì)費(fèi)團(tuán)隊(duì)歷來都非常重視高一致性存儲系統(tǒng)的建設(shè)痰娱。
到目前為止,計(jì)費(fèi)高一致性存儲層的解決方案大致經(jīng)過了3個(gè)階段菩收,本文將分享最新的基于MySQL的分布式解決方案梨睁。
隨著業(yè)務(wù)的發(fā)展,基于內(nèi)存的NoSQL解決方案HOLD平臺在高峰期一天支撐3000億讀寫娜饵,證明了分布式Cache的巨大價(jià)值;但隨著各種業(yè)務(wù)的接入坡贺,NoSQL方案的不足也逐步顯現(xiàn)出來了,如下所示箱舞。
1遍坟、適用的業(yè)務(wù)場景比較有限,僅提供get/set操作晴股,有不少業(yè)務(wù)場景希望能通過記錄中的其他字段做索引來查詢愿伴,比如流水類業(yè)務(wù)。
2电湘、不是所有的數(shù)據(jù)都是熱點(diǎn)隔节,一臺64GB內(nèi)存機(jī)器提供的有效內(nèi)存空間大概在50GB左右,而采用Fusion卡的機(jī)型容量一般在1TB以上胡桨,對比起來官帘,如果所有數(shù)據(jù)放入分布式Cache明顯是一種極大的浪費(fèi)瞬雹,最合理的當(dāng)然是熱點(diǎn)在HOLD昧谊,冷數(shù)據(jù)采用基于磁盤的存儲。
3酗捌、計(jì)費(fèi)平臺部多年來在支付領(lǐng)域有了相當(dāng)多的技術(shù)積累呢诬,HOLD作為NoSQL系統(tǒng)功能有限,因此建造一套更加強(qiáng)大通用的高一致性存儲系統(tǒng)將整個(gè)支付領(lǐng)域的實(shí)時(shí)數(shù)據(jù)(重點(diǎn)是賬戶數(shù)據(jù)胖缤、用戶訂單數(shù)據(jù)尚镰,以及海量的流水?dāng)?shù)據(jù))統(tǒng)一管理起來非常有價(jià)值。
基于上面的分析哪廓,結(jié)合我們在MySQL領(lǐng)域多年的應(yīng)用和優(yōu)化經(jīng)驗(yàn)狗唉,最終決定在MySQL存儲引擎基礎(chǔ)之上,打造一套分布式的SQL系統(tǒng)涡真。
1分俯、保持原來的MySQL協(xié)議,這樣以前訪問MySQL系統(tǒng)的C++哆料、Java各類系統(tǒng)都不需要修改缸剪,DBA能繼續(xù)保持原來大部分使用習(xí)慣。
2东亦、自動(dòng)的跨IDC容災(zāi)切換杏节,同時(shí)保證數(shù)據(jù)一致性,對于提交成功的事務(wù)保證一筆不丟,達(dá)到銀行級對容災(zāi)的要求奋渔。
3镊逝、靈活的容量伸縮機(jī)制,對業(yè)務(wù)透明嫉鲸,解決MySQL本身擴(kuò)容不靈活的問題蹋半。
4、重點(diǎn)支持OLTP類型的在線業(yè)務(wù)充坑。
整體架構(gòu)
針對上面的需求减江,TDSQL最終的結(jié)構(gòu)如圖1所示(與當(dāng)前大部分中心化的分布式系統(tǒng)類似)。
系統(tǒng)由三個(gè)模塊組成:Scheduler捻爷、Agent辈灼、網(wǎng)關(guān),三個(gè)模塊的交互都是通過ZooKeeper完成也榄,極大簡化了各個(gè)節(jié)點(diǎn)之間的通信機(jī)制顽分,相對于第二代HOLD的開發(fā)簡單了很多。
Scheduler作為集群的管理調(diào)度中心例衍,主要功能包括:
???管理set艘狭,提供創(chuàng)建、刪除set囚霸、set內(nèi)節(jié)點(diǎn)替換等工作;
???所有的DDL操作統(tǒng)一下發(fā)和調(diào)度;
???監(jiān)控set內(nèi)各個(gè)節(jié)點(diǎn)的存活狀態(tài)腰根,當(dāng)set內(nèi)主節(jié)點(diǎn)故障,發(fā)起高一致性主備切換流程;
???監(jiān)控各個(gè)set的CPU拓型、磁盤容量额嘿、各個(gè)表的資源消耗情況,必要的時(shí)候自動(dòng)發(fā)起擴(kuò)容流程;
???Scheduler自身的容災(zāi)通過ZooKeqzer的選舉機(jī)制完成劣挫,保證中心控制節(jié)點(diǎn)無單點(diǎn)册养。
Agent模塊負(fù)責(zé)監(jiān)控本機(jī)MySQL實(shí)例的運(yùn)行情況,主要功能包括:
???用短連接的方式周期性訪問本機(jī)的MySQL實(shí)例压固,檢測是否可讀球拦、可寫,若發(fā)生異常帐我,會(huì)將異常信息上報(bào)到ZooKeeper坎炼,最終會(huì)由上面描述的Scheduler模塊檢測到這個(gè)異常情況,從而發(fā)起容災(zāi)切換;
???檢測主備復(fù)制的執(zhí)行情況焚刚,會(huì)定期上報(bào)主備復(fù)制的延時(shí)和延遲的事務(wù)數(shù)点弯,若發(fā)生了主備切換,自動(dòng)向新主機(jī)重建主備矿咕,因此MySQL的主備不需要DBA干預(yù)抢肛,對于新增的實(shí)例會(huì)自動(dòng)采用xtrabackup通過主機(jī)自動(dòng)重建數(shù)據(jù);
???檢測MySQL實(shí)例的CPU利用率和各個(gè)表的請求量狼钮、數(shù)據(jù)量、CPU利用率捡絮,上報(bào)到ZooKeeper熬芜,ZooKeeper通過全局的資源情況抉擇如何擴(kuò)容、縮容;
???監(jiān)控是否有下發(fā)到自身的擴(kuò)容任務(wù)福稳,如有則會(huì)執(zhí)行擴(kuò)容流程(下面會(huì)有描述);
???監(jiān)控是否要發(fā)生容災(zāi)切換涎拉,并按計(jì)劃執(zhí)行主備切換流程。
網(wǎng)關(guān)基于MySQL Proxy開發(fā)的圆,在網(wǎng)絡(luò)層鼓拧、連接管理、SQL解析越妈、路由等方面做了大量優(yōu)化季俩,主要特點(diǎn)和功能如下:
???解析SQL,將識別出的DDL語句直接存到ZooKeeper梅掠,讓Keeper來統(tǒng)一調(diào)度;
???Watch ZooKeeper的路由信息酌住,拉取最新的路由表保存到本地文件和內(nèi)存;
???將SQL請求路由到對應(yīng)的set,支持讀寫分離;
???對接入的IP阎抒、用戶名酪我、密碼進(jìn)行鑒權(quán);
???記錄完整的SQL執(zhí)行信息,與秒級監(jiān)控平臺對接完成實(shí)時(shí)的SQL請求的時(shí)耗且叁,成功率等指標(biāo)監(jiān)控分析;
???對count都哭、distinct、sum谴古、avg质涛、max稠歉、min掰担、order by、group by等聚合類SQL一般需要訪問后端的多個(gè)set怒炸,網(wǎng)關(guān)會(huì)分析結(jié)果并做合并再返回带饱,暫不支持跨set join和分布式事務(wù);
???網(wǎng)關(guān)無狀態(tài),既支持與業(yè)務(wù)部署到一起阅羹,也可以獨(dú)立部署(可通過TGW或者LVS做容災(zāi))勺疼。
自動(dòng)擴(kuò)容機(jī)制
目前,針對MySQL的擴(kuò)容捏鱼,一般有下面兩種策略执庐。
???垂直擴(kuò)容。一般通過升級硬件來實(shí)現(xiàn)导梆,比如更換更好的CPU轨淌,將傳統(tǒng)的sas盤換成FusionIO卡這類迂烁,然后針對新硬件調(diào)整好參數(shù),在硬件結(jié)構(gòu)變化比較大的時(shí)候递鹉,性能甚至能達(dá)到上十倍的提升盟步。但垂直擴(kuò)容有比較大的局限,就是這種模式隨著業(yè)務(wù)的突增還是比較容易達(dá)到瓶頸躏结,特別是面對互聯(lián)網(wǎng)海量用戶的時(shí)候却盘,所以在互聯(lián)網(wǎng)應(yīng)用場景下,一般僅將垂直擴(kuò)容當(dāng)做一個(gè)輔助的手段媳拴。
???水平擴(kuò)容黄橘。常用的有2種方法,一是不同的庫或者表部署到不同的實(shí)例屈溉,二是一張表需要根據(jù)某個(gè)字段拆分到不同的字表中(數(shù)據(jù)分片)旬陡,這種策略在互聯(lián)網(wǎng)系統(tǒng)中非常常見,很多系統(tǒng)會(huì)將這2種水平擴(kuò)容的方法結(jié)合起來使用;
通過上述2種擴(kuò)容方法的比較语婴,為了應(yīng)對海量擴(kuò)展的需求描孟,應(yīng)該是重點(diǎn)選用水平擴(kuò)容的方法。但水平擴(kuò)容的實(shí)現(xiàn)一般對業(yè)務(wù)是有感知的砰左,比如采用什么規(guī)則來拆表匿醒,拆開的表放到哪些節(jié)點(diǎn),如果某個(gè)子表還有瓶頸應(yīng)該怎么擴(kuò)容缠导,擴(kuò)容是否還需要業(yè)務(wù)配合等等這些事情如果全部交給業(yè)務(wù)會(huì)比較繁瑣廉羔,因此這些需求應(yīng)該盡量全部交給TDSQL自身來完成,對業(yè)務(wù)完全透明僻造。
分表邏輯
在TDSQL中憋他,每個(gè)表(邏輯表)可能會(huì)拆分成多個(gè)子表(建表的時(shí)候通過在建表語句中嵌入注釋的方式提供一個(gè)shard字段名,最多會(huì)拆分出1W個(gè)子表)髓削,每個(gè)子表在MySQL上都是一個(gè)真實(shí)的物理表竹挡,這里稱為一個(gè)shard,因此一張表的數(shù)據(jù)可能會(huì)按這樣的方式分布在多個(gè)Set中立膛,如圖2所示
每個(gè)SQL請求到達(dá)網(wǎng)關(guān)之后揪罕,網(wǎng)關(guān)會(huì)做詞法和語法解析,重點(diǎn)會(huì)解析出shard字段宝泵,如果帶了shard字段就可以直接查詢路由表并發(fā)送到某個(gè)具體的set中好啰。計(jì)費(fèi)的OLTP類業(yè)務(wù)99%的請求都會(huì)帶上shard字段;如果某筆請求沒有shard字段,查詢路由之后會(huì)將請求發(fā)送到所有的shard對應(yīng)的set中儿奶,并對所有返回的結(jié)果做一些聚合運(yùn)算框往。
擴(kuò)容流程
上面描述了shard的方式,但是這樣的shard結(jié)構(gòu)不是固定不變的闯捎,當(dāng)Scheduler檢測到某個(gè)set椰弊,某個(gè)表的CPU嘁酿、磁盤超過閾值之后就會(huì)啟動(dòng)擴(kuò)容流程。
這里描述下具體的擴(kuò)容流程男应。擴(kuò)容過程中一般都要盡量避免影響業(yè)務(wù)闹司,目前來看存在2種比較成熟的策略。
策略1先切后搬:先修改路由沐飘,將需要遷走的數(shù)據(jù)的請求直接發(fā)送到新set游桩,在新set交易過程中如發(fā)現(xiàn)本地的數(shù)據(jù)不存在,則去原set拉取數(shù)據(jù)耐朴,然后再通過一些離線的策略將要遷移的數(shù)據(jù)全量再搬遷一次借卧,HOID平臺就是采用這樣的策略。
策略2先搬后切:讓請求繼續(xù)在原set交易筛峭,擴(kuò)容程序首先記錄一個(gè)binlog位置點(diǎn)铐刘,并將源set中符合遷移條件的數(shù)據(jù)全部遷移出去,最后再將搬遷過程中新增的binlog追完影晓,最后修改路由規(guī)則镰吵,將請求發(fā)送到新set。
綜合來看挂签,策略1最大的優(yōu)點(diǎn)是假如是因?yàn)閴毫Υ笞龅倪w移疤祭,可能很快就能將部分請求發(fā)送新set了,實(shí)現(xiàn)對原set的壓力分擔(dān);策略2實(shí)現(xiàn)上在最后的追路由階段需要更多的精細(xì)化控制饵婆,實(shí)現(xiàn)會(huì)稍微復(fù)雜點(diǎn)勺馆,但策略2有個(gè)非常大的好處就是擴(kuò)容過程中回滾非常方便,如有異常直接干掉擴(kuò)容任務(wù)即可侨核。
對于TDSQL這類數(shù)據(jù)庫業(yè)務(wù)系統(tǒng)來說草穆,策略1實(shí)現(xiàn)會(huì)非常麻煩,因?yàn)檎埱蟮竭_(dá)新set之后可能需要去源set拉取數(shù)據(jù)搓译,這個(gè)需要對MySQL本身進(jìn)行修改;另外假如一個(gè)批量更新的update操作悲柱,可能要往新老set都發(fā)送一次請求,比較復(fù)雜侥衬,所以最終選擇了策略2诗祸。策略2會(huì)有更大的通用性,開發(fā)模式基本上可以統(tǒng)一到所有類似的系統(tǒng)轴总。
下面描述采用策略2具體的擴(kuò)容流程。假如要將Set1中的t_shard_1的數(shù)據(jù)遷移一半到Set4中的t_shard_4(1667-3333)博个。
Scheduler首先在Set4中創(chuàng)建好表t_shard_4怀樟。
后將擴(kuò)容任務(wù)下發(fā)到Set1中的agent模塊,agent檢測到擴(kuò)容任務(wù)之后會(huì)采用mysqldump+where條件的方式將t_shard_1中shard號段為1667-3333的記錄導(dǎo)出來并通過管道用并行的方式插入到Set4(不會(huì)在本地存文件盆佣,避免引起過多的IO)往堡,用mysqldump導(dǎo)出鏡像的時(shí)候會(huì)有一個(gè)binlog位置械荷。
從mysqldump記錄的binlog位置開始讀取binlog并插入到到Set4,追到所有binlog文件末尾的時(shí)候(這需要一個(gè)循環(huán)虑灰,每次循環(huán)記錄從開始追binlog截止到追到文件結(jié)尾消耗的時(shí)間吨瞎,必須保證追單次循環(huán)要在幾秒之內(nèi)完成,避免遺留的binlog太多導(dǎo)致最后一次追binlog消耗太多的時(shí)間穆咐,從而影響業(yè)務(wù)過久)颤诀,對原來的表t_shard_1重命名t_shard_5,此時(shí)針對這個(gè)表不會(huì)再有新請求对湃,若還有請求過來都會(huì)失敗崖叫,然后再追一次binlog到文件結(jié)尾(因?yàn)樯厦娴难h(huán)保證了追binlog不會(huì)太耗時(shí)間了,所以此次會(huì)快速完成)拍柒,然后上報(bào)狀態(tài)到ZooKeeper心傀,表明擴(kuò)容任務(wù)完成。
Scheduler收到擴(kuò)容完成的信息之后會(huì)修改路由表拆讯,最后由網(wǎng)關(guān)拉取到新路由完成整體的擴(kuò)容;從表重命名開始到網(wǎng)關(guān)拉取到新路由脂男,這段時(shí)間這個(gè)原始shard不可用,從我們測試結(jié)果來看這個(gè)不可用的時(shí)間是200毫秒左右;如果某個(gè)網(wǎng)關(guān)異常种呐,拉取不到新路由疆液,繼續(xù)訪問老表t_shard_1會(huì)一直失敗,這樣就可以保證數(shù)據(jù)的一致性陕贮。
容災(zāi)機(jī)制
對于TDSQL來說堕油,我們希望容災(zāi)做到自動(dòng)切換,自動(dòng)恢復(fù)肮之,主備一致性(保證業(yè)務(wù)提交的事務(wù)在切換過程不丟失)掉缺,跨IDC容災(zāi)。
【MySQL異步復(fù)制】
在MySQL發(fā)展的早期戈擒,就提供了異步復(fù)制的技術(shù)眶明,只要寫的壓力不是特別大,在網(wǎng)絡(luò)條件較好的情況下筐高,發(fā)生主備切換基本上能將影響控制到秒級別搜囱,因此吸引了很多開發(fā)者的關(guān)注和使用。但這套方案提供的一致性保證柑土,對于計(jì)費(fèi)或者金融行業(yè)是不夠的蜀肘。
圖4是異步復(fù)制的大致流程,很顯然主機(jī)提交了binlog就會(huì)返回給業(yè)務(wù)成功稽屏,沒有保證binlog同步到了備機(jī)扮宠,這樣在切換的瞬間很有可能丟失這部分事務(wù)。
【MySQL半同步復(fù)制】
到了MySQL5.5版本的時(shí)候狐榔,Google提供了一個(gè)半同步半異步的插件坛增,確保必須收到一個(gè)備機(jī)的應(yīng)答才讓事務(wù)在主機(jī)中提交;當(dāng)備機(jī)應(yīng)答超時(shí)的情況下获雕,強(qiáng)同步就會(huì)自動(dòng)退化成異步模式(這也是半同步半異步名字的由來)。
這套方案相對異步復(fù)制收捣,在數(shù)據(jù)的可靠性方面確實(shí)好很多届案,在主機(jī)本身故障的情況下,基本能保證不丟失事務(wù)(因?yàn)樽詈笠粋€(gè)事務(wù)罢艾,至少有一個(gè)備機(jī)上存在)楣颠,但一旦退化成異步復(fù)制就回到過去了。TDSQL沒直接采用這套方案昆婿,是因?yàn)椋涸谥鱾淇鏘DC(ping延遲2-3毫秒)時(shí)性能非常很低球碉。
【Cluster方案】
除了上面的方案外,開源社區(qū)還有三個(gè)Cluster解決方案仓蛆,分別是Oracle的NDB引擎睁冬、Percona XtraDB Cluster和MariaDB GaleraCluster,從公開資料的性能對比上來看看疙,后2者在性能和系統(tǒng)靈活性等方面都強(qiáng)于NDB(同時(shí)采用NDB意味著也放棄了InnoDB引擎豆拨,NDB主要是基于全內(nèi)存的,并且需要高速網(wǎng)絡(luò)環(huán)境支持能庆,所以不考慮了);PerconaXtraDB Cluster和MariaDB Galera Cluster強(qiáng)同步機(jī)制的底層都是采用Galera這套強(qiáng)同步的架構(gòu)施禾。
MariaDB GaleraCluster具有如下非常吸引人的特性:
???MariaDB Galera Cluster 是一套在MySQL InnoDB存儲引擎上面實(shí)現(xiàn)multi-master及數(shù)據(jù)實(shí)時(shí)同步的系統(tǒng)架構(gòu),業(yè)務(wù)層面無需做讀寫分離工作搁胆,數(shù)據(jù)庫讀寫壓力都能按照既定的規(guī)則分發(fā)到各個(gè)節(jié)點(diǎn)上去;
???同步復(fù)制Synchronous replication:保證節(jié)點(diǎn)間數(shù)據(jù)一致性;
???Active-active multi-master拓?fù)溥壿嫞憾嘀鞯耐負(fù)浣Y(jié)構(gòu)弥搞,可以認(rèn)為沒有備機(jī)的概念;
???可對集群中任一節(jié)點(diǎn)進(jìn)行數(shù)據(jù)讀寫:假如一個(gè)set有3個(gè)節(jié)點(diǎn),則3個(gè)節(jié)點(diǎn)可以同時(shí)讀寫渠旁,上次完全不用關(guān)心主備切換和讀寫分離;
???自動(dòng)成員控制攀例,故障節(jié)點(diǎn)自動(dòng)從集群中移除;
???自動(dòng)節(jié)點(diǎn)加入;
???真正并行的復(fù)制,基于行級:同一個(gè)表可以在集群中任何節(jié)點(diǎn)更新顾腊,支持不帶where條件粤铭,但一次更新的記錄條數(shù)有限制;
???每個(gè)節(jié)點(diǎn)都包含完整的數(shù)據(jù)副本。
目前來看杂靶,Galera是一套相當(dāng)完美的方案梆惯。但是,在跨IDC的性能測試中吗垮,其性能下降比較大垛吗,另外,實(shí)現(xiàn)方案也比較復(fù)雜抱既,目前對它的代碼理解還不夠透徹职烧,所以暫時(shí)沒有在計(jì)費(fèi)領(lǐng)域大范圍推廣使用。但我相信這個(gè)方向是對的防泵,有吸引力的蚀之,隨著后續(xù)Galera越來越完善,我們對它研究得越透徹捷泞,也許有一天會(huì)采用這套方案足删。
【性能測試和分析】
上面的三種復(fù)制模式對比測試,數(shù)據(jù)如圖6所示锁右。
從圖6的數(shù)據(jù)可以看出失受,半同步和Galera模式對性能的損耗還是非常大的,Galera的毛刺尤其嚴(yán)重咏瑟,所以在跨IDC環(huán)境下還不是適合計(jì)費(fèi)這樣對延遲要求非常低的場景拂到。
為什么性能損耗會(huì)這么嚴(yán)重呢?這個(gè)看明白MySQL的網(wǎng)絡(luò)模型就清楚了。外界可查的MySQL最早的公開版本應(yīng)該是1996年的3.1.1.1版本码泞,這么多年來兄旬,網(wǎng)絡(luò)模型基本上變化不大,與Apache有點(diǎn)類似余寥,有點(diǎn)區(qū)別的是MySQL采用的是每個(gè)連接一個(gè)線程的模型领铐,這套模型最大的好處就是開發(fā)特別簡單,線程內(nèi)部都是同步調(diào)用宋舷,只要不訪問外部接口绪撵,支撐每秒幾百上千的請求量也基本夠用,因?yàn)榇蟛糠智闆r下IO是瓶頸祝蝠。不過隨著當(dāng)前硬件的發(fā)展音诈,尤其是SSD、FusionIO的出現(xiàn)绎狭,IOPS從200+/s進(jìn)化到幾十萬甚至百萬次/s细溅,IO基本上不再是瓶頸,若再采用這套模型并采用阻塞的方式調(diào)用延遲較大的外部接口坟岔,則CPU都會(huì)阻塞在等網(wǎng)絡(luò)應(yīng)答上了谒兄,性能自然上不去。
不過在MySQL5.6企業(yè)版和MariaDB社付、Percona中都引入了線程池承疲,使得網(wǎng)絡(luò)模型靈活了很多,圖7是簡化后的對比模型鸥咖。
TDSQL采用的強(qiáng)同步方案
從上面的分析可知燕鸽,半同步半異步是比較輕量級的高一致性容災(zāi)方案,但受限于已有的同步網(wǎng)絡(luò)模型啼辣,CPU利用不起來啊研。我們?nèi)绻诰€程池基礎(chǔ)之上做一些修改,參考半同步的思路就可以實(shí)現(xiàn)一個(gè)高性能的強(qiáng)同步方案。
目前的做法是采用與Linux內(nèi)核處理中斷的思路:將上面線程池模型的第三個(gè)環(huán)節(jié)(執(zhí)行SQL的邏輯)拆成兩個(gè)部分:
???上半部分:任務(wù)執(zhí)行到寫binlog為止党远,然后將會(huì)話保存到session中削解,接著執(zhí)行下一輪循環(huán)去處理其他請求了,這樣就避免讓線程阻塞等待應(yīng)答了;
???然后:MySQL自身負(fù)責(zé)主備同步的dump線程會(huì)將binlog立即發(fā)送出去沟娱,備機(jī)的IO線程收到binlog并寫入到relay
log之后氛驮,再通過UDP給主機(jī)一個(gè)應(yīng)答;
???在主機(jī)上,開一組線程來處理應(yīng)答济似,收到應(yīng)答之后找到對應(yīng)的會(huì)話矫废,執(zhí)行下半部分的commit,send應(yīng)答砰蠢,綁定到epoll等操作蓖扑。綁定到epoll之后這個(gè)連接又可以被其他線程檢測到并執(zhí)行了。
改造后性能提升明顯台舱,如圖8所示律杠。
數(shù)據(jù)高可用性保障機(jī)制
除上述強(qiáng)同步機(jī)制外,TDSQL還做了以下增強(qiáng)柿赊,以提升數(shù)據(jù)的可用性俩功。
???推薦一個(gè)set最少配置3個(gè)跨IDC的節(jié)點(diǎn),可以按業(yè)務(wù)的要求對備機(jī)開放查詢服務(wù)碰声。
???支持靈活增加節(jié)點(diǎn)诡蜓,比如覺得3個(gè)節(jié)點(diǎn)還不夠,可以非常方便地增加節(jié)點(diǎn)胰挑。TDSQL會(huì)自動(dòng)完成數(shù)據(jù)的全量和增量復(fù)制蔓罚,此處主要依賴Xtrabackup實(shí)現(xiàn)物理復(fù)制,性能測試數(shù)據(jù)表明:一個(gè)小時(shí)大概可以拷貝500GB數(shù)據(jù)到新節(jié)點(diǎn)瞻颂。那么對于Z3(1.1TB盤豺谈,一般最多用800GB左右),新加入的節(jié)點(diǎn)大概1.5個(gè)小時(shí)左右就有了全量數(shù)據(jù)贡这,此功能也可以用在壞盤等情況下替換節(jié)點(diǎn)的時(shí)候使用茬末,非常方便。
???細(xì)心的同學(xué)可能會(huì)發(fā)現(xiàn)上面的強(qiáng)同步還有點(diǎn)小缺陷:比如主機(jī)用kill-9殺掉盖矫,那么可能寫了binlog但沒有來得及發(fā)送到遠(yuǎn)端丽惭,此時(shí)當(dāng)然也不會(huì)返回給業(yè)務(wù)成功,備機(jī)上不存在這筆數(shù)據(jù)辈双,但主機(jī)起來之后會(huì)多出來這筆事務(wù)责掏。我們的做法是對新增的事務(wù)根據(jù)row格式的binlog做閃回,當(dāng)然回退不了的比如drop
table之類的湃望,就直接提醒運(yùn)維手工確認(rèn)是否清除數(shù)據(jù)庫换衬,然后會(huì)由Xtrabakcup機(jī)制自動(dòng)從新的備機(jī)全量拉取數(shù)據(jù)重構(gòu)痰驱。
???節(jié)點(diǎn)的監(jiān)控通過跨IDC部署的ZooKeeper來保證,并且主備切換由一套自動(dòng)化的嚴(yán)格流程來保證瞳浦。
接下來的方向
???當(dāng)將高一致性容災(zāi)担映、高可用性、自動(dòng)容量伸縮做實(shí)后术幔,隨著業(yè)務(wù)的接入另萤,集群的規(guī)模會(huì)越來越大湃密,TDSQL必將會(huì)更加依賴實(shí)時(shí)的資源調(diào)度诅挑、隔離框架,因此有必要研究如何將TDSQL與Docker結(jié)合起來泛源。
???如前所述拔妥,Galera集群是個(gè)非常好的發(fā)展方向,我們會(huì)持續(xù)研究并實(shí)踐达箍。
???目前大部分MySQL還在使用單個(gè)連接單線程模型没龙,線程池也剛起步,以后隨著大家對性能要求越來越高缎玫,這塊也許可以繼續(xù)突破硬纤,比如結(jié)合線程池+協(xié)程也許是個(gè)很好的方向,如果真能引入?yún)f(xié)程赃磨,也許為MySQL增加調(diào)用外部接口的結(jié)構(gòu)會(huì)靈活很多筝家。
???TDSQL將數(shù)據(jù)拆是拆的徹底了,但作為完整的分布式數(shù)據(jù)庫邻辉、合也需要考慮溪王,比如跨庫少量記錄的join,規(guī)模受限的分布式事務(wù)等值骇,目前的做法是數(shù)據(jù)按小時(shí)入TDW莹菱,在TDW上做OLAP分析。