數(shù)據(jù)庫分庫分表的21條法則
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
(一)好好的系統(tǒng),為什么要分庫分表? 本文是《分庫分表ShardingSphere5.x原理與實(shí)戰(zhàn)》系列的第二篇文章,距離上一篇文章已經(jīng)過去好久了,慚愧慚愧~ 還是不著急實(shí)戰(zhàn),咱們先介紹下在分庫分表架構(gòu)實(shí)施過程中,會(huì)接觸到的一些通用概念,了解這些概念能夠幫助理解市面上其他的分庫分表工具,盡管它們的實(shí)現(xiàn)方法可能存在差異,但整體思路基本一致。因此,在開始實(shí)際操作之前,我們有必要先掌握這些通用概念,以便更好地理解和應(yīng)用分庫分表技術(shù)。 我們結(jié)合具體業(yè)務(wù)場景,以 數(shù)據(jù)分片通常我們在提到分庫分表的時(shí)候,大多是以水平切分模式(水平分庫、分表)為基礎(chǔ)來說的,數(shù)據(jù)分片它將原本一張數(shù)據(jù)量較大的表 數(shù)據(jù)節(jié)點(diǎn)數(shù)據(jù)節(jié)點(diǎn)是數(shù)據(jù)分片中一個(gè)不可再分的最小單元(表),它由數(shù)據(jù)源名稱和數(shù)據(jù)表組成,例如上圖中 邏輯表邏輯表是指具有相同結(jié)構(gòu)的水平拆分表的邏輯名稱。 比如我們將訂單表 分庫分表通常對業(yè)務(wù)代碼都是無侵入式的,開發(fā)者只專注于業(yè)務(wù)邏輯SQL編碼,我們在代碼中 業(yè)務(wù)邏輯SQL
真實(shí)執(zhí)行SQL
真實(shí)表真實(shí)表就是在數(shù)據(jù)庫中真實(shí)存在的物理表 廣播表廣播表是一類特殊的表,其表結(jié)構(gòu)和數(shù)據(jù)在所有分片數(shù)據(jù)源中均完全一致。與拆分表相比,廣播表的數(shù)據(jù)量較小、更新頻率較低,通常用于字典表或配置表等場景。由于其在所有節(jié)點(diǎn)上都有副本,因此可以大大降低 需要注意的是,對于廣播表的修改操作需要保證同步性,以確保所有節(jié)點(diǎn)上的數(shù)據(jù)保持一致。 廣播表的特點(diǎn):
訂單管理系統(tǒng)中,往往需要查詢統(tǒng)計(jì)某個(gè)城市地區(qū)的訂單數(shù)據(jù),這就會(huì)涉及到省份地區(qū)表
單表單表指所有的分片數(shù)據(jù)源中僅唯一存在的表(沒有分片的表),適用于數(shù)據(jù)量不大且無需分片的表。 如果一張表的數(shù)據(jù)量預(yù)估在千萬級別,且沒有與其他拆分表進(jìn)行關(guān)聯(lián)查詢的需求,建議將其設(shè)置為單表類型,存儲(chǔ)在默認(rèn)分片數(shù)據(jù)源中。 分片鍵分片鍵決定了數(shù)據(jù)落地的位置,也就是數(shù)據(jù)將會(huì)被分配到哪個(gè)數(shù)據(jù)節(jié)點(diǎn)上存儲(chǔ)。因此,分片鍵的選擇非常重要。 比如我們將 在這個(gè)過程中, 這樣同一個(gè)訂單的相關(guān)數(shù)據(jù)就會(huì)落在同一個(gè)數(shù)據(jù)庫、表中,查詢訂單時(shí)同理計(jì)算,就可直接定位數(shù)據(jù)位置,大幅提升數(shù)據(jù)檢索的性能,避免了全庫表掃描。 不僅如此 分片策略分片策略來指定使用哪種分片算法、選擇哪個(gè)字段作為分片鍵以及如何將數(shù)據(jù)分配到不同的節(jié)點(diǎn)上。 分片策略是由
分片算法分片算法則是用于對分片鍵進(jìn)行運(yùn)算,將數(shù)據(jù)劃分到具體的數(shù)據(jù)節(jié)點(diǎn)中。 常用的分片算法有很多:
實(shí)際業(yè)務(wù)開發(fā)中分片的邏輯要復(fù)雜的多,不同的算法適用于不同的場景和需求,需要根據(jù)實(shí)際情況進(jìn)行選擇和調(diào)整。 綁定表綁定表是那些具有相同分片規(guī)則的一組分片表,由于分片規(guī)則一致所產(chǎn)生的的數(shù)據(jù)落地位置相同,在 比如:
當(dāng)使用
如果不配置綁定表關(guān)系,兩個(gè)表的數(shù)據(jù)位置不確定就會(huì)全庫表查詢,出現(xiàn)笛卡爾積關(guān)聯(lián)查詢,將產(chǎn)生如下四條
而配置綁定表關(guān)系后再進(jìn)行關(guān)聯(lián)查詢時(shí),分片規(guī)則一致產(chǎn)生的數(shù)據(jù)就會(huì)落到同一個(gè)庫表中,那么只需在當(dāng)前庫中
SQL 解析分庫分表后在應(yīng)用層面執(zhí)行一條 SQL 語句時(shí),通常需要經(jīng)過以下六個(gè)步驟: SQL解析過程分為
接著語法解析會(huì)將拆分后的SQL關(guān)鍵字轉(zhuǎn)換為抽象語法樹,通過對抽象語法樹遍歷,提煉出分片所需的上下文,上下文包含查詢字段信息( 執(zhí)⾏器優(yōu)化執(zhí)⾏器優(yōu)化是根據(jù)SQL查詢特點(diǎn)和執(zhí)行統(tǒng)計(jì)信息,選擇最優(yōu)的查詢計(jì)劃并執(zhí)行,比如
SQL 路由通過上邊的SQL解析得到了分片上下文數(shù)據(jù),在匹配用戶配置的分片策略和算法,就可以運(yùn)算生成路由路徑,將 SQL 語句路由到相應(yīng)的數(shù)據(jù)節(jié)點(diǎn)上。 簡單點(diǎn)理解就是拿到分片策略中配置的分片鍵等信息,在從SQL解析結(jié)果中找到對應(yīng)分片鍵字段的值,計(jì)算出 SQL該在哪個(gè)庫的哪個(gè)表中執(zhí)行,SQL路由又根據(jù)有無分片健分為
標(biāo)準(zhǔn)路由標(biāo)準(zhǔn)路由是最推薦也是最為常⽤的分⽚⽅式,它的適⽤范圍是不包含關(guān)聯(lián)查詢或僅包含綁定表之間關(guān)聯(lián)查詢的SQL。 當(dāng) SQL分片健的運(yùn)算符為
SQL路由處理后
直接路由直接路由是直接將SQL路由到指定⾄庫、表的一種分⽚方式,而且直接路由可以⽤于分⽚鍵不在SQL中的場景,還可以執(zhí)⾏包括⼦查詢、⾃定義函數(shù)等復(fù)雜情況的任意SQL。 笛卡爾積路由笛卡爾路由是由⾮綁定表之間的關(guān)聯(lián)查詢產(chǎn)生的,比如訂單表
全庫表路由全庫表路由針對的是數(shù)據(jù)庫 全庫路由全庫路由主要是對數(shù)據(jù)庫層面的操作,比如數(shù)據(jù)庫 對邏輯庫設(shè)置
全實(shí)例路由全實(shí)例路由是針對數(shù)據(jù)庫實(shí)例的 DCL 操作(設(shè)置或更改數(shù)據(jù)庫用戶或角色權(quán)限),比如:創(chuàng)建一個(gè)用戶 order ,這個(gè)命令將在所有的真實(shí)庫實(shí)例中執(zhí)行,以此確保 order 用戶可以正常訪問每一個(gè)數(shù)據(jù)庫實(shí)例。
單播路由單播路由用來獲取某一真實(shí)表信息,比如獲得表的描述信息:
阻斷路由⽤來屏蔽SQL對數(shù)據(jù)庫的操作,例如:
這個(gè)命令不會(huì)在真實(shí)數(shù)據(jù)庫中執(zhí)⾏,因?yàn)?nbsp; SQL 改寫SQL經(jīng)過解析、優(yōu)化、路由后已經(jīng)明確分片具體的落地執(zhí)行的位置,接著就要將基于邏輯表開發(fā)的SQL改寫成可以在真實(shí)數(shù)據(jù)庫中可以正確執(zhí)行的語句。比如查詢
這時(shí)需要將分表配置中的邏輯表名稱改寫為路由之后所獲取的真實(shí)表名稱。
SQL執(zhí)⾏將路由和改寫后的真實(shí) SQL 安全且高效發(fā)送到底層數(shù)據(jù)源執(zhí)行。但這個(gè)過程并不能將 SQL 一股腦的通過 JDBC 直接發(fā)送至數(shù)據(jù)源執(zhí)行,需平衡數(shù)據(jù)源連接創(chuàng)建以及內(nèi)存占用所產(chǎn)生的消耗,它會(huì)自動(dòng)化的平衡資源控制與執(zhí)行效率。 結(jié)果歸并將從各個(gè)數(shù)據(jù)節(jié)點(diǎn)獲取的多數(shù)據(jù)結(jié)果集,合并成一個(gè)大的結(jié)果集并正確的返回至請求客戶端,稱為結(jié)果歸并。而我們SQL中的排序、分組、分頁和聚合等語法,均是在歸并后的結(jié)果集上進(jìn)行操作的。 分布式主鍵數(shù)據(jù)分⽚后,一個(gè)邏輯表( 盡管可通過設(shè)置表⾃增主鍵 這個(gè)時(shí)候就需要我們手動(dòng)為一條數(shù)據(jù)記錄,分配一個(gè)全局唯一的ID,這個(gè)ID被叫做分布式ID,而生產(chǎn)這個(gè)ID的系統(tǒng)通常被叫做發(fā)號(hào)器。 大家可以參考我之前發(fā)布的這篇文章 9種分布式ID生成方案 數(shù)據(jù)脫敏分庫分表數(shù)據(jù)脫敏是一種有效的數(shù)據(jù)保護(hù)措施,可以確保敏感數(shù)據(jù)的機(jī)密性和安全性,減少數(shù)據(jù)泄露的風(fēng)險(xiǎn)。 比如,我們在分庫分表時(shí)可以指定表的哪些字段為脫敏列,并設(shè)置對應(yīng)的脫敏算法,在數(shù)據(jù)分片時(shí)解析到執(zhí)行SQL中有待脫敏字段,會(huì)直接將字段值脫敏后的寫入庫表內(nèi)。 對于用戶的個(gè)人信息,如姓名、地址和電話號(hào)碼等,可以通過加密、隨機(jī)化或替換成偽隨機(jī)數(shù)據(jù)的方式進(jìn)行脫敏,以確保用戶的隱私得到保護(hù)。 大家可以參考我之前發(fā)布的這篇文章 大廠也在用的 6種 數(shù)據(jù)脫敏方案 分布式事務(wù)分布式事務(wù)的核心問題是如何實(shí)現(xiàn)跨多個(gè)數(shù)據(jù)源的原子性操作。 由于不同的服務(wù)通常會(huì)使用不同的數(shù)據(jù)源來存儲(chǔ)和管理數(shù)據(jù),因此,跨數(shù)據(jù)源的操作可能會(huì)導(dǎo)致數(shù)據(jù)不一致性或丟失的風(fēng)險(xiǎn)。因此,保證分布式事務(wù)的一致性是非常重要的。 以訂單系統(tǒng)為例,它需要調(diào)用支付系統(tǒng)、庫存系統(tǒng)、積分系統(tǒng)等多個(gè)系統(tǒng),而每個(gè)系統(tǒng)都維護(hù)自己的數(shù)據(jù)庫實(shí)例,系統(tǒng)間通過API接口交換數(shù)據(jù)。 為了保證下單后多個(gè)系統(tǒng)同時(shí)調(diào)用成功,可以使用 經(jīng)過分庫分表之后,問題的難度進(jìn)一步提升。自身訂單服務(wù),也需要處理跨數(shù)據(jù)源的操作。這樣一來,系統(tǒng)的復(fù)雜度顯著增加。因此,不到萬不得已的情況下,最好避免采用分庫分表的解決方案。 關(guān)于分布式事務(wù)詳細(xì)的介紹,大家可以參考我之前發(fā)布的這篇文章 對比 5 種分布式事務(wù)方案,還是寵幸了阿里的 Seata(原理 + 實(shí)戰(zhàn)) 數(shù)據(jù)遷移分庫分表后還有個(gè)讓人頭疼的問題,那就是數(shù)據(jù)遷移,為了不影響現(xiàn)有的業(yè)務(wù)系統(tǒng),通常會(huì)新建數(shù)據(jù)庫集群遷移數(shù)據(jù)。將數(shù)據(jù)從舊集群的數(shù)據(jù)庫、表遷移到新集群的分庫、分表中。這是一個(gè)比較復(fù)雜的過程,在遷移過程中需要考慮 遷移主要針對 存量數(shù)據(jù)可以采用定時(shí)、分批次的遷移,遷移過程可能會(huì)持續(xù)幾天。 增量數(shù)據(jù)可以采用新、舊數(shù)據(jù)庫集群雙寫模式。待數(shù)據(jù)遷移完畢,業(yè)務(wù)驗(yàn)證了數(shù)據(jù)一致性,應(yīng)用直接切換數(shù)據(jù)源即可。 后續(xù)我們會(huì)結(jié)合三方工具,來演示遷移的過程。 影子庫什么是影子庫( 影子庫是一個(gè)與生產(chǎn)環(huán)境數(shù)據(jù)庫結(jié)構(gòu)完全相同的實(shí)例,它存在的意義是為了在不影響線上系統(tǒng)的情況下,驗(yàn)證數(shù)據(jù)庫遷移或者其他數(shù)據(jù)庫變更操作的正確性,以及全鏈路壓測。影子庫中存儲(chǔ)的數(shù)據(jù)是從生產(chǎn)環(huán)境中定期復(fù)制過來的,但是它不對線上業(yè)務(wù)產(chǎn)生任何影響,僅用于測試,驗(yàn)證和調(diào)試。 在進(jìn)行數(shù)據(jù)庫升級、版本變更、參數(shù)調(diào)優(yōu)等操作前,通過在影子庫上模擬這些操作,可以發(fā)現(xiàn)潛在的問題,因?yàn)闇y試環(huán)境的數(shù)據(jù)是不可靠的。 在使用影子庫時(shí),需要遵循以下幾個(gè)原則:
總結(jié)本文介紹了關(guān)于分庫分表架構(gòu)的21個(gè)通用概念,有一定的了解之后,接下來我們將進(jìn)入更深度的內(nèi)容,包括 下期文章將是《分庫分表ShardingSphere5.x原理與實(shí)戰(zhàn)》系列的第三篇,《快速實(shí)現(xiàn)分庫分表的 2種方式》。 ·········· END ·············· 該文章在 2023/5/17 9:40:58 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |