熊游泳
摘要:隨著4G網(wǎng)絡(luò)和移動互聯(lián)網(wǎng)業(yè)務(wù)的迅猛發(fā)展,面對海量數(shù)據(jù)處理、高并發(fā)交易的壓力,傳統(tǒng)的集中式數(shù)據(jù)庫如Oracle基本不支持大規(guī)模自動擴(kuò)展,逐漸表現(xiàn)出其局限性。中國電信基于開源的Mysql數(shù)據(jù)庫和Mycat分布式數(shù)據(jù)庫中間件,結(jié)合企業(yè)實際,自主研發(fā)的分布式數(shù)據(jù)庫系統(tǒng)在湖南電信IT系統(tǒng)中得到廣泛應(yīng)用,解決了海量交易型業(yè)務(wù)數(shù)據(jù)的存儲和高效訪問的難題,實現(xiàn)了低成本、高性能、高可用、高擴(kuò)展,有利的支撐了企業(yè)IT架構(gòu)互聯(lián)網(wǎng)化轉(zhuǎn)型。
關(guān)鍵詞:MySQL;Mycat;分布式數(shù)據(jù)庫
中圖分類號:TP391 文獻(xiàn)標(biāo)識碼:A
文章編號:1009-3044(2019)32-0018-05
1概述
湖南電信自1995年“九七工程”建設(shè)第一個IT系統(tǒng)開始,截止到2017年底,已建成的IT系統(tǒng)達(dá)到288套。其中近95%的系統(tǒng)使用的是Oracle RAC數(shù)據(jù)庫。進(jìn)入互聯(lián)網(wǎng)時代以來,特別是近幾年,隨著4G網(wǎng)絡(luò)和移動互聯(lián)網(wǎng)業(yè)務(wù)的迅猛發(fā)展,電信核心系統(tǒng)數(shù)據(jù)量均出現(xiàn)了大規(guī)模的增長,以計費系統(tǒng)為例,每月的清單數(shù)據(jù)量從2014年的5TB增長到2019年的30TB,5年時間數(shù)據(jù)量增長近6倍,由于原有系統(tǒng)Oracle RAC的shared ev-erything的架構(gòu),10的處理能力及擴(kuò)展能力有限,并且隨著節(jié)點數(shù)的增加,數(shù)據(jù)庫系統(tǒng)的穩(wěn)定性和高性能難以保障。因此,海量數(shù)據(jù)的存儲、處理與訪問成為當(dāng)時湖南電信乃至整個中國電信IT系統(tǒng)設(shè)計與使用中亟待解決的問題。
中國電信自2017年開始,對標(biāo)業(yè)界領(lǐng)先公司,采用主流互聯(lián)網(wǎng)公司技術(shù)路線,基于開源的Mysql數(shù)據(jù)庫和Mycat分布式數(shù)據(jù)庫中間件,結(jié)合企業(yè)實際,自主研發(fā)了高性能、高可用、高擴(kuò)展的分布式數(shù)據(jù)庫,在低成本、可擴(kuò)展、快速響應(yīng)等方面擁有巨大優(yōu)勢,成為湖南電信企業(yè)級rr架構(gòu)的發(fā)展方向。
2分布式數(shù)據(jù)庫概念的提出
Oracle、Mysql等傳統(tǒng)的關(guān)系數(shù)據(jù)庫非常成熟并且已大規(guī)模商用,為什么還要用分布式數(shù)據(jù)庫呢?主要是由于中國互聯(lián)網(wǎng)業(yè)務(wù)的迅猛發(fā)展,所生成的海量數(shù)據(jù)對存儲、處理、訪問的性能要求越來越高,傳統(tǒng)數(shù)據(jù)庫存在著先天性的缺陷,即單機(jī)性能有限,擴(kuò)展困難,且隨著節(jié)點數(shù)的增加,數(shù)據(jù)庫系統(tǒng)的穩(wěn)定性和高性能難以保障,已經(jīng)無法滿足海量數(shù)據(jù)存儲及高性能訪問的要求。因此,業(yè)界提出了分布式數(shù)據(jù)庫的概念。簡單來說,分布式數(shù)據(jù)庫是采用分庫分表等數(shù)據(jù)切分的方式提供可擴(kuò)展的數(shù)據(jù)存儲,并且采用數(shù)據(jù)庫代理方式為應(yīng)用提供透明訪問及平滑擴(kuò)縮容能力,包括數(shù)據(jù)的存儲與數(shù)據(jù)的訪問兩部分的內(nèi)容。
3分布式數(shù)據(jù)庫的數(shù)據(jù)切分
分布式數(shù)據(jù)庫的數(shù)據(jù)存儲通過數(shù)據(jù)切分的方式,按照特定的規(guī)則,將一個數(shù)據(jù)庫中的數(shù)據(jù)分散存放到多個數(shù)據(jù)庫里面,從而將單臺數(shù)據(jù)庫的負(fù)載分散到多個數(shù)據(jù)庫。
數(shù)據(jù)的切分可以分為垂直切分與水平切分兩種切分模式。按照業(yè)務(wù)的不同,對表進(jìn)行分類,不同業(yè)務(wù)的表切分到不同的數(shù)據(jù)庫稱為垂直切分;按照表中某個字段的特定規(guī)則將數(shù)據(jù)分散到多個庫之中,每個表都包含部分?jǐn)?shù)據(jù),稱為水平切分。水平切分可以理解為是按照數(shù)據(jù)行進(jìn)行的切分,表中的一部分行切分到一個數(shù)據(jù)庫,而另外的一部分行又切分到其他的數(shù)據(jù)庫中,分布式數(shù)據(jù)庫一般使用的是水平切分的方式。
垂直切分一般來說規(guī)則比較簡單,實施比較方便,對于業(yè)務(wù)邏輯清晰,業(yè)務(wù)之間的耦合度較低的系統(tǒng)尤其適合。在湖南電信BSS3.0系統(tǒng)中就按照相對獨立的業(yè)務(wù)垂直切分為受理中心數(shù)據(jù)庫、賬務(wù)中心數(shù)據(jù)庫、計費中心數(shù)據(jù)庫、策略中心數(shù)據(jù)庫、客服中心數(shù)據(jù)庫等。由于垂直切分是按照不同的業(yè)務(wù)的分類將表分散到不同的庫,不可避免地存在一些業(yè)務(wù)表會過于龐大、單庫讀寫性能與存儲瓶頸的問題,例如經(jīng)過垂直切分后的計費中心數(shù)據(jù)庫依然存在單表數(shù)據(jù)量過大的問題,此時就需要進(jìn)行進(jìn)一步的水平拆分來做解決。
水平切分相對于垂直切分來說,由于要將同一個表中的不同數(shù)據(jù)拆分到不同的數(shù)據(jù)庫中,拆分規(guī)則及后期的數(shù)據(jù)維護(hù)及數(shù)據(jù)訪問也會更為復(fù)雜一些。在數(shù)據(jù)的水平切分過程中,數(shù)據(jù)容量和訪問的均衡性是我們首要考量的因素,不均衡的數(shù)據(jù)分布和訪問無法充分發(fā)揮數(shù)據(jù)拆分的能力,讓訪問體驗變差,同時帶來成本上的損耗。一般來說拆分字段區(qū)分度比較大,數(shù)據(jù)分布和訪問相對會比較均衡,同時也需要考慮到某一個拆分值是否存在熱點訪問的問題。此外,事務(wù)邊界越大或者單個sql所執(zhí)行的數(shù)據(jù)分片數(shù)越大,那么系統(tǒng)的鎖沖突概率越高,系統(tǒng)越難以擴(kuò)展,性能越低。因此,若想將系統(tǒng)做到很好的擴(kuò)展性,那么一個最重要的原則就是想辦法劃小事務(wù)邊界,并盡可能讓事務(wù)的邊界限制在單臺機(jī)器內(nèi)。
3.1數(shù)據(jù)切分的原則
分表分庫雖然能解決大表對數(shù)據(jù)庫系統(tǒng)的壓力,但它并不是萬能的,也有一些不利之處,通過結(jié)合在湖南電信的應(yīng)用實踐,數(shù)據(jù)切分一般要遵守以下幾個原則。
分片數(shù)量盡量少,分片盡量均勻分布在多個庫上,因為一個查詢SQL跨分片越多,則總體性能越差,只在必要的時候進(jìn)行擴(kuò)容,增加分片數(shù)量。
能不分片就不分片,800萬行以內(nèi)的表,不建議分片,通過合適的索引,讀寫分離等方式,可以很好地解決性能問題。
不到800萬但跟大表(超800萬的表)有關(guān)聯(lián)查詢的表也要拆分,在此稱為大表關(guān)聯(lián)表。大表關(guān)聯(lián)表如何拆:小于100萬的使用全局表;大于100萬小于800萬跟大表使用同樣的拆分策略;無法跟大表使用相同規(guī)則的,可以考慮從iava代碼上分步驟查詢,不用關(guān)聯(lián)查詢,或者破例使用全局表。
拆分字段只能是一個字段,如果想按照兩個字段拆分,必須新建一個冗余字段,冗余字段的值使用兩個字段的值拼接而成(如大xE+年月拼成zone_yyyymm字段)。
分片規(guī)則需要慎重選擇,分片規(guī)則的選擇,需要考慮數(shù)據(jù)的增長模式,數(shù)據(jù)的訪問模式,分片關(guān)聯(lián)性問題,分片擴(kuò)容問題以及數(shù)據(jù)熱點問題。如果某個表的數(shù)據(jù)有明顯的時間特征,比如訂單、交易記錄等,則他們通常比較合適用時間范圍分片,因為具有時效性的數(shù)據(jù),我們往往關(guān)注其近期的數(shù)據(jù),查詢條件中往往帶有時間字段進(jìn)行過濾,比較好的方案是,當(dāng)前活躍的數(shù)據(jù),采用跨度比較短的時間段進(jìn)行分片,而歷史性的數(shù)據(jù),則采用比較長的跨度存儲??傮w上來說,分片的選擇是取決于最頻繁的查詢SQL的條件。
3.2水平切分的常用算法
水平切分的算法根據(jù)分片鍵類型的不同主要有以下幾種:
取模分片(PartitionByMod)是對整數(shù)型分片鍵進(jìn)行十進(jìn)制求模,根據(jù)模值對應(yīng)到不同分片。適用于分片鍵是整數(shù)類型,分片鍵求余后的值均勻分布的場景。其特點是算法簡單,性能高,由于分片鍵相鄰的數(shù)據(jù)分散在不同的分片上故對多值、范圍的查詢支持較差。
字符串hashCode取模分片(PartitionByStringMod)是對字符型分片字段的值先進(jìn)行hashcode()計算并取其絕對值,然后根據(jù)配置的分片數(shù)量求模得到最終的分片。由于是對字符串先hash再取模,數(shù)據(jù)分布較不均勻。
枚舉分片(PartitionByFileMap)是根據(jù)配置文件中枚舉的具體值(允許非數(shù)值)與分片號的對應(yīng)關(guān)系和分片字段的值進(jìn)行分片,當(dāng)未找到對應(yīng)分片時,進(jìn)入到設(shè)定的默認(rèn)分片。數(shù)據(jù)分布的均勻度取決于枚舉值對應(yīng)的記錄是否分布均勻,較好的支持多值、范圍的查詢。電信有些業(yè)務(wù)數(shù)據(jù)需要按照省份或市縣來做保存,而省份市縣相對固定,適合于使用這個分片算法。
時間范圍分片(PartitionByDat-eRange)是按照時間范圍進(jìn)行分片,超過分片數(shù)量后從第一個分片再次循環(huán)分片。適用于按時間范圍進(jìn)行存儲的數(shù)據(jù)。
枚舉分組取模分片(PartitionByEnumAndMod)是枚舉+取模的組合分片方式,包含枚舉鍵和取模鍵兩個分片鍵,先通過枚舉鍵將數(shù)據(jù)分配到不同的分組,再在分組里通過取模鍵對應(yīng)到具體的分片。
4數(shù)據(jù)庫中間件
要實現(xiàn)對應(yīng)用透明的分布式數(shù)據(jù)庫的訪問,離不開數(shù)據(jù)庫中間件。簡單來說,數(shù)據(jù)庫中間件就是介于數(shù)據(jù)庫與應(yīng)用之間,進(jìn)行數(shù)據(jù)處理與交互的中間服務(wù)。由于對數(shù)據(jù)進(jìn)行水平切分處理之后,原來一個表的數(shù)據(jù)現(xiàn)在分布到多個庫的多個表里,應(yīng)用不可避免的需要訪問多個數(shù)據(jù)庫的數(shù)據(jù)并進(jìn)行匯聚處理。如果沒有數(shù)據(jù)庫中間件,那么應(yīng)用將直接面對分片集群,數(shù)據(jù)源切換、事務(wù)處理、數(shù)據(jù)聚合都需要應(yīng)用直接處理,原本該是專注于業(yè)務(wù)的應(yīng)用,將會花大量的工作來處理分片后的問題。所以有了數(shù)據(jù)庫中間件,應(yīng)用只需要集中于業(yè)務(wù)處理,而數(shù)據(jù)聚合,事務(wù),數(shù)據(jù)源切換都由中間件來完成,數(shù)據(jù)庫中間件可以看作一個或多個數(shù)據(jù)庫集群構(gòu)成的邏輯庫,而對實際應(yīng)用來說,并不需要知道中間件的存在。
5電信自研的分布式數(shù)據(jù)庫
5.1系統(tǒng)架構(gòu)
電信自研的分布式數(shù)據(jù)庫由統(tǒng)一數(shù)據(jù)訪問層TeleUDAL及高可用數(shù)據(jù)庫TeleDB兩部分組成。TeleDB基于開源關(guān)系型數(shù)據(jù)庫MySQL改造,提供高可靠的數(shù)據(jù)存儲能力;數(shù)據(jù)訪問基于開源數(shù)據(jù)庫中間件Cobar改造,屏蔽數(shù)據(jù)庫分庫分表帶來的訪問難題。
系統(tǒng)架構(gòu)圖如圖1所示。
從圖1可看出,TeleUDAL主要由LVS、DBProxy、GiServer組件組成。
LVS為DBProxy提供服務(wù)注冊發(fā)現(xiàn)及負(fù)載均衡功能,應(yīng)用發(fā)送的請求通過LVS均衡分布到各個DBProxy上。
DBProxy是TeleUDAL的核心組件,是一個實現(xiàn)了mysql協(xié)議的Sever進(jìn)程,前端用戶可以把DBProxy看成數(shù)據(jù)庫代理,可用mysql客戶端工具或命令行方式直接訪問,其后端以mysql原生協(xié)議與多個mysql數(shù)據(jù)庫進(jìn)行通信,也可以用jdbc協(xié)議與大多數(shù)主流數(shù)據(jù)庫服務(wù)器通信,DBProxy的核心功能是分庫分表并對應(yīng)用層屏蔽分庫分表帶來的訪問難題。
GiServer是切片索引服務(wù)進(jìn)程,是為了提升非分片鍵查詢(select語句)時的效率(避免廣播查詢)而開發(fā)的,與數(shù)據(jù)庫的索引沒有任何關(guān)系,是完全不同的兩個概念,GiServer是切片索引數(shù)據(jù)的生產(chǎn)者,真正的消費者是DBProxy進(jìn)程,假設(shè)客戶表是以cust_id進(jìn)行分表的,但應(yīng)用需要通過客戶身份證來查詢客戶信息,如果沒有切片索引,則DBProxy會將查詢語句廣播到所有節(jié)點執(zhí)行,接收到執(zhí)行結(jié)果進(jìn)行匯聚后再返回給應(yīng)用,如果建立了切片索引,則DBProxy首先會根據(jù)身份證號碼從切片索引中查詢到對應(yīng)的cust_id,再根據(jù)分片算法定位到cust_id對應(yīng)的分片,這樣就避免了廣播查詢。
除此之外,UDAL依賴的外部組件主要有zookeeper及分布式緩存,zookeeper用于存放DBProxy、GiServer的配置信息及全局序列數(shù)據(jù),分布式緩存用于存放切片索引數(shù)據(jù)。
5.2關(guān)鍵概念
電信分布式數(shù)據(jù)庫中涉及邏輯庫、邏輯表、切片索引、全局序列等幾個關(guān)鍵概念。
邏輯庫(schema),對實際應(yīng)用來說,并不需要知道中間件的存在,應(yīng)用開發(fā)人員只需要知道數(shù)據(jù)庫的概念,所以數(shù)據(jù)庫中間件可以被看作一個或多個數(shù)據(jù)庫集群構(gòu)成的邏輯庫。UDAL的邏輯庫(schema),與MySQL中的Database(數(shù)據(jù)庫)對應(yīng),一個邏輯庫中定義了所包括的table。
邏輯表(table),對應(yīng)用來說,所操作的表就是邏輯表,可以是數(shù)據(jù)切分后,分布多個分片庫中,也可以不做切分,存放在單個分片中,在UDAL中邏輯表包括:單片表、分片表、全局表、庫內(nèi)分表四種類型的表。
單片表是相對分片表來說的,就是指那些不需要作數(shù)據(jù)切分的表,一個數(shù)據(jù)庫中并不是所有表都很大,某些表是可以不用進(jìn)行切分的。
分片表是指那些原有的很大數(shù)據(jù)的表,需要切分到多個數(shù)據(jù)庫的表,這樣,每個分片都有一部分?jǐn)?shù)據(jù),所有分片構(gòu)成完整的數(shù)據(jù)。
全局表是在每個分片庫都中保存一份同樣數(shù)據(jù)的表,主要解決跨庫關(guān)聯(lián)查詢問題。這類表的數(shù)據(jù)量一般較小,變化不頻繁,如:字典、配置、工號、機(jī)表、區(qū)域等,其特點主要是變動不頻繁,數(shù)據(jù)量總體變化不大且數(shù)據(jù)量較小,全局表的插入、更新操作會同步在所有節(jié)點上執(zhí)行,全局表的查詢操作,只從一個節(jié)點獲取,全局表可以跟任何一個表進(jìn)行JOIN操作。對全局表執(zhí)行update、delete、insert等DML操作時,需要保障這些DML語句在所有節(jié)點同步執(zhí)行成功,由于全局表的每條語句都需要分發(fā)到所有節(jié)點執(zhí)行,這樣就形成了跨節(jié)點分布式事務(wù),在UDAL中我們采用事務(wù)補(bǔ)償機(jī)制來保障全局表數(shù)據(jù)的最終一致性。DB-Proxy檢測事務(wù)中的第一條DML語句是全局表時,會自動開啟分布式事務(wù)如果有節(jié)點commit失敗,DBProxy會進(jìn)行自動補(bǔ)償。
切片索引fgiserver)是一組非分片鍵和分片鍵的映射關(guān)系,目的是提升非分片鍵查詢(select語句)時的效率,避免廣播查詢。當(dāng)沒有切片索引時,select語句中如果沒有帶分片鍵,db-proxy無法計算出分片節(jié)點,這樣語句會廣播到所有節(jié)點執(zhí)行。如果有切片索引,先通過非分片鍵查詢到分片鍵的值,根據(jù)分片鍵的值計算出路由節(jié)點,再把語句發(fā)送到相應(yīng)的分片執(zhí)行,避免了廣播查詢。GiServer的原理是基于mysql binlog技術(shù),模擬自己為mysql slave,所以一定要開啟mysql的binlog功能,并配置binlog模式為row.數(shù)據(jù)處理流程如圖2所示。
全局序列是在整個邏輯庫層面實現(xiàn)了全局唯一的序列。在分布式數(shù)據(jù)庫場景下,一個邏輯庫對應(yīng)了多個物理數(shù)據(jù)庫分片,邏輯庫表的主鍵要求在所有物理庫分片上都唯一,這樣用數(shù)據(jù)庫本身的機(jī)制生成序列號就無法滿足業(yè)務(wù)的需求了,必須采用新的全局序列生成機(jī)制。我們TeleUDAL的實現(xiàn)原理是DBProxy從ZooKeeper上獲取序列段保存到本地內(nèi)存,同時修改ZooKeeper上下一次獲取序列段的起始值,本地內(nèi)存中的序列用完后再從zk獲取新的序列段。全局序列的使用與ora]ce的sequence使用類似,先創(chuàng)建好sequence,再通過select XXX.next-val獲取序列值。為保證序列獲取的效率,dbproxy會緩存一段序列,這樣在一個集群中存在多個dbproxy的情況下不能保證序列是嚴(yán)格遞增的。
5.3 TeleUDAL簡單原理
TeleUDAL究竟是如何實現(xiàn)數(shù)據(jù)的水平拆分及對應(yīng)用透明的數(shù)據(jù)訪問的呢?下面簡要說明其實現(xiàn)原理。
1)數(shù)據(jù)的拆分及存儲
分片鍵是數(shù)據(jù)進(jìn)行拆分的分片字段,是UDAL中數(shù)據(jù)分布和SQL路由的計算依據(jù)。UDAL中的數(shù)據(jù)按照拆分字段值,加上特定的算法進(jìn)行計算,根據(jù)結(jié)果存儲數(shù)據(jù)到對應(yīng)分片。如圖3所示,左表使用MEMBE_ID作為分片鍵,表中數(shù)據(jù)根據(jù)字符串hash取模算法分散到庫1和2中。
2)SQL路由
當(dāng)用戶SQL到UDAL時,UDAL會理解整個SQL含義,然后按照拆分字段的值和執(zhí)行策略將SQL路由到對應(yīng)分區(qū)進(jìn)行執(zhí)行,如圖4所示。
3)數(shù)據(jù)匯聚
如果一個SQL對應(yīng)多個分片數(shù)據(jù)執(zhí)行,UDAL會將各個分片返回的數(shù)據(jù)按照原始SQL語義進(jìn)行合并,如圖5所示。
5.4TdeDB梁構(gòu)
TeleDB是中國電信基于開源MySQL5.7數(shù)據(jù)庫系統(tǒng)自主開發(fā)的高可用數(shù)據(jù)庫集群產(chǎn)品。在MYSQL基礎(chǔ)上,額外開發(fā)了Gateway、keeper、Agen組件,對外提供高性能高可用、數(shù)據(jù)一致性的分布式數(shù)據(jù)庫服務(wù),大概架構(gòu)如圖7所示。
Keeper是TeleDB的調(diào)度器,監(jiān)聽zookeeper的特定路徑,主要作用是用于監(jiān)控底層主數(shù)據(jù)庫與備數(shù)據(jù)庫的可用狀態(tài)、數(shù)據(jù)庫同步延遲等一類信息;決定主從數(shù)據(jù)是否能夠進(jìn)行主從切換,控制主從切換的啟動及操作過程。在生產(chǎn)環(huán)境中為保證KEEPER高可用,至少部署三臺KEEPER在三臺獨立機(jī)上。
zookeeper是分布式一致性協(xié)議的一種開源實現(xiàn),用于TeleDB組件中狀態(tài)信息的保存,起到通信媒介的作用;一旦zookeeper崩潰,各個模塊間的通信全部中斷。為保證zookeeper高可用,至少部署三臺zookeeper在三臺獨立機(jī)上。
Agent用于收集底層DB服務(wù)器的狀態(tài)信息,并將相關(guān)信息寫入zookeeper。DB服務(wù)器狀態(tài)信息包括底層數(shù)據(jù)庫狀態(tài)信息(是否可讀寫),主從數(shù)據(jù)復(fù)制延遲、服務(wù)器負(fù)載、磁盤使用使用情況等信息。
DB層是數(shù)據(jù)庫節(jié)點組,由MySQL數(shù)據(jù)庫引擎模塊以及監(jiān)控和信息采集系統(tǒng)AGENT兩個部分組成,一個數(shù)據(jù)庫節(jié)點組(SET)包括一個主節(jié)點(Master)、若干備節(jié)點(slave)I,一般是一主兩從,SET通過心跳監(jiān)控和信息采集模塊(agent)監(jiān)控,確保集群的健壯性;在分布式架構(gòu)下,若干個數(shù)據(jù)庫節(jié)點組(SET)可以提供一個“邏輯統(tǒng)一,物理分散”分布式數(shù)據(jù)庫實例。
5.5TeleDB核心功能
TeleDB在開源的MySQL的基礎(chǔ)上,對主從同步、性能和可靠性等多個方面做了一定的改進(jìn)。
1)支持在事務(wù)commit前等待ACK,提高主備庫同步可靠性。
TeleDB相對于MySQL5.7之前的版本增加了rDl-semi_sync_master_wait_point參數(shù)來控制半同步復(fù)制模式下主庫在返回給會話事務(wù)成功之前提交事務(wù)的方式。
該參數(shù)有兩個值A(chǔ)FrER_COMMIT,AFrER_SYNC。AF-TER_COMMIT是master將每個事務(wù)寫入binlog,傳遞到slave刷新到磁盤(relay 10g),同時主庫提交事務(wù)。master等待slave反饋收到relaylog,只有收到ACK后master才將commitOK結(jié)果反饋給客戶端,由于主庫在備庫返回ACK信號之前就提交了事務(wù),故存在主備庫數(shù)據(jù)不一致的風(fēng)險;而AFTER_SYNC則是master將每個事務(wù)寫入binlog,傳遞到slave刷新到磁盤(relaylog)。master等待slave反饋接收到relaylog的ack之后,再提交事務(wù)并且返回commit OK結(jié)果給客戶端。即使主庫crash,所有在主庫上已經(jīng)提交的事務(wù)都能保證已經(jīng)同步到slave的relaylog中,因此AFTER_SYNC模式同步的可靠性更高,TeleDB默認(rèn)采用該模式。
2)實現(xiàn)了發(fā)送binlog和接受ack的異步化,提高主備庫同步性能。
以前版本的半同步的性能受限于dump thread,原因是dumpthread承擔(dān)了兩份不同且又十分頻繁的任務(wù):傳送binlog給slave,還需要等待slave反饋信息,而且這兩個任務(wù)是串行的,dump thread必須等待slave返回之后才會傳送下一個events事務(wù)。dump thread已然成為整個半同步提高性能的瓶頸。在高并發(fā)業(yè)務(wù)場景下,這樣的機(jī)制會影響數(shù)據(jù)庫整體的TPS。在TeleDB中,實現(xiàn)了發(fā)送binlog和接受ack的異步化,提高了主從同步的性能。
3)控制半同步主庫超時時間,實現(xiàn)高性能與高可靠靈活控制。
TeleDB版本在MySQL 5.7基礎(chǔ)上通過調(diào)整rpl_semi_sync_master_timeout參數(shù),來控制半同步主庫超時時間,以便運維人員在性能與可靠性兩者之間進(jìn)行權(quán)衡。在通常的生產(chǎn)運營環(huán)境下,通過將該參數(shù)調(diào)整為較大的值,可以達(dá)到高可靠即強(qiáng)同步的效果;而在其他一些對數(shù)據(jù)可靠性不那么敏感,而對性能要求更高的場合,則可以將此參數(shù)調(diào)小。
4)使用線程池技術(shù),提高連接效率。
TeleDB拋棄了MySQL傳統(tǒng)每連接每線程的連接模式,這種連接模式會導(dǎo)致巨大的系統(tǒng)開銷進(jìn)而影響整個性能。因此,TeleDB通過擴(kuò)展MySQL線程池,使用線程池技術(shù)來解決最大連接數(shù)限制問題以及過多線程帶來的系統(tǒng)開銷。
5)提升高并發(fā)場景下的性能穩(wěn)定性。
MySQL官方版默認(rèn)使用glibc作為mallc的動態(tài)庫,在高并發(fā)情況下,大量連接連到數(shù)據(jù)庫,而在這些連接結(jié)束釋放資源后,MvsQL會導(dǎo)致cpu sys值升高,使數(shù)據(jù)庫性能惡化。針對此問題,TeleDB給出兩種方案:增強(qiáng)線程池功能,跟主流開源線程池版本例如Percona、MariaDB等相比增加了線程池線程Cache功能;修改底層內(nèi)存分配庫,替代默認(rèn)使用系統(tǒng)glibc庫。以上兩種方案都可以解決MySQL官方版本使用glibc高并發(fā)場景sys升高的問題,沒有再出現(xiàn)sys飆高導(dǎo)致性能急劇下降的情況。
通過以上幾個方面的改進(jìn),TeleDB在高可靠、高連接、高并發(fā)、高吞吐等訪問場景下表現(xiàn)出極強(qiáng)的穩(wěn)定性,比官方MySQL具有明顯的優(yōu)勢。
6分布式數(shù)據(jù)庫在湖南電信的應(yīng)用
2018年,湖南電信啟動以分布式數(shù)據(jù)庫為核心的企業(yè)級PaaS平臺建設(shè),到2019年7月為止,已經(jīng)完成服務(wù)開通系統(tǒng)、自動激活系統(tǒng)、支付中心的改造遷移工作,預(yù)計到2019年底完成客戶服務(wù)中心、能力開放平臺等其余15個系統(tǒng)的改造遷移工作,到2020年完成湖南電信核心BSS3.0系統(tǒng)的遷移改造工作。目標(biāo)是在未來幾年逐步實現(xiàn)省內(nèi)IT系統(tǒng)、網(wǎng)管系統(tǒng)、業(yè)務(wù)系統(tǒng)的分布式改造,實現(xiàn)統(tǒng)一平臺、統(tǒng)一運營。
通過使用TeleUDAL和TeleDB分布式數(shù)據(jù)庫,遷移后支付中心的SQL執(zhí)行平均耗時由15ms減少到4ms,SQL執(zhí)行效率提升275%,服務(wù)開通系統(tǒng)每分鐘CRM取單峰值,由之前的1333筆提升到5552筆,性能提升316%;移動電話派發(fā)自動激活,每分鐘取單峰值由之前的582筆提升到1161筆,性能提升99.5%。系統(tǒng)改造后,效果提升明顯,充分證明TeleUDAL和TeleDB組成的分布式數(shù)據(jù)庫系統(tǒng)的穩(wěn)定、可靠、高性能,實現(xiàn)了容量和服務(wù)能力的可彈性伸縮,可輕松應(yīng)對高并發(fā)的實時交易場景。
7結(jié)論
面對海量數(shù)據(jù)的存儲、處理、訪問的難題,中國電信基于開源組件開發(fā)了TeleUDAL和TeleDB分布式數(shù)據(jù)庫,TeleUDAL通過對數(shù)據(jù)的水平切分,將海量數(shù)據(jù)分散到多個物理上獨立而邏輯上統(tǒng)一的數(shù)據(jù)庫里,解決數(shù)據(jù)存儲和并發(fā)訪問問題;通過SQL路由和數(shù)據(jù)匯聚技術(shù)解決透明數(shù)據(jù)訪問的問題。TeleDB通過搭建一主兩從的集群,解決數(shù)據(jù)的可靠存儲問題,通過對開源Mysql的改進(jìn),提高主備庫同步的可靠性及性能。最終解決了電信企業(yè)海量交易型業(yè)務(wù)數(shù)據(jù)的存儲和高效訪問的難題,使湖南電信能夠?qū)鹘y(tǒng)的運營商支撐系統(tǒng)轉(zhuǎn)型為新型的互聯(lián)網(wǎng)IT架構(gòu)的系統(tǒng),提升企業(yè)通信服務(wù)水平。