分庫分表之初識Vitess
Vitess,作為海外最為知名的分庫分表產(chǎn)品,一直以來在國內(nèi)聲音不多。近期抽空了解下這個產(chǎn)品,特分享出來。本文部分內(nèi)容取自Vitess官網(wǎng)https://vitess.io。
1. Vitess概述
人生基本上就是兩件事,選題和解題。最好的人生是在每個關(guān)鍵點上,既選對題,又解好題。人生最大的痛苦在于解對了題,但選錯了題,而且還不知道自己選錯了題。正如人生最大的遺憾就是,不是你不行,而是你本可以。
Vitess是一個用于部署、擴展和管理大型開源數(shù)據(jù)庫實例集群的數(shù)據(jù)庫解決方案。它目前支持MySQL、Percona和MariaDB。它的架構(gòu)設(shè)計使其在公共或私有云架構(gòu)中運行時與在專用硬件上運行時一樣有效。它結(jié)合并擴展了許多重要的SQL功能和NoSQL數(shù)據(jù)庫的可擴展性。
1).使用場景
- 數(shù)據(jù)分片
通過允許分片來縮放SQL數(shù)據(jù)庫,同時將應(yīng)用程序更改保持在最低限度。
- 數(shù)據(jù)遷移
從裸金屬遷移到私有云或公共云。
- 管理實例
部署和管理大量SQL數(shù)據(jù)庫實例。
2).技術(shù)特點
性能優(yōu)化
- 連接池
數(shù)據(jù)庫連接池能力,滿足支持大量前端應(yīng)用連接。
- 查詢結(jié)果重用
正在運行的查詢,對于后續(xù)完全相同的請求將重用同一查詢的結(jié)果。
- 事務(wù)管理器
限制并發(fā)事務(wù)的數(shù)量并管理超時,以優(yōu)化整體吞吐量。
- 行緩存
對于需根據(jù)主鍵隨機訪問的字段查詢,維護一個基于行的緩存(使用 memcached),可優(yōu)化 OLTP 工作負(fù)載非常有用。
運行防護
- 查詢重寫和凈化
添加限制并防止不確定性的更新。
- 查詢黑名單
自定義規(guī)則,防止?jié)撛谟袉栴}的查詢提交到數(shù)據(jù)庫。
- 殺掉查詢
終止運行需要很長時間才能返回數(shù)據(jù)的查詢。
- 表級別 ACLs
根據(jù)連接用戶為表定義訪問控制列表(ACLs)。
監(jiān)控診斷
- 性能分析
提供對數(shù)據(jù)庫性能進行監(jiān)控、診斷和分析的工具。
系統(tǒng)運維
- 集群/拓?fù)涔芾砉ぞ?/li>
提供基于 Web 的的集群管理工具,可顯示整體拓?fù)?。上述能力支持面向多個數(shù)據(jù)中心/區(qū)域的場合。
海量存儲
- 分片能力
支持垂直、水平分片能力,支持自定義分片策略,支持在線重分片能力。
3). 核心優(yōu)勢
- 分片管理
MySQL本身并不提供拆分分片功能,但是您的業(yè)務(wù)數(shù)據(jù)量增大到一定程度是您是需要增加集群的。Vitess提供在線拆分功能,只需要很少的時間就完成新集群的切換,無需您在應(yīng)用程序中添加任何拆分邏輯。
- 連接池
Vitess避免了MySQL連接的高內(nèi)存開銷。Vitess服務(wù)器輕松地一次處理數(shù)千個連接。
- 工作流
Vitess會跟蹤有關(guān)集群配置的所有元數(shù)據(jù),以便集群拓?fù)涫冀K是最新的,對不同的客戶端保持一致。
- 性能
Vitess自動重寫對數(shù)據(jù)庫性能有損害的查詢。它還使用緩存機制來調(diào)節(jié)查詢,并防止重復(fù)查詢同時到達您的數(shù)據(jù)庫
- 擴展性
Vitess集Mysql數(shù)據(jù)庫的很多重要特性和NoSQL數(shù)據(jù)庫的可擴展性于一體。其內(nèi)建拆分分片功能使您能夠?qū)δ腗ySQL數(shù)據(jù)庫集群無限水平擴展,同時無需為應(yīng)用添加分片邏輯
- 管理
Vitess可以支持自動處理主故障轉(zhuǎn)移和備份等功能。它使用分布式元數(shù)據(jù)服務(wù)來跟蹤和管理服務(wù)器,使您的應(yīng)用程序無需關(guān)心數(shù)據(jù)庫拓?fù)渥兓?/p>
4).方案對比
- 與MySQL對比
- 與NoSQL對比
2. Vitess基本架構(gòu)
人生基本上就是兩件事,選題和解題。最好的人生是在每個關(guān)鍵點上,既選對題,又解好題。人生最大的痛苦在于解對了題,但選錯了題,而且還不知道自己選錯了題。正如人生最大的遺憾就是,不是你不行,而是你本可以。
Vitess 平臺由若干服務(wù)器進程、命令行工具和基于 web 的工具組成,具備一致性元數(shù)據(jù)存儲支持。根據(jù)用戶應(yīng)用程序的現(xiàn)狀,可以選擇不同的方式接入Vitess。如果正在從頭構(gòu)建一個服務(wù),應(yīng)該起始于定義數(shù)據(jù)庫拓?fù)?如果需要對現(xiàn)有數(shù)據(jù)庫進行擴展,那首先需要部署一個連接代理。無論數(shù)據(jù)庫集群規(guī)模大小,Vitess 工具和服務(wù)器都旨在提供幫助。對于較小的實現(xiàn),VTTablet 的一些特性諸如連接池和行緩存可以幫助更充分利用現(xiàn)有硬件。Vitess 的自動化工具則為大型實現(xiàn)提供額外的好處。
Cell
Cell 是放置一組服務(wù)器和網(wǎng)絡(luò)基礎(chǔ)設(shè)施的區(qū)域,并且與其他Cell做到故障隔離。它通常是一個完整的數(shù)據(jù)中心或數(shù)據(jù)中心子集,有時稱為Zone或Availability Zone。Vitess 可以優(yōu)雅地處理Cell 級故障,例如當(dāng)一個Cell 斷開網(wǎng)絡(luò)時。Vitess 在每個Cell中托管本地拓?fù)浞?wù)。這一服務(wù)在Cell中包含Tablet的大部分信息,這使得Cell能夠被拆除并重建。Vitess 限制數(shù)據(jù)和元數(shù)據(jù)的跨Cell的流量。雖然其具有將讀取流量路由到單個Cell的能力,但 Vitess 目前僅提供來自本地Cell的讀取。如有必要,Vitess可跨Cell寫入。
Execution Plans
Vitess 在 VTGate 和 VTablet 層解析查詢,評估執(zhí)行查詢的最佳方法,進而生成查詢執(zhí)行計劃。Vitess 優(yōu)化策略之一是將盡可能多的工作下推到底層 MySQL 實例。當(dāng)這不可能時,Vitess 將使用從多個MySQL收集輸入并合并結(jié)果以生成正確查詢結(jié)果。
- 評估模式
一個執(zhí)行計劃由操作符組成,每個操作符執(zhí)行一個特定的工作。整個執(zhí)行計劃是由一組樹形結(jié)構(gòu)的操作符組成,每個操作符為樹中的一個節(jié)點。每個操作符將零或多行作為輸入,并產(chǎn)生零或多行作為輸出。這意味著一個操作的輸出成為下一個操作的輸入。連接樹中兩個分支的操作符組合來自兩個傳入流的輸入并產(chǎn)生單個輸出。執(zhí)行計劃的評估從樹的葉子節(jié)點開始。葉子節(jié)點從 VTablet 中提取數(shù)據(jù),并且在某些情況下還能夠在本地評估表達式值。每個葉子節(jié)點不會有來自其他操作符的輸入,并且將它們產(chǎn)生的任何節(jié)點通過管道傳輸?shù)狡涓腹?jié)點。然后,父節(jié)點將通過管道將節(jié)點傳送到它們的父節(jié)點,一直到根節(jié)點。根節(jié)點產(chǎn)生查詢的最終結(jié)果并將結(jié)果傳遞給用戶。
- 查看計劃
可通過瀏覽/queryz端點,在 VTGate 級別觀察緩存的執(zhí)行計劃。從Vitess 6開始,也可通過下面命令來查看:EXPLAIN FORMAT=vitess
Keyspace
Keyspace 是一個邏輯數(shù)據(jù)庫。如果使用分片技術(shù),則keyspace映射到多個 MySQL 數(shù)據(jù)庫;如果沒使用分片,則keyspace直接映射到 MySQL 數(shù)據(jù)庫名稱。無論那種情況,從應(yīng)用側(cè)來看,keyspace都顯示為單個數(shù)據(jù)庫。從 keyspace 讀取數(shù)據(jù)就像從 MySQL 數(shù)據(jù)庫讀取數(shù)據(jù)一樣。但是根據(jù)讀取操作的一致性要求,Vitess 可能會選擇從主數(shù)據(jù)庫或備數(shù)據(jù)庫中讀取。
- Keyspace id
Keyspace ID,就是通常講的分片鍵?;诜秶姆制?,是指創(chuàng)建時指定覆蓋特定范圍的keyspace ID。使用此方式,可通過用兩個或更多新分片,替換原有分片來拆分。而新分片組合在一起以覆蓋keyspace ID 的范圍,而無需移動其他分片中的任何記錄。Keyspace ID本身,是通過對數(shù)據(jù)中某些列的函數(shù)計算所得。Vitess 允許從各種函數(shù) ( vindexes ) 中進行選擇來執(zhí)行此映射。這使你可以選擇正確的方法來實現(xiàn)數(shù)據(jù)在分片之間的最佳分布。
MoveTables
MoveTables 是一種基于 VReplication 的新工作流。它使您能夠在 Keyspace 之間重新定位表,從而在不停機的情況下重新定位物理 MySQL 實例。
- 識別候選表
建議將需要相互關(guān)聯(lián)的表保留在同一 Keyspace 中,因此 MoveTables 操作的典型候選對象是一組邏輯上組合在一起或以其他方式隔離的表。如果有多組表作為候選,移動最有意義可能取決于環(huán)境的具體情況。例如,一個更大的表將需要更多的時間來移動,但這樣做你可能能夠利用額外的或更新的硬件,這些硬件在需要執(zhí)行額外的操作(如分片)之前有更多的空間。同樣,以更頻繁的速率更新的表可能會增加移動時間。
- 對生產(chǎn)流量影響
在內(nèi)部,MoveTables 操作由表副本和對表所做的所有更改的訂閱組成。Vitess 使用批處理來提高表復(fù)制和應(yīng)用訂閱更改的性能,但應(yīng)該期望修改率較低的表移動得更快。在主動移動過程中,數(shù)據(jù)是從副本而不是主服務(wù)器復(fù)制的。這有助于確保最小的生產(chǎn)流量影響。在MoveTables 中SwitchWrites 操作階段,Vitess 可能會暫時不可用。這種不可用性通常是幾秒鐘,但如果系統(tǒng)從主副本到副本的復(fù)制延遲很高,則會更高。
Query Rewrite
Vitess 努力營造一種用戶與單個數(shù)據(jù)庫連接的錯覺。實際上,單個查詢可能與多個數(shù)據(jù)庫交互,并且可能使用多個連接到同一數(shù)據(jù)庫。
- 查詢分解
具有跨分片連接的復(fù)雜查詢,可能需要先從保持 VIndex 查找表的 Tablet 中獲取信息,然后使用此信息查詢兩個不同的分片以獲取更多數(shù)據(jù),并將傳入的結(jié)果連接到用戶接收的單個結(jié)果中。MySQL 獲取的查詢通常只是原始查詢的一部分,最終結(jié)果將在 VTGate 級別組裝。
- 連接池
當(dāng) Tablet 與 MySQL 對話以代表用戶執(zhí)行查詢時,它不會為每個用戶使用專用連接,而是會在用戶之間共享底層連接。這意味著在會話中存儲任何狀態(tài)都是不安全的,因為無法確定它是否會繼續(xù)在同一連接上執(zhí)行查詢,并且無法確定此連接稍后是否會被其他用戶使用。
Replication Map
Vitess 通過復(fù)制圖來識別主數(shù)據(jù)庫和它們各自的副本之間的關(guān)系。在故障轉(zhuǎn)移期間,復(fù)制圖使 Vitess 能夠?qū)⑺鞋F(xiàn)有副本指向新指定的主數(shù)據(jù)庫,以便繼續(xù)復(fù)制。
Shard
分片是一個 Keyspace 的子集。一個 Keyspace 將包含一個或多個分片。一個分片通常包含一個 MySQL 主副本和許多 MySQL 副本。分片中的每個 MySQL 實例都具有相同的數(shù)據(jù)。副本可以提供只讀流量(具有最終的一致性保證)、執(zhí)行長時間運行的數(shù)據(jù)分析查詢或執(zhí)行管理任務(wù)(備份、恢復(fù)、差異等)。
- Reshard
Vitess 支持重新分片,其中在實時集群上更改分片的數(shù)量。這可以是將一個或多個分片拆分為更小的部分,或者將相鄰的分片合并為更大的部分。在重新分片期間,源分片中的數(shù)據(jù)被復(fù)制到目標(biāo)分片中,然后與原始分片進行比較以確保數(shù)據(jù)完整性,最后將實時服務(wù)基礎(chǔ)設(shè)施轉(zhuǎn)移到目標(biāo)分片,并刪除源分片。
- Tablet
Tablet 是mysqld過程和相應(yīng)的vttablet過程的組合,通常運行在同一機器上。每個 Tablet 都具備對應(yīng)的角色。查詢通過 VTGate 服務(wù)器路由到Tablet。Tablet 劃分角色如下:
- primary
Tablet對應(yīng)的MySQL角色是主庫。
- replica
Tablet對應(yīng)的MySQL角色是從庫,且該從庫有資格提升為主。這一角色一般服務(wù)面向?qū)崟r只讀查詢的訪問。
- rdonly
Tablet對應(yīng)的MySQL角色是從庫,且該從庫無法提升為主。這一角色通常用于后臺處理作業(yè),例如備份、將數(shù)據(jù)轉(zhuǎn)儲到其他系統(tǒng)、大量分析查詢、MapReduce 和重新分片。
- backup
Tablet對應(yīng)的MySQL角色是從庫,且因一致性快照而停止復(fù)制,可將其分片上傳備份。完成后,它將恢復(fù)復(fù)制并返回到以前的類型。
- restore
啟動時 Tablet 對應(yīng)MySQL沒有數(shù)據(jù),正在從最新備份中恢復(fù)。完成后,它將進入復(fù)制狀態(tài),并且角色變?yōu)閞eplica或rdonly。
- drained
為Vitess 后臺進程保留的Tablet,例如用于重分片等需求。
Topology Service
該拓?fù)浞?wù)是一組在不同服務(wù)器上運行的后端進程組成。這些服務(wù)器存儲全局拓?fù)鋽?shù)據(jù),并提供分布式鎖定服務(wù)。Vitess 使用插件系統(tǒng)來支持存儲拓?fù)鋽?shù)據(jù)的各種實現(xiàn),默認(rèn)的拓?fù)浞?wù)存儲插件是etcd2。拓?fù)浞?wù)的存在有幾個原因:
協(xié)調(diào)集群內(nèi) Tablets,發(fā)現(xiàn)Tablet,并感知將查詢路由到哪里。
存儲集群中不同服務(wù)器上的 Vitess 配置,并且必須在服務(wù)器重新啟動之間保持不變。
一個 Vitess 集群有一個全局拓?fù)浞?wù),每個單元有一個本地拓?fù)浞?wù)。
- Global Topology
全局拓?fù)浞?wù)存儲不經(jīng)常更改的 Vitess 數(shù)據(jù)。具體來說,它包含有 Keyspace 和 Shard 的數(shù)據(jù)以及每個 Shard 的主要 Tablet。全局拓?fù)溆糜谝恍┎僮鳎ㄖ匦逻x主、重新分片。為了在任何單個單元發(fā)生故障時幸免于難,全局拓?fù)浞?wù)應(yīng)該在多個單元中具有節(jié)點,以便在單元發(fā)生故障時維持仲裁。
- Local Topology
每個本地拓?fù)涠及c其自身 Cell 相關(guān)的信息。具體來說,它包含有關(guān) Cell 中 Tablet 的數(shù)據(jù)、該 Cell 的 Keyspace 以及該Cell的復(fù)制圖。本地拓?fù)浞?wù)必須可供 Vitess 使用以發(fā)現(xiàn)Tablet 并在 Tablet 變化時調(diào)整路由。但是,在穩(wěn)定狀態(tài)下提供查詢服務(wù)的關(guān)鍵路徑中不會調(diào)用拓?fù)浞?wù)。這意味著在拓?fù)鋾簳r不可用期間仍會提供查詢服務(wù)。
VSchema
一個 VSchema 用來描述數(shù)據(jù)是如何Keyspace和Shard內(nèi)組織。此信息用于路由查詢,也用于重新分片操作。對于 Keyspace,可以指定它是否被分片。對于分片的 Keyspace,可以為每個表指定 vindexes 列表。
- 序列
Vitess 支持序列生成器,可用于生成新的 id,其工作方式類似于 MySQL 自動增量列。VSchema 允許將表列關(guān)聯(lián)到序列表。如果沒有為這樣的列指定值,那么 VTGate 將知道使用序列表為它生成一個新值。
VStream
VStream 是一種可通過 VTGate 訪問的更改通知服務(wù)。VStream 的目的是從 Vitess 集群的底層 MySQL 分片提供與 MySQL 二進制日志等效的信息。gRPC 客戶端,包括 Vitess 組件,如 VTablets,可以訂閱 VStream 以接收來自其他分片的更改事件。VStream從VTTablet實例上的一個或多個VStreamer實例拉取事件,后者又從底層MySQL實例的二進制日志拉取事件。這允許有效執(zhí)行諸如 VReplication 之類的功能,其中訂閱者可以從一個或多個 MySQL 實例分片的二進制日志中間接接收事件,然后將其應(yīng)用于目標(biāo)實例。用戶可以利用 VStream 獲取有關(guān)給定 Vitess Keyspace、Shard和位置的數(shù)據(jù)更改事件的深入信息。工作原理可參考如下:
vtctl
vtctl是一個命令行工具,用于管理 Vitess 集群。它既可用作獨立工具 ( vtctl),也可用作客戶端-服務(wù)器(vtctlclient與 結(jié)合使用vtctld)。建議使用客戶端-服務(wù)器,因為它在遠程使用客戶端時提供了額外的安全層。使用 vtctl,可以識別主數(shù)據(jù)庫和副本數(shù)據(jù)庫、創(chuàng)建表、啟動故障轉(zhuǎn)移、執(zhí)行重新分片操作等。隨著 vtctl 執(zhí)行操作,拓?fù)浞?wù)會根據(jù)需要進行更新。其他 Vitess 服務(wù)器會觀察這些變化并做出相應(yīng)的反應(yīng)。例如,如果您使用 vtctl 故障轉(zhuǎn)移到新的主數(shù)據(jù)庫,vtgate 會看到更改并將未來的寫入操作定向到新的主數(shù)據(jù)庫。
vtctld
vtctld是一個 HTTP 服務(wù)器,可瀏覽存儲在拓?fù)浞?wù)中的信息。它對于故障排除或獲取服務(wù)器及其當(dāng)前狀態(tài)的高級概述很有用。vtctld還充當(dāng)vtctlclient連接的服務(wù)器。
VTGate
VTGate 是一個輕量級的代理服務(wù)器,它可以將流量路由到正確的 VTTablet 服務(wù)器并將合并的結(jié)果返回給客戶端。它同時使用 MySQL 協(xié)議和 Vitess gRPC 協(xié)議。因此,應(yīng)用程序可以像連接 MySQL 服務(wù)器一樣連接到 VTGate。在將查詢路由到適當(dāng)?shù)?VTablet 服務(wù)器時,VTGate 會考慮分片方案、所需的延遲以及表及其底層 MySQL 實例的可用性。
3. Vitess產(chǎn)品理念
人生基本上就是兩件事,選題和解題。最好的人生是在每個關(guān)鍵點上,既選對題,又解好題。人生最大的痛苦在于解對了題,但選錯了題,而且還不知道自己選錯了題。正如人生最大的遺憾就是,不是你不行,而是你本可以。
1). 可擴展理念
Vitess的產(chǎn)品理念,是將數(shù)據(jù)庫分片,將其分解成很小的部分,很容易將它們分解到足以容納一臺機器的程度。在行業(yè)中,每個主機只運行一個MySQL實例是很常見的。Vitess建議將實例分解成可管理的塊(每個MySQL服務(wù)器250GB),并且不要回避每個主機運行多個實例。凈資源使用量將大致相同。但是當(dāng)MySQL實例很小時,可管理性會大大提高。跟蹤端口和分離MySQL實例的路徑會很復(fù)雜。然而,一旦越過這個障礙,其他一切都變得簡單了。拆分為更小粒度后,需要擔(dān)心的鎖爭用更少,復(fù)制更快,停機對生產(chǎn)的影響變得更小,備份和恢復(fù)運行更快,并改善資源使用。
2). 復(fù)制代替持久性
傳統(tǒng)意義上,數(shù)據(jù)被刷新到磁盤時就將其視為持久的。Vitess 更為推薦的耐久性方法是通過將數(shù)據(jù)復(fù)制到多臺機器甚至多個地理位置來實現(xiàn)的。這種形式的耐久性解決了對設(shè)備故障和災(zāi)難的擔(dān)憂。Vitess中的許多工作流都是根據(jù)這種方法構(gòu)建的。例如,強烈建議打開半同步復(fù)制。這允許Vitess在主數(shù)據(jù)庫崩潰時故障轉(zhuǎn)移到新副本,而不會丟失數(shù)據(jù)。依賴復(fù)制還允許放松一些基于磁盤的耐久性設(shè)置。例如,可以關(guān)閉sync_binlog,這大大減少了磁盤的IOPS數(shù)量,從而提高了有效吞吐量。
3). 有取舍一致性
非一致性讀
在 Vitess 中跨分片讀取可能彼此不一致。在制定分片決策中,應(yīng)該試圖盡量減少這種情況,因為跨分片讀取更昂貴。如果存在可以容忍稍顯陳舊的數(shù)據(jù),則可將查詢發(fā)送到replica角色的 Tablet 處理;對于OLAP工作負(fù)載,則可發(fā)送到rdonly角色的 Tablet 處理。這一方式可提供更為靈活的縮放讀取流量,并可按地理位置分布它們。這種權(quán)衡允許以陳舊或可能不一致的讀取為代價獲得更好的吞吐量,因為隨著數(shù)據(jù)的變化(可能在不同的分片上有不同的滯后),讀取可能會落后于主分片。為了緩解這種情況,VTGate服務(wù)器能夠監(jiān)控副本滯后,并且可以配置為避免來自滯后超過X秒的實例的數(shù)據(jù)。
- REPLICA/RDONLY read
服務(wù)器可以按地理位置縮放。本地讀取速度很快,但可能會因副本延遲而失效。
- PRIMARY read
每個分片只有一個全局主要讀取。來自遠程位置的讀取將受制于網(wǎng)絡(luò)延遲和可靠性,但數(shù)據(jù)將是最新的(寫入后讀取一致性)。隔離級別READ_COMMITTED。
- PRIMARY transaction
它們顯示與主讀取相同的屬性。但是,可以為單個分片獲得REPEATABLE_READ一致性和ACID寫入??绶制邮聞?wù)的支持正在進行中。
快照級讀
對于真正的快照,查詢必須在事務(wù)中發(fā)送到主服務(wù)器。為了寫入后讀取的一致性,從主服務(wù)器讀取而不使用事務(wù)就足夠了。
分布式事務(wù)
在“盡最大努力模式”中,跨分片事務(wù)可能會在中間失敗,并導(dǎo)致部分提交。可以改為使用“2PC模式”事務(wù),為提供分布式原子保證。然而,選擇此選項會增加大約50%的寫入成本。單個分片事務(wù)繼續(xù)保持ACID,就像MySQL支持它一樣。事務(wù)支持原子性,支持以下級別:
- SINGLE:禁止多db事務(wù)。
- MULTI:盡最大努力提交的多數(shù)據(jù)庫事務(wù)。
- TWOPC:具有2PC提交的多數(shù)據(jù)庫事務(wù)
4). 高可用性
Vitess與Orchestrator集成,Orchestrator能夠在故障檢測后幾秒鐘內(nèi)執(zhí)行到新主服務(wù)器的故障轉(zhuǎn)移。這對于大多數(shù)應(yīng)用程序來說通常已經(jīng)足夠了。