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