品牌名稱
去哪兒
企業規模
5001-10000人

分布式數據庫SequoiaDB在去哪兒網的實踐

405次閱讀

分布式數據庫SequoiaDB在去哪兒網的實踐

2019-04-02

 

開源數據庫百花齊放新時代

 

MySQL目前是全球最流行,用戶最多的開源數據庫這是無可非議的事實。而同時,開源數據庫PostgreSQL也一直在不斷發展壯大,當然還包括眾多的新一代NoSQL、NewSQL數據庫不斷涌現。

此前,本人有幸參與“MariaDB/MySQL vs PostgreSQL世紀大決戰”,現場火藥味十足。作為為MySQL戰隊的一員,我個人認為,“大決戰”可能并不準確,更多的應該是碰撞,因為有史以來,在數據庫界,兩家不同數據庫被擺到臺上公開對標,他們應該是第一次走得這么近,我擔心的是,這樣的現象以后還會不會出現。

其實技術本身都是好的,我個人認為,我們應該本著“百花齊放、百家爭鳴”的態度來學習,來使用。如果沒有PostgreSQL,也許MySQL不會有現在這么好的口碑,當然反過來,如果沒有了MySQL,PostgreSQL也亦因為找不到對手而感覺孤獨不少。一家是“The world's most advanced open source database”,另一家是“The world's most popular open source database”,他們本來就應該相互學習,相互進步,所以這樣的“碰撞”,以后應該還會再有,期待下一屆“開源數據庫大會”的到來。

 

MySQL是否是唯一選擇?

 

而現在的事實是,MySQL確實如其所述,是“most popular”的開源數據庫,而PostgreSQL確實做到了“most advanced”,這點在“世紀大決戰”中也體現的淋漓盡致,做為“most advanced”的數據庫PostgreSQL,難免顯得有點高(級)冷(清),因為相比“most popular”的MySQL而言,用戶確實少多了。MySQL在“popular”方面,做得確實不錯,非常成功。因為正如大家所看到的,只要用到了數據庫,絕大多數都會考慮MySQL,因為這個問題還是和我的觀念比較契合的,所以我認為,任何結果,都是有其深層次的原因的,MySQL的popular,原因可能有以下幾點:

開源,這個可能無需多提,這個相比PostgreSQL,他沒有優勢,因為PostgreSQL也是開源的。

簡單,MySQL入門可以說是非常簡單的,這個大家應該都有感受,只要想用數據庫,除了使用access之外,MySQL可能就是不二之選了。

插件式,插件式也是兩面性的,一方面限制了他的發展;另一方面,靈活,功能強大,因為有很多插件可以自己選擇,應用自如,而用戶看重更多的是后者。

先入為主,在PostgreSQL想要流行起來的時候,MySQL已經流行起來了。

互聯網大公司推動,在去O大潮中,因為上面的原因,大型互聯網公司的推動,首選的是MySQL,導致了MySQL的快速發展。

原因有很多,現在的結果是,MySQL確實太火了,并且再加上MGR的出現,“用MGR完事”,也許真的是這樣。

但MySQL也有其缺點,那就是他的存儲都是單點。這當然也是大型通用數據庫的通病,一般都需要通過多點冗余來實現數據的高可用、高性能,但如果數據量再大了,即超出單盤容量(目前PCIe SSD卡最大容量達到12.8T)之后,MySQL可能就出現瓶頸了,當然這也是有解的。

我們去哪兒的解決辦法,通常都是在業務上面拆分,比如總數據量是20T,那就拆10個集群,每個集群都是2T的數據量,這樣就可以解決存儲的問題了,當然這都是從業務邏輯上面解決的,需要加上路由表來控制數據的存儲節點位置。這樣的解決辦法,雖然可以解決問題,但是當下可能更多人想要的是一個更advanced的解決方案,即現在很火的分布式數據庫。

理想中的解決方案是,我們無需關心數據存儲,我們只需要向一個節點上寫入,或者從一個節點上讀取即可。不但數據量可以為任意大小,當這個節點掛了,我們還可以隨時啟動另一個節點“頂上”即可實現故障轉移,這樣就實現了真正的“云存儲”。在這樣的“云存儲”中,我們不需要關心其高可用、多副本、容量、性能等問題,也不需要關心是不是存在多點寫入,讀寫節點可以隨時擴展,也許這樣才是我們心目中的分布式。

所以從這點來看,MGR還是存在單盤的問題,并不能解決數據量極大情況下的分布式問題。

 

分布式數據庫

 

那有沒有比較好的,類似我們心目中的分布式數據庫呢,我想是有的,至少是向這個方向在走。去哪兒網也一直在探索,所以我的要求基本有以下幾點:

要兼容MySQL,因為本人就是MySQL重度研究與使用者,高度認可MySQL這個數據庫的架構及使用方式等(中毒已深)。兼容MySQL這個要求,其實是非常高的,我們每個人都知道。只是MySQL的語法比較亂(說到代碼實現,可能更多的是罵了),很松散,如果說做到了90%的兼容度,那是不夠的,最好要做到100%,這能做到嗎?我想是可以的。

存儲率高,使用分布式數據庫的業務,大部分應該是存儲分析型,如果使用了分布式數據庫,還需要占用太多的硬件資源,且存儲不了太多數據的話,那這個在成本上就非常高了,得不償失。

有健全的圈子,使用中難免會碰到問題,碰到問題的時候,現在處于分布式發展的初級階段,所以社區的人比較少,而只能去求助官方,如果官方不能提供幫助(也許是沒給錢),那這樣的數據庫,可能就不具有誘惑力了,風險太大。

性能夠用,在使用了分布式數據庫之后,其實已經默認接受了降低性能要求的條件,所以我們的要求只是說,性能夠用即可,不會去和單點MySQL去比,因為沒有意義。夠用就好,當然在這方面如果足夠好,那是再好不過了。

少技術棧,這樣的需求是非常高的,因為技術棧太長,會加重運維人員的成本,并且在現在這樣人才難找更難招的情況下,這樣的愿望是更迫切的。

 

符合這樣要求的分布式數據庫有嗎?

 

最近在開源數據庫大會上向開源社區做出分享的SequoiaDB巨杉數據庫,這個名稱應該是比較熟悉了,他們已經做了很多年的分布式數據庫,只是最近才出現在了MySQL社區。其實一個很重要的原因就是,他們終于想清楚了,或者說意識到了MySQL的重要意義,所以他們也與MySQL保持了親密關系,或者更準確的說,巨杉數據庫,成為了MySQL圈內的一員,屬于真正的MySQL體系。

 

SequoiaDB巨杉數據庫

 

根據官方網站介紹,巨杉作為中國數據庫產品,技術上,SequoiaDB的3.0版本采用了計算-存儲分離的架構,這一架構是的SQL和存儲引擎實現了松耦合,在資源分配和通用性上優化空間更大。其中,SequoiaDB的數據存儲引擎是巨杉完全自研的分布式JSON數據存儲引擎,是完全從零開始自研的。而數據庫所有的數據管理、分布式控制、事務、ACID功能支持等都是在SequoiaDB的分布式存儲引擎里完成的。SQL層,目前SequoiaDB通過連接器(sequoiasql-mysql)直接使用了MySQL的原生解析器,實現MySQL的完整兼容,同時目前也支持PGSQL和SparkSQL。

 

為什么說巨杉數據庫屬于MySQL體系內呢?因為他做到了一點,就是100%兼容了MySQL的語法,更準確的說,他成為了MySQL的一個插件,說到插件,我想每個人都熟悉,因為你不會覺得MySQL插件不是MySQL體系內的。所以這點完全滿足了我的第一個需求,作為一個MySQL工作者,最喜歡看到這樣的場景了;

存儲率方面,巨杉數據庫,只需要三個節點就可以了;

在健全的圈子方面,我想,巨杉做為一個MySQL的插件,這個圈子夠大了,因為MySQL Server層的問題,我們自己就可以解決,僅剩下的巨杉數據庫本身,那可能就需要去不斷的學習與分享了,但至少少了很多問題;

性能方面,我們已經測試過,在只向一個IP端口讀寫(數據沒有分區,sdb只有一個節點)的情況下,性能基本是MySQL單點的三分之二,這是可以接受的,因為做為分布式數據庫,這樣的使用方式,必然是比不上單點MySQL的,這里重點在測試性能損失多少,如果想提升性能,則可以增加分區,或者增加協調節點等方式來實現,從而可以做到最大限度的發揮他的分布式優勢;

技術棧方面,這個和MySQL還是脫不了關系,對于Server層,輕車熟路,巨杉存儲引擎,也只是幾個獨立進程,架構清楚簡單,維護起來不會有太大困難。

 

巨杉數據庫架構設計詳解

 

上面是巨杉數據庫的架構圖。這里涉及到多個模塊,下面分別做一個解釋:

1. 協調節點:用來做數據的路由的,他的作用更像一個中間件,他會根據數據訪問的KEY,以及編目節點,來確定數據的存儲位置。可以有多個協調節點,用來提供更高的性能;

2. 編目節點:用來存儲路由信息的,與數據節點配合,可以最終定位數據;

3. 數據節點:用來存儲數據的;

4. sdb plugin:這就是MySQL插件,巨杉數據庫,本身與MySQL沒有任何關系,但MySQL通過這個插件,實現了所有訪問數據的接口,二者這才建立了關系,所以sdb plugin更多的是一個適配器。MySQL Server與巨杉數據庫的協議轉換器。

從架構上來看,這真正的實現了MySQL的云化存儲方案。此時的MySQL Server,自身不會存儲任何內容,其作用更多的被轉化為一個中間件了。

做為一個存儲引擎,在創建一個表的時候,還需要遵守MySQL本身的規則,比如還需要創建一個frm文件。其實個人認為,這個frm文件,和巨杉數據庫中對應的表沒有強關聯,它只是為了“騙過”MySQL Server,讓其知道,這個表是存在的,可以正常訪問這個數據庫,那么在騙過MySQL Server之后,就會走到存儲引擎層的訪問。

在順利通過了MySQL Server的各種考驗之后,就到了存儲引擎的訪問,因為巨杉實現了所有的存儲引擎與Server層的接口,所以存儲引擎的訪問,就會順利訪問到巨杉的sdb plugin,比如取一條數據、寫一條數據、帶條件的取數據(MySQL5.6中新增的condition push down特性)等,只要能順利將Server請求的接口返回正確的數據,那Server層就會正常的處理這些數據,最終返回給客戶端。

 

在將數據或者請求傳給巨杉存儲引擎之前,或者將數據從存儲引擎返回給Server層的時候,這些所有的操作,與巨杉是沒有關系的,這完全是MySQL Server層的工作,這些工作包括語法分析、語義分析、查詢優化、MDL鎖、數據庫權限、如果開了復制,則還會包括主從復制等等,當然還包括我們經常運維的一些命令,比如show processlist; information schema; MySQL庫信息的查詢。基于這些熟悉的特征,這樣的實現方式,給我們非常大的誘惑力。

從上面實現原理來看,從MySQL Server,到巨杉數據庫,架構應該是如上圖所示的,sdb plugin本身沒有存儲數據,所以其角色轉換為一個輕量級的中間件了,由sdb plugin來轉發應用的請求到協調節點,到這里,就是巨杉數據庫的天地了,我就不再贅述,我這里重點要講的是本身架構的問題。

現在把MySQL Server理解為中間層,最好的架構方式就是,有多套MySQL server在運行著,應用可以隨便訪問任意一套,這樣有以下幾點好處:

可以增強讀寫性能。

可以實現讀寫分離。

可以實現故障轉移

支持多點寫入功能,在故障切換時,隨便切換無影響。

但多套中間層的情況下,就存在一個問題,即配置的同步問題,在這套架構中,配置指的更多的是其元數據,比如表結構,也就是用來“騙過”MySQL Server的表結構,因為如果這些信息在多個節點之間不能同步,首先MySQL Server這層就不能順利通過,也就無法訪問巨杉了。

這個問題目前的解決方案是,巨杉提供了一個腳本,通過MySQL Server的審計功能,訂閱MySQL Server層的DDL操作,這樣在有元數據變更的時候,自動同步到其它MySQL Server中,這樣也就實現了元數據的同步功能。這樣實現,既熟悉,又無奈,因為這是MySQL,插件沒有辦法提供這樣的接口來同步元數據,只好這樣實現了。不過對于MySQL足夠熟悉時,這樣的實現也不失為一個好辦法。

我們進一步將這個架構完善一下

 

在多個MySQL Server(中間層)前面加上一個Keepalived,將VIP綁定在Server上,如果有一個down了,Keepalived會自動切換到活著的Server上面,實現了自動故障轉移。當然也可以不加這層,由業務自行去輪循環判斷死活來訪問MySQL Server也是可以的,因為使用Keepalived的話,存在一個問題就是VIP切換,在正常維護的時候,也會影響到業務,所以可能會產生這么一點點的不友好。

 

這種情況下,如果MySQL Server正常維護,只需要在通用中間層中做配置,讓維護節點下線,這樣流量就不會再路由到這個維護節點了,等所有操作執行完之后,就可以正常維護了。或者如果掛了,哨兵會發現其狀態變化,哨兵會連接到通用中間層上面,做配置更改,然后就可以實現故障轉移。

不過這種架構其實沒有什么太大必要,因為這個時候,MySQL Server非常輕量級,并且其作用已經成為了一個中間層的角色,只有在其所在機器需要關機的時候,或者某些MySQL的參數是只讀的情況,但又不得不修改的時候才會去維護,影響并不會太大。

至于巨杉本身架構中,很多節點的高可用如何實現故障轉移,我想這可以更多的參考他們的實現原理,拒我所知,其內容使用了raft類似的算法,做選舉判斷狀態等,這些都是目前主流的分布式實現方法,應該是足夠可靠了,這里不再做過多贅述了。

 

小結

不支持自增列,自增列在MySQL中用得比較多,但實際被使用時,都是一個無意義的列,并沒有在業務邏輯中使用,但由于他的自增屬性,導致很多業務程序在寫SQL的時候,都不會指定這個列的數據,所以對自增列做了強依賴,所以目前巨杉還沒有支持這個屬性的列,在新業務上面問題不大,對于老業務的遷移,可能在兼容性上面還不夠好。不過交流之后,官方聲稱在幾個月之內可以上線。
 

元數據同步,之前已經提到過了,只能說是不完美,功能是有了。

在經過功能和性能的測評之后,SequoiaDB已經滿足了我們的要求,我們也將會在近期在合適的場景進行上線使用。

MySQL的未來肯定是光明的,我希望有更多的開源軟件能加入到MySQL這個圈子里來,一起碰撞,一起共享,一起成長。我們也希望巨杉數據庫可以很快的建立起一個分享技術的圈子,可以讓更多人在開源的社區內受益。

 

作者簡介:
 

王竹峰,去哪兒網數據庫總監,中國計算機行業協會開源數據庫專業委員會常務理事。擅長數據庫開發、數據庫管理及維護,一直致力于MySQL數據庫源碼的研究與探索,對數據庫原理及實現有深刻的理解。曾就職于達夢數據庫,從事多年數據庫內核開發工作,后轉戰人人網,任職高級數據庫工程師,目前在去哪兒網負責MySQL源碼研究與運維、數據庫管理和自動化運維平臺設計開發及實踐工作,是Inception開源項目及《MySQL運維內參》的作者,也是國內少數幾個MySQL方向的Oracle  ACE之一。