數(shù)據(jù)庫(kù)架構(gòu)的演變
?
在業(yè)務(wù)數(shù)據(jù)量比較少的時(shí)代,我們使用單機(jī)數(shù)據(jù)庫(kù)就能滿足業(yè)務(wù)使用,隨著業(yè)務(wù)請(qǐng)求量越來(lái)越多,數(shù)據(jù)庫(kù)中的數(shù)據(jù)量快速增加,這時(shí)單機(jī)數(shù)據(jù)庫(kù)已經(jīng)不能滿足業(yè)務(wù)的性能要求,數(shù)據(jù)庫(kù)主從復(fù)制架構(gòu)隨之應(yīng)運(yùn)而生。
?
主從復(fù)制是將數(shù)據(jù)庫(kù)寫操作和讀操作進(jìn)行分離,使用多個(gè)只讀實(shí)例(slaver replication)負(fù)責(zé)處理讀請(qǐng)求,主實(shí)例(master)負(fù)責(zé)處理寫請(qǐng)求,只讀實(shí)例通過(guò)復(fù)制主實(shí)例的數(shù)據(jù)來(lái)保持與主實(shí)例的數(shù)據(jù)一致性。由于只讀實(shí)例可以水平擴(kuò)展,所以更多的讀請(qǐng)求不成問(wèn)題,隨著云計(jì)算、大數(shù)據(jù)時(shí)代的到來(lái),事情并沒(méi)有完美的得以解決,當(dāng)寫請(qǐng)求越來(lái)越多,主實(shí)例的寫請(qǐng)求變成主要的性能瓶頸。
?
如何解決上述問(wèn)題?如果僅僅通過(guò)增加一個(gè)主實(shí)例來(lái)分擔(dān)寫請(qǐng)求,寫操作如何在兩個(gè)主實(shí)例之間同步來(lái)保證數(shù)據(jù)一致性,如何避免雙寫,問(wèn)題會(huì)變的更加復(fù)雜。這時(shí)就需要用到分庫(kù)分表(sharding),對(duì)寫操作進(jìn)行切分來(lái)解決,如圖1。
?
華為云中間件產(chǎn)品DDM(Distributed Database Middleware)作為RDS的前置分布式數(shù)據(jù)庫(kù)訪問(wèn)服務(wù),徹底解決了數(shù)據(jù)庫(kù)的擴(kuò)展性問(wèn)題,對(duì)應(yīng)用透明地實(shí)現(xiàn)海量數(shù)據(jù)的高并發(fā)訪問(wèn),實(shí)現(xiàn)了讀寫分離和分庫(kù)分表。
?
圖1:典型的讀寫分離和分庫(kù)分表
?
數(shù)據(jù)分片的實(shí)現(xiàn)方案
?
數(shù)據(jù)分片的實(shí)現(xiàn)方案可分為應(yīng)用層分片和中間件分片,這兩種實(shí)現(xiàn)方案的特點(diǎn)如圖2所示:
?
DDM作為一款優(yōu)秀的分布式數(shù)據(jù)庫(kù)中間件產(chǎn)品,實(shí)現(xiàn)了讀寫分離和數(shù)據(jù)分片功能,使用DDM來(lái)分庫(kù)分表,應(yīng)用0改動(dòng),對(duì)應(yīng)用完全透明。
?
分庫(kù)分表的切分方式
?
數(shù)據(jù)的切分(Sharding)根據(jù)其切分規(guī)則的類型,可以分為兩種切分模式。一種是按照不同的表(或者Schema)來(lái)切分到不同的數(shù)據(jù)庫(kù)(主機(jī))之上,這種切分方式可以稱之為數(shù)據(jù)的垂直(縱向)切分;另外一種則是根據(jù)表中的數(shù)據(jù)的邏輯關(guān)系,將同一個(gè)表中的數(shù)據(jù)按照某種條件拆分到多臺(tái)數(shù)據(jù)庫(kù)(主機(jī))上面,這種切分稱之為數(shù)據(jù)的水平(橫向)切分。
?
垂直切分最大特點(diǎn)就是規(guī)則簡(jiǎn)單,實(shí)施也更為方便,尤其適合各業(yè)務(wù)之間的耦合度非常低,相互影響很小,業(yè)務(wù)邏輯非常清晰的系統(tǒng)。在這種系統(tǒng)中,可以很容易做到將不同業(yè)務(wù)模塊所使用的表分拆到不同的數(shù)據(jù)庫(kù)中。根據(jù)不同的表來(lái)進(jìn)行拆分,對(duì)應(yīng)用程序的影響也更小,拆分規(guī)則也會(huì)比較簡(jiǎn)單清晰。
?
水平切分于垂直切分相比,相對(duì)來(lái)說(shuō)稍微復(fù)雜一些。因?yàn)橐獙⑼粋€(gè)表中的不同數(shù)據(jù)拆分到不同的數(shù)據(jù)庫(kù)中,對(duì)于應(yīng)用程序來(lái)說(shuō),拆分規(guī)則本身比根據(jù)表名來(lái)拆分更為復(fù)雜,后期的數(shù)據(jù)維護(hù)也會(huì)更為復(fù)雜一些。
?
具體而言,如果單個(gè)庫(kù)太大,這時(shí)我們要看是因?yàn)楸矶喽鴮?dǎo)致數(shù)據(jù)多,還是因?yàn)閱螐埍砝锩娴臄?shù)據(jù)多。如果是因?yàn)楸矶喽鴶?shù)據(jù)多,使用垂直切分,根據(jù)業(yè)務(wù)切分成不同的庫(kù)。如果是因?yàn)閱螐埍淼臄?shù)據(jù)量太大,這時(shí)要用水平切分,即把表的數(shù)據(jù)按某種規(guī)則切分成多張表,甚至多個(gè)庫(kù)上的多張表。分庫(kù)分表的順序應(yīng)該是先垂直分,后水平分。因?yàn)榇怪狈指?jiǎn)單,更符合我們處理現(xiàn)實(shí)世界問(wèn)題的方式。
?
水平切分
?
相對(duì)于垂直拆分,水平拆分不是將表做分類,而是按照某個(gè)字段的某種規(guī)則來(lái)分散到多個(gè)庫(kù)之中,每個(gè)表中包含一部分?jǐn)?shù)據(jù)。簡(jiǎn)單來(lái)說(shuō),我們可以將數(shù)據(jù)的水平切分理解為是按照數(shù)據(jù)行的切分,就是將表中的某些行切分到一個(gè)數(shù)據(jù)庫(kù),而另外的某些行又切分到其他的數(shù)據(jù)庫(kù)中。
?
水平切分的優(yōu)點(diǎn):
?
1、拆分規(guī)則抽象好,join操作基本可以數(shù)據(jù)庫(kù)做。
?
2、不存在單庫(kù)大數(shù)據(jù),高并發(fā)的性能瓶頸。
?
3、應(yīng)用端改造較少。
?
4、 ?提高了系統(tǒng)的穩(wěn)定性跟負(fù)載能力。
?
水平切分的缺點(diǎn):
?
1、拆分規(guī)則難以抽象。
?
2、分片事務(wù)一致性難以解決。
?
3、數(shù)據(jù)多次擴(kuò)展難度跟維護(hù)量極大。
?
4、跨庫(kù)join性能較差。
?
水平切分的典型分片規(guī)則:
?
1、HASH取模
?
例如:取用戶id,然后hash取模,分配到不同的數(shù)據(jù)庫(kù)上。
?
2、RANGE
?
例如:從0到10000一個(gè)表,10001到20000一個(gè)表。
?
3、時(shí)間
?
按照時(shí)間切分,例如:將6個(gè)月前,甚至一年前的數(shù)據(jù)切出去放到另外的一張表,因?yàn)殡S著時(shí)間流逝,這些表的數(shù)據(jù)被查詢的概率變小,所以沒(méi)必要和”熱數(shù)據(jù)“放在一起,這個(gè)也是“冷熱數(shù)據(jù)分離”。
?
切分原則一般是根據(jù)業(yè)務(wù)找到適合的切分規(guī)則分散到不同的庫(kù),根據(jù)用戶ID取模作為切分規(guī)則。
?
垂直切分
?
一個(gè)數(shù)據(jù)庫(kù)由很多表的構(gòu)成,每個(gè)表對(duì)應(yīng)著不同的業(yè)務(wù),垂直切分是指按照業(yè)務(wù)將表進(jìn)行分類,分布到不同的數(shù)據(jù)庫(kù)上面,這樣也就將數(shù)據(jù)或者說(shuō)壓力分擔(dān)到不同的庫(kù)上面。
?
垂直切分的優(yōu)點(diǎn):
?
1、數(shù)據(jù)維護(hù)簡(jiǎn)單。
?
2、拆分后業(yè)務(wù)清晰,拆分規(guī)則明確。
?
3、系統(tǒng)之間整合或擴(kuò)展容易。
?
垂直切分的缺點(diǎn):
?
1、事務(wù)處理復(fù)雜。
?
2、部分業(yè)務(wù)表無(wú)法join,只能通過(guò)接口方式解決,提高了系統(tǒng)復(fù)雜度。
?
3、受每種業(yè)務(wù)不同的限制存在單庫(kù)性能瓶頸,不易數(shù)據(jù)擴(kuò)展跟性能提高。
?
由于垂直切分是按照業(yè)務(wù)的分類將表分散到不同的庫(kù),所以有些業(yè)務(wù)表會(huì)過(guò)于龐大,存在單庫(kù)讀寫與存儲(chǔ)瓶頸,所以就需要水平拆分來(lái)做解決。
?
切分原則
?
由于數(shù)據(jù)切分后數(shù)據(jù)Join的難度,在此也分享一下數(shù)據(jù)切分的經(jīng)驗(yàn):
?
第一原則:能不切分盡量不要切分。
?
第二原則:如果要切分一定要選擇合適的切分規(guī)則,提前規(guī)劃好。
?
第三原則:數(shù)據(jù)切分盡量通過(guò)數(shù)據(jù)冗余或表分組(Table Group)來(lái)降低跨庫(kù)Join的可能。
?
第四原則:由于數(shù)據(jù)庫(kù)中間件對(duì)數(shù)據(jù)Join實(shí)現(xiàn)的優(yōu)劣難以把握,而且實(shí)現(xiàn)高性能難度極大,業(yè)務(wù)讀取盡量少使用多表Join。
?
分庫(kù)分表后的問(wèn)題和應(yīng)對(duì)策略
?
分庫(kù)分表主要用于應(yīng)對(duì)當(dāng)前互聯(lián)網(wǎng)常見(jiàn)的兩個(gè)場(chǎng)景:海量數(shù)據(jù)和高并發(fā)。然而,分庫(kù)分表是一把雙刃劍,雖然很好的應(yīng)對(duì)海量數(shù)據(jù)和高并發(fā)對(duì)數(shù)據(jù)庫(kù)的沖擊和壓力,但也提高了系統(tǒng)的復(fù)雜度和維護(hù)成本,帶來(lái)一些問(wèn)題。
?
1、事務(wù)支持
?
在分庫(kù)分表后,就成為分布式事務(wù)了,如何保證數(shù)據(jù)的一致性成為一個(gè)必須面對(duì)的問(wèn)題。一般情況下,使存儲(chǔ)數(shù)據(jù)盡可能達(dá)到用戶一致,保證系統(tǒng)經(jīng)過(guò)一段較短的時(shí)間的自我恢復(fù)和修正,數(shù)據(jù)最終達(dá)到一致。
?
2、分頁(yè)與排序問(wèn)題
?
一般情況下,列表分頁(yè)時(shí)需要按照指定字段進(jìn)行排序。在單庫(kù)單表的情況下,分頁(yè)和排序也是非常容易的。但是,隨著分庫(kù)與分表的演變,也會(huì)遇到跨庫(kù)排序和跨表排序問(wèn)題。為了最終結(jié)果的準(zhǔn)確性,需要在不同的分表中將數(shù)據(jù)進(jìn)行排序并返回,并將不同分表返回的結(jié)果集進(jìn)行匯總和再次排序,最后再返回給用戶。
?
3、表關(guān)聯(lián)問(wèn)題
?
在單庫(kù)單表的情況下,聯(lián)合查詢是非常容易的。但是,隨著分庫(kù)與分表的演變,聯(lián)合查詢就遇到跨庫(kù)關(guān)聯(lián)的問(wèn)題。粗略的解決方法:ER分片:子表的記錄與所關(guān)聯(lián)的父表記錄存放在同一個(gè)數(shù)據(jù)分片上。全局表:基礎(chǔ)數(shù)據(jù),所有庫(kù)都拷貝一份。字段冗余:這樣有些字段就不用join去查詢了。ShareJoin:是一個(gè)簡(jiǎn)單的跨分片join,目前支持2個(gè)表的join,原理就是解析SQL語(yǔ)句,拆分成單表的SQL語(yǔ)句執(zhí)行,然后把各個(gè)節(jié)點(diǎn)的數(shù)據(jù)匯集。
?
4、分布式全局唯一ID
?
在單庫(kù)單表的情況下,直接使用數(shù)據(jù)庫(kù)自增特性來(lái)生成主鍵ID,這樣確實(shí)比較簡(jiǎn)單。在分庫(kù)分表的環(huán)境中,數(shù)據(jù)分布在不同的分表上,不能再借助數(shù)據(jù)庫(kù)自增長(zhǎng)特性,需要使用全局唯一ID。
?
分庫(kù)分表案例
?
某稅務(wù)核心征管系統(tǒng),全國(guó)34個(gè)省國(guó)/地稅,電子稅務(wù)局15省格局。
?
技術(shù)路徑:核心征管?+?納稅服務(wù) 業(yè)務(wù)應(yīng)用分布式上云改造。
?
業(yè)務(wù)挑戰(zhàn)
?
1、數(shù)據(jù)查詢時(shí)間3-5秒,響應(yīng)速度慢嚴(yán)重影響體驗(yàn)
?
當(dāng)前業(yè)務(wù)邏輯大量放在數(shù)據(jù)庫(kù)層,一個(gè)辦稅業(yè)務(wù)的事務(wù)邊界過(guò)大(40條SQL語(yǔ)句),涉及以“申報(bào)”、“發(fā)票”大表為主的多張表關(guān)聯(lián)事務(wù)操作,導(dǎo)致業(yè)務(wù)查詢響應(yīng)速度慢。
?
2、億級(jí)數(shù)據(jù)快速的增長(zhǎng),挑戰(zhàn)業(yè)務(wù)性能瓶頸
?
省級(jí)稅務(wù)局,辦稅高峰期承載百萬(wàn)級(jí)用戶并發(fā)量,3000-5000TPS。現(xiàn)網(wǎng)分析得到數(shù)據(jù):核心征管庫(kù)近1000張表,其中“申報(bào)”、“發(fā)票”業(yè)務(wù)表數(shù)據(jù)量大、增長(zhǎng)快,是主要瓶頸表;發(fā)票綜合信息:每省10億級(jí)條記錄,每年千萬(wàn)到億條記錄級(jí)別增量;申報(bào)信息表:億級(jí)記錄數(shù)據(jù)量。
?
解決方案
?
1、垂直分庫(kù)、微服務(wù)分解數(shù)據(jù)庫(kù)壓力,降低單業(yè)務(wù)sql數(shù)
?
基于微服務(wù)將大事務(wù)拆解為異步小事務(wù),業(yè)務(wù)邏輯從數(shù)據(jù)庫(kù)層面剝離。拆分主庫(kù)數(shù)據(jù),將大表垂直拆分到多個(gè)數(shù)據(jù)庫(kù)中,一個(gè)業(yè)務(wù)40條SQL縮減到20條SQL,達(dá)到分解數(shù)據(jù)庫(kù)壓力的目的。
?
2、數(shù)據(jù)分片支撐海量數(shù)據(jù)增長(zhǎng),線性提升業(yè)務(wù)處理速度
?
單表億級(jí)記錄以納稅人作為拆分鍵,拆分到RDS-MySQL?的128個(gè)分片上。實(shí)現(xiàn)支撐海量數(shù)據(jù)的存儲(chǔ)。拆分后數(shù)據(jù)庫(kù)設(shè)計(jì)簡(jiǎn)潔、簡(jiǎn)單,數(shù)據(jù)庫(kù)的表之間不設(shè)外鍵,不寫觸發(fā)器,不寫存儲(chǔ)過(guò)程,實(shí)現(xiàn)數(shù)據(jù)庫(kù)記錄的水平擴(kuò)展。
?
3、讀寫分離提升查詢性能
?
DDM自動(dòng)實(shí)現(xiàn)讀寫分離,透明地完成寫操作和讀操作的分發(fā),應(yīng)用程序無(wú)需做特殊的改動(dòng)和處理邏輯。寫操作分發(fā)到RDS主實(shí)例,讀操作自動(dòng)分發(fā)到RDS的多個(gè)讀實(shí)例上,這樣寫操作不會(huì)影響讀操作的并發(fā),讀并發(fā)業(yè)務(wù)增長(zhǎng)時(shí)只需要按需增加只讀實(shí)例即可。
?
企業(yè)受益
?
1、使用了DDM之后,輕松突破原來(lái)的性能瓶頸,一次業(yè)務(wù)操作,原來(lái)需要3到5秒,現(xiàn)在只需要1秒。
?
2、讀寫操作通過(guò)DDM的自動(dòng)讀寫分離,在不改動(dòng)業(yè)務(wù)情況下,輕松提升了整體的讀寫并發(fā)能力。
?
文章來(lái)源:https://www.huaweicloud.com/
?
評(píng)論