citus是一款基于PostgreSQL的開源分布式數(shù)據(jù)庫(kù),自動(dòng)繼承了PostgreSQL強(qiáng)大的SQL支持能力和應(yīng)用生態(tài)(不僅僅是客戶端協(xié)議的兼容還包括服務(wù)端擴(kuò)展和管理工具的完全兼容)。
和其他類似的基于PostgreSQL的分布式方案,比如GreenPlum北专,PostgreSQL-XL蔚龙,PostgreSQL-XC相比,citus最大的不同在于citus是一個(gè)PostgreSQL擴(kuò)展而不是一個(gè)獨(dú)立的代碼分支狐史。
因此,citus可以用很小的代價(jià)和更快的速度緊跟PostgreSQL的版本演進(jìn);同時(shí)又能最大程度的保證數(shù)據(jù)庫(kù)的穩(wěn)定性和兼容性滑沧。
主要特性
● PostgreSQL兼容
● 水平擴(kuò)展
● 實(shí)時(shí)并發(fā)查
● 快速數(shù)據(jù)加載
● 實(shí)時(shí)增刪改查
● 持分布式事務(wù)
● 支持常用DDL
性能參考
為了能夠直觀的了解citus分片表的性能優(yōu)勢(shì),下面在1個(gè)CN和8個(gè)worker組成citus集群上巍实, 對(duì)比普通表和分片表(96分片)的性能差異滓技。
相關(guān)的表定義和SQL如下:
普通表
分片表
技術(shù)架構(gòu)
citus集群由一個(gè)中心的協(xié)調(diào)節(jié)點(diǎn)(CN)和若干個(gè)工作節(jié)點(diǎn)(Worker)構(gòu)成。CN只存儲(chǔ)和數(shù)據(jù)分布相關(guān)的元數(shù)據(jù)棚潦,實(shí)際的表數(shù)據(jù)被分成M個(gè)分片令漂,打散到N個(gè)Worker上。這樣的表被叫做“分片表”丸边,可以為“分片表”的每一個(gè)分片創(chuàng)建多個(gè)副本叠必,實(shí)現(xiàn)高可用和負(fù)載均衡。
citus官方文檔更建議使用PostgreSQL原生的流復(fù)制做HA妹窖,基于多副本的HA也許只適用于append only的分片纬朝。
分片表主要解決的是大表的水平擴(kuò)容問題,對(duì)數(shù)據(jù)量不是特別大又經(jīng)常需要和分片表Join的維表可以采用一種特殊的分片策略骄呼,只分1個(gè)片且每個(gè)Worker上部署1個(gè)副本共苛,這樣的表叫做“參考表”。
除了分片表和參考表蜓萄,還剩下一種沒有經(jīng)過分片的PostgreSQL原生的表隅茎,被稱為“本地表”〖倒粒“本地表”適用于一些特殊的場(chǎng)景辟犀,比如高并發(fā)的小表查詢。
客戶端應(yīng)用訪問數(shù)據(jù)時(shí)只和CN節(jié)點(diǎn)交互耻蛇。CN收到SQL請(qǐng)求后踪蹬,生成分布式執(zhí)行計(jì)劃胞此,并將各個(gè)子任務(wù)下發(fā)到相應(yīng)的Worker節(jié)點(diǎn),之后收集Worker的結(jié)果跃捣,經(jīng)過處理后返回最終結(jié)果給客戶端漱牵。
適用場(chǎng)景
citus適合兩類業(yè)務(wù)場(chǎng)景:
● 實(shí)時(shí)數(shù)據(jù)分析
citus不僅支持高速的批量數(shù)據(jù)加載(20w/s),還支持單條記錄的實(shí)時(shí)增刪改查疚漆。 查詢數(shù)據(jù)時(shí)酣胀,CN對(duì)每一個(gè)涉及的分片開一個(gè)連接驅(qū)動(dòng)所有相關(guān)worker同時(shí)工作。并且支持過濾娶聘,投影闻镶,聚合,join等常見算子的下推丸升,盡可能減少CN的負(fù)載铆农。所以,對(duì)于count()狡耻,sum()這類簡(jiǎn)單的聚合計(jì)算墩剖,在128分片時(shí)citus可以輕松獲得和PostgreSQL單并發(fā)相比50倍以上的性能提升。
● 多租戶
和很多分布式數(shù)據(jù)庫(kù)類似夷狰,citus對(duì)分片表間join的支持存在一定的限制岭皂。而多租戶場(chǎng)景下每個(gè)租戶的數(shù)據(jù)按租戶ID分片,業(yè)務(wù)的SQL也帶租戶ID沼头。因此這些SQL都可以直接下推到特定的分片上爷绘,避免了跨庫(kù)join和跨庫(kù)事務(wù)。
按現(xiàn)下流行的說法进倍,citus可以算是一個(gè)分布式HTAP數(shù)據(jù)庫(kù)土至,只是AP方面SQL的兼容性有待繼續(xù)提升,TP方面還缺一個(gè)官方的多CN支持背捌。
SQL限制與回避方法
citus對(duì)復(fù)雜SQL的支持能力還有所欠缺(和GreenPlum相比)毙籽,這主要反映在跨庫(kù)join洞斯,子查詢和窗口函數(shù)上毡庆。好在目前citus的開發(fā)非常活躍烙如,幾乎2個(gè)月就出一個(gè)新的大版本么抗,并大幅度改善其SQL支持能力。下面羅列了7.3版本的主要SQL限制亚铁。
Join
Join是分布式數(shù)據(jù)庫(kù)比較頭疼的問題蝇刀。citus處理Join有兩種方式,一種是把Join下推到分片上徘溢,即本地Join吞琐。本地Join捆探,性能最優(yōu),但只適用于親和分片表之間的Join站粟,以及分片表和參考表之間的Join黍图。
親和分片表指的是兩個(gè)分片規(guī)則(分片數(shù),副本數(shù)奴烙,分片字段助被,分片位置)完全相同的分片表。定義分片表時(shí)切诀,可以在create_distributed_table()的參數(shù)colocate_with中指定和某個(gè)已存在的分片表親和揩环。比如:
設(shè)計(jì)表時(shí)應(yīng)盡可能通過親和關(guān)系以及參考表解決Join的問題。如果無法做到幅虑,就只能實(shí)施跨庫(kù)Join丰滑。citus支持跨庫(kù)Join的方式是對(duì)數(shù)據(jù)按Join字段重新分區(qū),這一過程叫做MapMerge倒庵。這種方式只支持自然Join吨枉,其它Join仍然不支持。
子查詢:子查詢和Join一樣存在跨庫(kù)的問題哄芜,有時(shí)候子查詢可以轉(zhuǎn)化為一個(gè)等價(jià)的Join貌亭,所以和Join有相似的限制。
窗口函數(shù):citus只支持PARTITION BY子句包含分片字段的窗口函數(shù)认臊。 比如下面的SQL圃庭,如果class不是分片字段,這個(gè)SQL將不能支持失晴。
回避方法:可以通過臨時(shí)表或dblink將數(shù)據(jù)拉到CN上處理進(jìn)行回避剧腻。上面的SQL可以改寫為:
事務(wù)一致性:citus中沒有全局的事務(wù)快照,這和MyCAT等常見的分庫(kù)分表方案一樣涂屁。這樣可以簡(jiǎn)化設(shè)計(jì)提升性能书在,帶來的問題就是不能保證全局的一致性讀,而只能實(shí)現(xiàn)的最終一致性拆又。
舉個(gè)例子儒旬,從用戶A的賬戶上轉(zhuǎn)賬100塊到用戶B的賬戶上,用戶A和B對(duì)應(yīng)的記錄分別位于不同的Worker上帖族。 citus使用2PC處理這個(gè)分布式事務(wù)栈源,具體處理步驟如下:
在步驟7和8之間,參與2PC的2個(gè)子事務(wù)一個(gè)已提交另一個(gè)還沒提交竖般。 如果此時(shí)有人查詢賬戶總額甚垦,會(huì)得到一個(gè)不正確的值。
部署實(shí)施
citus的安裝非常簡(jiǎn)單,但要實(shí)際用到生產(chǎn)上還需要下一番功夫艰亮。比如如何擴(kuò)容闭翩,這是一個(gè)上生產(chǎn)后無法回避的問題,而citus的社區(qū)版恰恰又不支持?jǐn)U容迄埃。怎么辦? 辦法當(dāng)然是有的男杈,關(guān)于citus的部署,后面準(zhǔn)備通過一個(gè)系列的文章進(jìn)行介紹:
● 入門
● 實(shí)驗(yàn)環(huán)境搭建
● 平滑擴(kuò)容
● 多CN部署
● 連接管理
● 分布式事務(wù)
● 高可用