分布式數(shù)據(jù)庫(kù),是近些年來(lái)頗受關(guān)注的領(lǐng)域。一方面隨著數(shù)據(jù)規(guī)模不斷增大,數(shù)據(jù)使用場(chǎng)景更為多樣,對(duì)底層數(shù)據(jù)庫(kù)的要求越來(lái)越高;另一方面對(duì)數(shù)據(jù)庫(kù)的可用性、擴(kuò)展能力等也都提出更高的要求。分布式數(shù)據(jù)庫(kù)的出現(xiàn),恰好滿足了上述兩方面的訴求。但當(dāng)用戶選擇使用分布式的第一個(gè)問(wèn)題,就是如何將之前基于單機(jī)或集中式數(shù)據(jù)庫(kù)設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)遷移到分布式環(huán)境中,核心點(diǎn)就在于數(shù)據(jù)分片的設(shè)計(jì)。這其中的核心要點(diǎn)有兩個(gè):一是選擇什么字段或字段組合作為分片鍵;二是使用什么分片算法來(lái)分片。本文嘗試說(shuō)明第一個(gè)問(wèn)題。
1. 是否需要設(shè)計(jì)分片
是否需要設(shè)計(jì)分片?相信是大家首要提出的問(wèn)題,作為一種新架構(gòu)的出現(xiàn),分布式數(shù)據(jù)庫(kù)確實(shí)可以解決一些場(chǎng)景問(wèn)題,但數(shù)據(jù)分片是在設(shè)計(jì)之初就需考慮。是否有一種更為透明的方式解決分片問(wèn)題呢,這就引出一個(gè)概念—“數(shù)據(jù)分布獨(dú)立性”。它是指用戶或用戶程序使用分布式數(shù)據(jù)庫(kù)如同使用集中式數(shù)據(jù)庫(kù)那樣,不必關(guān)系全局?jǐn)?shù)據(jù)的分布情況。也就是說(shuō)全局?jǐn)?shù)據(jù)的邏輯分片、片段的物理位置等情況對(duì)用戶和用戶應(yīng)用程序式透明的。因此分布式數(shù)據(jù)庫(kù)中分布獨(dú)立性也成為分布透明性。一個(gè)分布式數(shù)據(jù)庫(kù)系統(tǒng)可能提供的分布透明性層次越高,用戶編寫應(yīng)用程序越容易。比較理想的情況是,軟件工程師完全不必處理應(yīng)用級(jí)別的分片,因?yàn)檫@并不是他們真正的工作。然而,理想很豐滿,現(xiàn)實(shí)很骨感。完全透明的數(shù)據(jù)分片,在部分場(chǎng)景下仍然會(huì)面臨問(wèn)題,如低延遲、復(fù)雜業(yè)務(wù)、多中心等,這些場(chǎng)景仍然希望能夠精準(zhǔn)控制數(shù)據(jù)分片規(guī)則甚至物理位置。因此,如何設(shè)計(jì)分片策略也就成為新環(huán)境下DBA不得不面對(duì)的問(wèn)題,起碼是在相當(dāng)長(zhǎng)的時(shí)間是如此。正如同數(shù)據(jù)庫(kù)初學(xué)者需學(xué)習(xí)的范式理論一樣,未來(lái)數(shù)據(jù)分片的設(shè)計(jì)也是考驗(yàn)架構(gòu)、研發(fā)及DBA的基本要求之一。
這里稍微展開說(shuō)明下,分布式數(shù)據(jù)庫(kù)的實(shí)現(xiàn)有兩種主要方式,一是分庫(kù)分表;一是NewSQL。兩者的對(duì)比可參考下圖。具體在分片上,前者通??商峁└鼮殪`活精準(zhǔn)的分片控制,后者則在分片易用性上更具優(yōu)勢(shì)。
2. 如何選擇分片字段
數(shù)據(jù)分片的設(shè)計(jì)上需考慮兩點(diǎn):一是分片字段的選擇;二是對(duì)應(yīng)的分片算法。后續(xù)將重點(diǎn)談及分片字段選擇上,下面先簡(jiǎn)單說(shuō)明下分片算法問(wèn)題。
1).分片算法
分片算法,常規(guī)的有LIST、RANGE、HASH或自定義算法。根據(jù)各拆分算法特點(diǎn),可進(jìn)行選擇。若范圍均勻可采用HASH,冷熱數(shù)據(jù)明顯可采用RANGE等。同時(shí)可配合一些特性化設(shè)計(jì),如采用二級(jí)映射方式解決擴(kuò)縮容問(wèn)題、特征編碼字段滿足多特征拆分等。針對(duì)最為常見的兩個(gè)算法描述如下:
- RANGE
通過(guò)數(shù)據(jù)的范圍進(jìn)行分庫(kù)分表,是最樸實(shí)的一種分庫(kù)方案,它也可以和其他分庫(kù)分表方案靈活結(jié)合使用。當(dāng)需要使用分片字段進(jìn)行范圍查找時(shí),RANGE分片策略可快速定位數(shù)據(jù)進(jìn)行高效查詢。大多數(shù)情況下有效避免跨分片查詢的問(wèn)題。在后期擴(kuò)容時(shí),也比較方便,只需要添加節(jié)點(diǎn)即可,無(wú)需對(duì)其他分片的數(shù)據(jù)進(jìn)行遷移。但這種分布方式容易存在數(shù)據(jù)熱點(diǎn)問(wèn)題。
- HASH
雖然分庫(kù)分表的方案眾多,但是Hash分庫(kù)分表是最大眾最普遍的方案。隨機(jī)分片其實(shí)并不是隨機(jī),也遵循一定規(guī)則。通常采用HASH取模的方式進(jìn)行分片拆分,所以有時(shí)候也稱為離散分片。隨機(jī)分片的數(shù)據(jù)相對(duì)均勻,不容易出現(xiàn)熱點(diǎn)和并發(fā)訪問(wèn)的瓶頸。但涉及后面數(shù)據(jù)遷移的話,不太方便??墒褂靡恢滦訦ASH算法在很大程度上避免此問(wèn)題。此外,離散分片也容易面臨跨分片查詢的復(fù)雜問(wèn)題。
2).分片字段
分片字段的選擇,需涉及的因素很多,列個(gè)腦圖分類下。下面將針對(duì)各因素詳細(xì)說(shuō)明:
- 數(shù)據(jù)結(jié)構(gòu):主鍵或唯一鍵
主鍵及唯一鍵,是數(shù)據(jù)庫(kù)作為常見的約束,其是為了保證非空且唯一性。在分布式環(huán)境下,通常建議將主鍵或唯一鍵字段作為分片鍵或分片鍵的一部分,否則無(wú)法完成約束校驗(yàn);當(dāng)然也有產(chǎn)品支持單獨(dú)約束校驗(yàn)。這里有個(gè)引申問(wèn)題,就是主鍵設(shè)計(jì)問(wèn)題,在分布式數(shù)據(jù)庫(kù)架構(gòu)下,盡量不要用自增作為表的主鍵,自增性能很差、安全性不高、不適用于分布式架構(gòu)。通??墒褂萌鏤UID或全局發(fā)號(hào)器(雪花算法)。總之,用有序的全局唯一替代自增,是分布式數(shù)據(jù)庫(kù)主鍵的推薦做法。
- 數(shù)據(jù)結(jié)構(gòu):索引
通過(guò)分片鍵可以把 SQL 查詢路由到指定的分片,但是在現(xiàn)實(shí)的生產(chǎn)環(huán)境中,業(yè)務(wù)還要通過(guò)其他的索引訪問(wèn)表。針對(duì)原有系統(tǒng)的索引需要有單獨(dú)策略。通常的策略是通過(guò)索引表的方式,即將索引轉(zhuǎn)化為另一張分片表,對(duì)于查詢來(lái)說(shuō)通過(guò)二次查詢解決,但顯然這種方式不夠優(yōu)雅。因此,最優(yōu)的設(shè)計(jì)不是創(chuàng)建一個(gè)索引表,而是將索引數(shù)據(jù)融入到分片鍵的信息中,這樣通過(guò)查詢的列就能直接知道所在的分片信息。效率更高,查詢可以提前知道數(shù)據(jù)對(duì)應(yīng)的分片信息,只需 一次查詢就能獲取想要的結(jié)果。總結(jié)下,索引對(duì)分片字段的選擇上,沒(méi)有直接影響。對(duì)于高頻索引查詢,可以考慮通過(guò)分片鍵的設(shè)計(jì)上進(jìn)行增強(qiáng)。也可以通過(guò)全局二級(jí)索引(有些分布式數(shù)據(jù)庫(kù)支持)來(lái)實(shí)現(xiàn)或針對(duì)分片內(nèi)做普通索引。
- 數(shù)據(jù)結(jié)構(gòu):字段類型
作為分片鍵的字段,通常選擇較為簡(jiǎn)單的數(shù)據(jù)類型字段,可以提高效率,如常見的數(shù)字、日期、文本等,對(duì)復(fù)雜字段如LOB、JSON等不推薦使用。此外,在設(shè)計(jì)時(shí)需考慮分片字段的類型穩(wěn)定,盡量不要發(fā)生DDL變更。
- 數(shù)據(jù)特征:表規(guī)模
表規(guī)模是是否使用分片的關(guān)鍵因素之一。一旦表做了分片后,勢(shì)必會(huì)造成一定的“功能退化”,如能采取其他方式縮小表的大小,盡量?jī)?yōu)先其他方式??赏ㄟ^(guò)表的全生命周期規(guī)劃,如常規(guī)的數(shù)據(jù)歸檔、壓縮、轉(zhuǎn)儲(chǔ)、清理策略,減少數(shù)據(jù)量;或者利用數(shù)據(jù)庫(kù)內(nèi)置的如表分區(qū)、垂直分表等策略有效減小表的大小。
- 數(shù)據(jù)特征:離散度
這里說(shuō)的離散度是指按某個(gè)字段或字段組合后,應(yīng)用分片算法后,數(shù)據(jù)是否足夠分散。數(shù)據(jù)分片的初衷就是減少表的規(guī)模,盡量做到數(shù)據(jù)打散是其根本原則之一。這里需要統(tǒng)計(jì)數(shù)據(jù)拆分后離散程度,盡量選擇能充分打散的字段作為分片鍵。這里需注意,如果選擇字段是帶有業(yè)務(wù)特征,還要關(guān)注未來(lái)業(yè)務(wù)變化對(duì)它的影響。
- 訪問(wèn)特征:可變化性
選擇固定、不再變化的字段作為分片鍵。雖然有些分布式數(shù)據(jù)庫(kù)也支持分片鍵的修改,但畢竟修改后會(huì)涉及數(shù)據(jù)移動(dòng),成本代價(jià)很高;還是優(yōu)選不變的字段為好。
- 訪問(wèn)特征:事務(wù)隔離
盡量選擇按字段拆分后的數(shù)據(jù),對(duì)數(shù)據(jù)的變化處理可集中在分片內(nèi)解決。這樣大量的業(yè)務(wù)變化是可以通過(guò)本地事務(wù)完成,開銷比全局的要小很多,效率也高。
- 訪問(wèn)特征:數(shù)據(jù)過(guò)濾與關(guān)聯(lián)
如此字段經(jīng)常作為數(shù)據(jù)篩選字段被頻繁使用,且選擇率很好,可優(yōu)先作為分片字段。另一種情況則是作為與其他關(guān)聯(lián)表聯(lián)合使用,優(yōu)先選擇那些參與到關(guān)聯(lián)操作的字段為佳。盡量是數(shù)據(jù)在關(guān)聯(lián)后,能在本地完成join動(dòng)作,減少數(shù)據(jù)shuffle或上移匯聚類的操作??赏ㄟ^(guò)對(duì)系統(tǒng)中執(zhí)行的SQL進(jìn)行統(tǒng)計(jì)分析,選擇出需要分片那個(gè)表中最頻繁被使用到或最為重要的字段類分片。這其中可能包含一些來(lái)自O(shè)LAP類的查詢,可將此部分SQL排除在外。
- 分片字段順序
如涉及多個(gè)字段作為分片鍵的話,順序因素一般沒(méi)有什么影響。主要是針對(duì)分片算法,可利用字段做分片即可。但對(duì)于復(fù)合分片的情況,是要考慮分片字段的主次關(guān)系的。