高性能架構(gòu)-數(shù)據(jù)庫架構(gòu)方案(數(shù)據(jù)庫高可用架構(gòu))
數(shù)據(jù)是是一個(gè)企業(yè)的核心價(jià)值,現(xiàn)在每個(gè)企業(yè)都把數(shù)據(jù)視為公司核心機(jī)密。而數(shù)據(jù)庫是存儲(chǔ)數(shù)據(jù)的地方,在一個(gè)系統(tǒng)中的重要性更不言而喻。如何設(shè)計(jì)一個(gè)高性能的數(shù)據(jù)庫系統(tǒng),直接影響一個(gè)系統(tǒng)的存亡。目前常用的架構(gòu)方案有主備、主從、讀寫分離、雙主等,以及數(shù)據(jù)庫擴(kuò)容方案分庫分表。今天講一講企業(yè)中常用的方案。
主備架構(gòu)
主備架構(gòu)是比較常見的架構(gòu)方案,中有主庫提供讀寫服務(wù),備份庫同步主庫數(shù)據(jù),當(dāng)主庫故障時(shí)系統(tǒng)自動(dòng)切換至備份庫。
優(yōu)點(diǎn):讀寫都操作主庫,不存在數(shù)據(jù)一致性問題。架構(gòu)相對(duì)簡(jiǎn)單運(yùn)維成本比較低。
缺點(diǎn):讀寫都在主庫,很容易產(chǎn)生系統(tǒng)瓶頸。大部分情況下讀多寫少,讀會(huì)先成為瓶頸,進(jìn)而影響寫性能。備庫只是單純的備份,資源利用率低。只能通過建立索引和增加緩存的方式提高性能。
主從架構(gòu)
主從架構(gòu)也是一種比較常用的架構(gòu),一般會(huì)一主多從,讀寫分離進(jìn)行實(shí)現(xiàn)。寫數(shù)據(jù)會(huì)在主庫上進(jìn)行操作,然后從庫會(huì)同步主庫數(shù)據(jù)。讀數(shù)據(jù)只在從庫上進(jìn)行操作,分擔(dān)了主庫的壓力。
優(yōu)點(diǎn):一般大型系統(tǒng)讀多寫少,讀會(huì)成瓶頸,這樣的架構(gòu)分擔(dān)了主庫的壓力。索引不用建在主庫,可以建在只用于查詢的從庫上,這樣可以提高寫的效率??梢酝ㄟ^增加從庫來提高讀的性能。
缺點(diǎn):存在單點(diǎn)故障,如果主庫掛了,寫操作無法進(jìn)行。從庫越多,需要從主庫拉取日志的從庫端就越多,進(jìn)而影響主庫的性能,并且數(shù)據(jù)同步完成的時(shí)間也會(huì)更長(zhǎng)。
數(shù)據(jù)同步一致性問題
由于從庫拉取主庫數(shù)據(jù)一般通過日志方式,即主庫獲取日志記錄,然后同步到從庫上執(zhí)行。這個(gè)過程中可能存在延遲。假如一個(gè)用戶剛寫入一條數(shù)據(jù),然后就開始刷新數(shù)據(jù)列表,這條數(shù)據(jù)有可能還未同步至從庫,造成無法顯示在用戶端。有以下方案進(jìn)行解決:
選擇讀主
首先在寫數(shù)據(jù)的時(shí)候同時(shí)往緩存里寫一份數(shù)據(jù),比如根據(jù)庫 表 業(yè)務(wù)特征生成一個(gè)key放到Cache里并設(shè)置超時(shí)時(shí)間(大于等于主從數(shù)據(jù)同步時(shí)間)。讀請(qǐng)求時(shí),同樣的方式生成key先去查Cache,再判斷是否命中。若命中,則讀主庫,否則讀從庫。代價(jià)是多了一次緩存讀寫,基本可以忽略。
同步復(fù)制
同步復(fù)制等主從同步完成,寫請(qǐng)求才返回。這里利用數(shù)據(jù)庫自帶的功能,實(shí)現(xiàn)比較簡(jiǎn)單。代價(jià)是寫請(qǐng)求時(shí)延增長(zhǎng),吞吐量降低。
強(qiáng)制讀主
比如一些剛剛存儲(chǔ)的數(shù)據(jù),大概率還沒有同步到從庫的情況下,可以強(qiáng)制從主庫讀取。
分庫分表方案
數(shù)據(jù)庫瓶頸
服務(wù)器都有IO和CPU的瓶頸,隨著數(shù)據(jù)庫的活躍連接數(shù)增加,數(shù)據(jù)庫會(huì)達(dá)到活躍連接數(shù)的閾值。如果一個(gè)數(shù)據(jù)庫的列比較多,請(qǐng)求也比較多,這樣可以采用垂直分表方案,把數(shù)據(jù)分開放不同表,這樣可以加快讀速度。如果網(wǎng)絡(luò)IO也比較大,就可以采取垂直分庫技術(shù),把數(shù)據(jù)存在在不同的數(shù)據(jù)庫,以加快返回速度。單表數(shù)據(jù)量太大,查詢時(shí)掃描的行太多,SQL效率低,CPU率先出現(xiàn)瓶頸,可以采用水平分表方式優(yōu)化。
水平分庫(表)
以字段為依據(jù),按照一定策略(hash、range等),將一個(gè)庫中的數(shù)據(jù)拆分到多個(gè)庫(表)中。每個(gè)庫或表的結(jié)構(gòu)都是一樣的,但是數(shù)據(jù)是不一致的,所有數(shù)據(jù)的并集就是全量數(shù)據(jù)。
如果庫只有一張表數(shù)據(jù)量大性能太低,就考慮水平分表。假如庫里的表字段相對(duì)比較少,數(shù)據(jù)量大且服務(wù)器運(yùn)行達(dá)到極限,就要考慮水平分庫。水平分庫(表)主要解決單庫(表)數(shù)據(jù)量太大的問題。
垂直分庫(表)
以表為依據(jù),按照業(yè)務(wù)歸屬不同,將不同的表字段拆分到不同的庫中。每個(gè)庫(表)結(jié)構(gòu)都不一樣,每個(gè)庫(表)結(jié)構(gòu)也不一樣,所有庫(表)數(shù)據(jù)的并集為全量數(shù)據(jù)。
表的記錄并不多,但是字段多,并且熱點(diǎn)數(shù)據(jù)和非熱點(diǎn)數(shù)據(jù)在一起,單行數(shù)據(jù)所需的存儲(chǔ)空間較大。以至于數(shù)據(jù)庫緩存的數(shù)據(jù)行減少,查詢時(shí)會(huì)去讀磁盤數(shù)據(jù)產(chǎn)生大量的隨機(jī)讀IO,產(chǎn)生IO瓶頸。這個(gè)時(shí)候就需要垂直分表。隨著業(yè)務(wù)的發(fā)展一些公用的配置表、字典表等越來越多,這時(shí)可以將這些表拆到單獨(dú)的庫??傊褪歉鶕?jù)業(yè)務(wù)邏輯及運(yùn)行情況,把數(shù)據(jù)進(jìn)行拆分,減少單表字段很多的情況。