雲時代數據庫的核心特色

 

 

oracle  》  mysql  》 noSql (mondb redis) 》 NewSql (tidb)mysql

 

引言

最近幾年,隨着雲計算相關技術的發展,各類不一樣類型的雲層出不窮,服務愈來愈多不一樣類型的企業業務,傳統企業也漸漸開始探索上雲的道路。在雲上,做爲業務最核心的數據庫,相比以前的傳統方案會有哪些變化呢?在正式聊雲時代的數據庫特色以前,咱們須要瞭解一下目前雲時代架構發生的變化。redis

暢想一下,將來的服務都跑在雲端,任何的服務資源均可以像水電煤同樣按需選購。從 IaaS 層的容器/虛擬機,到 PaaS 層的數據庫,緩存和計算單元,再到 SaaS 層的不一樣類型的應用,咱們只須要根據自身業務特色進行資源選配,不再用擔憂應用服務支撐不住高速的業務增加,由於在雲上一切都是彈性伸縮的。有了可靠的基礎軟件架構,咱們就能夠把更多精力放到新業務的探索,新模式的創新,就有可能產生更多不同的新場景,從而催生更強大能力的雲端服務,這是一件多麼 cool 的事情。算法

固然,理想要一步一步實現,將來的基礎軟件棧到底會怎樣呢?社區在這方面正在進行積極地探索,其中最有表明性的就是基於容器(以 Docker 爲表明)的虛擬化技術和微服務(Microservice)。sql

在雲時代,一切都應該是可伸縮的,使用 k8s(Kubernetes)在保證資源平衡的前提下,經過 Docker 部署咱們依託於容器的微服務模塊,咱們不用關心服務到底跑在哪裏,只須要關心咱們須要多少服務資源。Docker 提供了極大的便利性,一次構建,處處運行,咱們能夠很好地解決開發、測試和上線的環境一致性問題。(若是不能很好地保證測試和實際上線環境的一致性,則頗有可能須要花費遠超過開發的時間去發現和修復問題。)k8s 更是在 Docker 構建的基礎上增長了更多的雲特性,包括 Docker 的升級,高可用和彈性伸縮等等。 關於 Docker/k8s 相關的討論已經不少了,由於時間關係,關於具體的細節就再也不展開。咱們只須要了解,有了它,能夠很輕鬆地解決服務的安裝和部署。數據庫

下面再聊聊微服務,微服務將一個服務拆分紅相對獨立的更小的子服務單元,不一樣的子服務單元之間經過統一的接口(HTTP/RPC 等)進行數據交互。緩存

相比於傳統的解決方案,這種架構有不少的優勢。安全

  • 更好的開發效率和可維護性。微服務將一個單獨的服務進行更細力度的拆分,每個子服務單元專一於更小的功能模塊,能夠更好地根據業務創建對應的數據模型,下降複雜度,使得開發變得更輕鬆,維護和部署變得更加友好.
  • 更好的可擴展性。每一個不一樣的子服務單元相互獨立,彼此之間沒有任何依賴,因此能夠根據業務的具體須要,靈活地部署多個子服務單元進行水平擴展。
  • 更強的容錯性。當其中一個子服務出現故障的時候,能夠經過輔助的負載均衡工具,自動路由到其餘的子服務,不會影響總體服務的可用性.

固然,微服務也不是一個銀彈,相對來講,這種方案會使總體系統的設計更加複雜,同時也加大了網絡的延遲,對整個系統測試的複雜度也會更高。服務器

Docker 提供的隔離型和可移植性,與微服務是一種自然的契合,微服務將整個軟件進行拆分和解耦,而經過 Docker/k8s 能夠很天然地作到獨立的部署,高可用和容錯性,彷佛一切均可以完美地運轉起來。可是真的是這樣麼?咱們是否是忽略了什麼?網絡

是的,咱們在討論前面的問題的時候忽略了一個很重要的東西:狀態。架構

從整個技術發展的角度來看,微服務是一個很是有意義的探索。每一個人都指望着每一個微服務的子服務都是無狀態的,這樣我能夠自由地啓停和伸縮,沒有任何的心智負擔,可是現實的業務狀況是什麼樣的呢?好比一個電商網站,用戶正在下單購買一件商品,此時平臺是經過訂單子服務的 A 應用來提供服務的,忽然,由於機器故障,訂單子服務的 A 應用不可用了,改由訂單子服務的 B 應用提供服務,那麼它是必需要知道剛纔用戶的訂單信息的,不然正在訪問本身訂單頁面的用戶會發現本身的訂單信息忽然不見了。雖然咱們儘可能想把子服務設計成無狀態的,可是不少時候狀態都是不可避免的,咱們不得不經過存儲層保存狀態,業界最主要的仍是各類數據庫,包括 RDBMS 和 NoSQL,好比使用 MySQL、MongoDB、HBase、Cassandra 等,特別是有些場景還要考慮數據一致性問題的時候,更加劇了對存儲層的依賴。

因而可知,雲計算時代系統的架構發生了巨大的變化,這一方面爲用戶提供了更優秀的特性,另外一方面也對雲計算的組件提出了更高的要求。數據庫做爲雲計算最基礎的組件之一,也須要適應這種架構的變化。(這裏咱們主要關注 SQL 數據庫,雲時代的數據庫如下簡稱雲數據庫。)

那麼雲數據庫主要有一些什麼樣的特色呢?我認爲主要有如下幾點。

彈性伸縮

傳統的數據庫方案,常見的會選用 Oracle,MySQL,PostgreSQL。在雲時代,數據量的規模有爆發性的增加,傳統的數據庫很容易遇到單機的存儲瓶頸,不得不選用一些集羣方案,常見的好比 Oracle RAC、 MySQL Sharding 等,而這些集羣方案或多或少都有一些不使人滿意的地方。

好比說,Oracle RAC 經過共享存儲的硬件方案解決集羣問題,這種方式基本上只能經過停機換用更大的共享內存硬件來解決擴容問題,RAC 節點過多會帶來更多的併發問題,一樣也會帶來更高的成本。

以 MySQL Sharding 爲表明的數據分片方案,不少時候不得不提早對數據量進行規劃,把擴容做爲很重要的一個計劃來作,從 DBA 到運維到測試到開發人員,很早以前就要作相關的準備工做,真正擴容的時候,爲了保證數據安全,常常會選擇停服務來保證沒有新的數據寫入,新的分片數據同步後還要作數據的一致性校驗。固然業界大公司有足夠雄厚的技術實力,能夠採用更復雜的方案,將擴容停機時間儘可能縮短(可是很難縮減到 0),可是對於大部分中小互聯網公司和傳統企業,依然沒法避免較長時間的停服務。

在雲時代,理想中全部的資源都是根據用戶業務需求按需分配的,服務器資源,應用容器資源,固然也包括數據庫資源。添加或者減小新的數據庫資源,徹底就像平常吃飯那樣稀疏日常,甚至用戶基本感知不到。好比做爲一個電商用戶,在雙 11 促銷活動以前,能夠經過增長數據庫節點的方式,擴大更多的資源池,用來部署相應的容器服務,當活動結束以後,再將多餘的資源移除去支持其餘的服務,這樣能夠極大地提升資源的利用率,一樣能夠彈性地支撐各類峯值業務。

高可用

傳統的 MySQL 方案,數據複製的時候默認採用異步的方式,對於一個寫入的請求,主庫寫入成功後就會返回成功信息給客戶端,可是這個時候數據可能尚未同步給從庫,一旦主庫這個時候掛掉了,啓動從庫的時候就會有丟失數據的風險。固然,也有人會選擇半同步的複製方式,這種方式在正常狀況下是同步的,可是在遇到數據壓力比較大的時候,依然會退化爲異步的方式,因此本質上來講,一樣有丟失數據的風險。其餘也有一些多主的同步方案,好比在應用層作數據同步,可是這種方式一是須要應用層的配合,二是在對網絡超時的處理很是複雜,增長心智負擔。

在雲時代,由於全部的數據庫資源都是分佈式存儲的,每一個數據庫節點出現問題都是很正常的事情,因此就必須有一種能夠實現數據一致性的數據複製方式來保證服務的高可用,業界給出的答案就是:Paxos/Raft(關於 Paxos 和 Raft 的實現細節咱們不在這裏展開)。PingCAP 在作的 TiDB 就是選擇了 Raft 協議,Raft 協議看起來更像是一個多副本的自適應的主從複製協議,對於每次寫請求,Raft 都會保證大多數寫成功纔會返回客戶端,即便 Raft Group的Leader 掛掉了,在一個有限的時間範圍內,會很快地選出一個新的 Leader 出來,繼續提供服務。一樣,對於一個 3 副本的 Raft Group,只要 2 個寫入成功,就能夠保證成功,而大多數狀況下,最早寫入成功的每每是與 Leader 網絡狀況最好的那個副本,因此這種 Majority 寫的方式,能夠很天然地選擇速度最快的副本進行數據同步複製。另外,Raft 協議自己支持 Config Change,增長一個新的節點,能夠很容易地作副本數據分佈的變動,而不須要中止任何服務。

一樣,在雲時代,數據庫的 DDL 操做也會是一個很是有趣的事情。以一個常見的 Add Column 操做爲例,在表規模已經很大的狀況下,在傳統的實現方案中,比較有參考意義的是,經過一些工具,建立相似表級別的觸發器,將原表的數據同步到一個新的臨時表中,當數據追平的時候,再進行一個鎖表操做,將臨時表命名爲原表,這樣一個 Add Column 操做就完成了。可是在雲時代,分佈式的數據存儲方式決定了這種方案很難實現,由於每一個數據庫節點很難保證 Schema 狀態變動的一致性,並且當數據規模增加到幾十億,幾百億甚至更多的時候,很短的阻塞時間都有可能會致使很大的負載壓力變化,因此 DDL 操做必須是保證無阻塞的在線操做。值得欣慰的是,Google 的 F1 給咱們提供了很好的實現參考,TiDB 便是根據 F1 的啓發進行的研發,感興趣的同窗能夠看下相關的內容。

易用透明

咱們能夠將雲數據庫想象成一個提供無限大容量的數據庫,傳統數據庫遇到單機數據存儲瓶頸的問題將不復存在。已有的程序基本上不怎麼須要修改已有的代碼,就能夠很天然地接入到雲數據庫中來得到無限 Scale 的能力。增減數據庫節點,或者節點的故障恢復,對於應用層來講徹底透明。另外,雲數據庫的監控、運維、部署、備份等等操做均可以在雲端經過高效的自動化工具來自動完成,極大地下降了運維成本。

多租戶

雲數據庫自己應該是能夠彈性伸縮的,因此很天然的,從資源利用率的角度來考慮,多個不一樣用戶的數據庫服務底層會跑在一個共享的雲數據庫中。所以多租戶技術會成爲雲數據庫的標配。可是這裏面就有一個不得不面對的問題,如何作到不一樣用戶的隔離性?用戶數據隔離是相對比較容易的,好比仍是以電商用戶(這裏說的是電商企業,不是顧客客戶)爲例,每一個用戶都有一個惟一的 ID,這樣在雲數據庫的底層存儲中,能夠保證每一個用戶數據都帶有本身 ID 前綴,用戶登錄進來的時候能夠根據這個前綴規則,獲取他對應的數據,同時他看不到其餘用戶的數據。

在一個真實的多租戶環境下面,純粹的數據隔離每每是不夠的,你還須要作到資源公平性的隔離。好比有的用戶寫一個 SQL,這個 SQL 沒有作優化,主要作的事情是一個全表描掃,這個表的數據量特別特別大,這樣他會吃掉不少的 CPU、Memory、IO 等資源,致使其餘用戶很輕量級的 SQL 操做均可能會變得很慢,影響到其餘用戶實際的體驗。那麼針對這種狀況怎麼作隔離?與此相似的還有,網絡帶寬怎麼作隔離?你們都是跑在一個雲數據庫上面的,若是一個用戶存放的數據特別大,他把帶寬都吃掉了,別人就顯得很是慢了。

還有一種狀況,若是我自己做爲一個租戶,內部又怎麼作隔離,你們知道 MySQL 能夠建不少 Database,不一樣的 Database 給不一樣的團隊來用,那麼他們之間內部隔離又怎麼作,這個問題就進一步更加複雜了。

目前來說沒有特別好的方法,在一個分佈式的環境下面去作很好的隔離,有兩個方向能夠考慮:

第一種是最簡單也是有效的方法,制定一些規則,把某些用戶特別大的數據庫表遷移到獨享的服務器節點上面,這樣就不會影響其餘用戶的服務,可是這裏面就涉及到定製化的事情了,自己理念其實與雲數據庫並不相符。

第二種就是依靠統計信息,作資源隔離和調度,可是這裏面對技術的要求就比較高了。由於雲數據庫是分佈式的,因此通常的統計都要橫跨不少的機器,由於網絡緣由,不可能作到徹底準確的統計,全部統計都是有延遲的。好比說對於某個用戶,如今統計到的流量是 1 個 G,他可能忽然就有一次峯值的網絡訪問,可能下一次統計消耗的流量是 5 個 G(這裏面只是舉例說明問題),若是你給他流量限制是 1 個 G,中間統計的間隔是多少比較合適,若是間隔比較小,那麼這個對整個系統的壓力就比較大,可能影響正常的用戶 SQL 訪問,另外自己這個流量限制的系統也是很複雜的系統。

調度算法一直是整個分佈式系統領域很困難的一個問題,如何作到隔離性和公平調度也是將來雲數據庫很是有挑戰的一個事情。

低成本

低成本應該是雲時代基礎設施最明顯的特色。首先,雲數據庫的高可用和容錯能力,使得咱們再也不須要昂貴的硬件設備,只須要普通的 X86 服務器就能夠提供服務。而後,受益於 Docker 的虛擬化技術,使得不一樣類型的應用容器能夠跑在同一個物理機上,這樣能夠極大地提升資源的利用率。其次,多租戶的支持,使得不一樣的用戶能夠共用一套底層的數據庫存儲系統,在數據庫層面再一次提升了資源的利用效率。再次,雲數據庫的自動化運維工具,下降了整個核心數據庫的運維成本。最後,雲數據庫資源是按需分配的,用戶徹底能夠根據自身的業務特色,選購合適的服務資源。

高吞吐

雲數據庫雖然能夠作到彈性擴容,可是自己是分佈式存儲的,雖然能夠經過 Batch Write、Pipeline 和 Router Cache 等方式加快訪問 SQL 請求的數據,可是相對傳統單機的數據庫來講,在數據訪問鏈路上至少也要多走一次網絡,因此大部分併發量不大的小數據量請求,都會比單機延遲要高一些。也就是說,當沒有足夠高的併發 SQL 訪問的話,其實不能徹底體現雲數據庫的性能優點,因此這也是咱們在選用雲數據庫的時候須要認識到的問題,雲數據庫更多的是追求高吞吐,而不是低延遲。當併發大到必定規模,雲數據庫高吞吐特性就顯現出來了,即便在很高的併發下,依然能夠維持至關穩定的延遲,而不會像單機數據庫那樣,延遲線性增加。固然,延遲的問題,在合理的架構設計方案下,能夠經過緩存的方式獲得極大的緩解。

數據安全

雲數據庫的物理服務器分佈在多個機房,這就爲跨數據庫中心的數據安全提供了最基礎的硬件支持。談到金融業務,你們耳熟能詳的可能就是兩地三中心,好比北京有兩個機房,上海有一個。將來一切服務都跑在雲上,金融類的業務固然也不例外。相比其餘業務,金融類業務對數據安全要求就要高得多。固然,每一個公司內部都有核心的業務,因此若是上雲的話,也會有一樣的強烈須要。這樣,對雲數據庫來講,數據的一致性、分佈式事務、跨數據中心的數據安全等更高端的需求有可能會日益強烈。常見的數據備份也有可能會被其餘新的模式所取代或者弱化,好比基於 Paxos/Raft 的多副本方案,自己就保證了會有多份備份。

自動負載平衡

對於雲數據庫來講,負載平衡是一個很重要的問題,它直接決定了整個雲數據庫系統性能的好壞,若是一個數據庫節點的數據訪問過熱的話,就須要考慮把數據遷移到其餘的數據庫節點來分擔負載,否則就很容易出現性能瓶頸。整個負載平衡是一個動態的過程,調度算法須要保證資源配比的最大平衡,還有保證數據遷移的過程對系統總體的負載影響最小。這在將來也是雲數據庫須要解決的一個核心問題。

小結

從目前已有的 SQL 數據庫實現方案來看,NewSQL 應該是最貼近於雲數據庫理念的實現。NewSQL 自己具備 SQL、ACID 和 Scale 的能力,自然就具有了雲數據庫的一些特色。可是,從 NewSQL 到雲數據庫,依然有不少須要挑戰的難題,好比多租戶、性能等。

上面提到的一些雲數據庫的特色,也是 PingCAP 目前在着力實現的部分,TiDB 做爲國內第一個 NewSQL 的開源項目,在與社區的共同努力下,咱們在上月底剛剛發佈了 Beta 版本,歡迎各位上 GitHub 瞭解咱們。

隨着整個社區技術水平的發展和雲時代新的業務需求的驅動,除了 PingCAP 的 TiDB,相信會有更多的團隊在這方面進行探索, 期待早日看到雲數據庫成熟的那一天。

Q&A

問:因爲客戶數據環境複雜多樣,在遷移到雲端的時候怎麼怎麼作規劃,以便後期統一運維管理?或者說,怎麼把用戶 SQL Server 或者 MongoDB 逐漸遷移到 TiDB 之類的分佈式數據庫? 崔秋:由於每一個業務場景都不太相同,因此在選用雲端服務的時候,首先要了解自身業務和雲服務具體的優缺點。 若是你的業務自己比較簡單,好比你以前用的 MongoDB,如今不少雲服務廠商都會提供雲端的 MongoDB 服務。這個時候你就要根據業務特色來作判斷,若是 MongoDB 自己容量不大,遠期的業務數據不會增加過快的話,這個時候其實你能夠直接使用 MongoDB 的服務的。可是若是你自己的數據量比較大,或者數據增加比較快的話,就可能要考慮數據的擴容問題,MongoDB 在這方面作的不是太好。 你能夠考慮 SQL 數據庫的集羣方案。好比 TiDB,它自己是支持彈性擴容,高併發高吞吐和跨數據庫中心數據安全的,另外有一點明顯的好處是 TiDB 兼容 MySQL 協議,因此若是你的應用程序是使用 MySQL,就基本上能夠無縫地遷移到 TiDB,這方面是很是方便的。後續咱們會提供經常使用的數據庫遷移工具,幫用戶把數據從 MongoDB/SQL Server 等平滑遷移到 TiDB 上面。 仍是那個原則,不要爲了上雲而上雲,必定要了解清楚本身的業務特色,雲數據庫會幫助你提供不少特性,若是真的很適用你的業務的話,就能夠考慮。

問:但從產品的角度來看,雲廠商提供的 RDS 產品是 Copy 客戶數據庫的思路,或者說是爲了支持不一樣的數據庫而支持。請問這種局面之後會有什麼改變嗎? 崔秋:如今確實蠻多雲數據庫服務其實就是在傳統的 RDS 上面包了一層自動化的監控,運維和部署工具,就賣給用戶提供服務了,可是實際上自己解決的僅僅是自動化管控的問題,雲服務提供的數據庫特性仍是單機的 RDS,或者 RDS Sharing 的特性。若是自己底層的數據庫知足不了你的需求的話,雲服務也是知足不了的。 若是你須要不停服務的彈性擴容,單機的 RDS 服務確定是搞不定的,RDS Sharing 也很難幫助你作到,這就對底層的數據庫有了更高的要求,固然這方面是 TiDB 的強項了。 如今不少雲上的 RDS 產品還遠遠沒有達到理想中的雲數據庫的要求,不過隨着社區的發展和業務需求的推進,我我的以爲,這方面最近幾年會有更多的變化。若是對於這方面感興趣的話,能夠關注下 TiDB。

問:從 Oracle 分流數據到 TiDB、Oracle 增量修改、Update 的記錄,如何同步到 TiDB?有沒有工具推薦,好比相似 Ogg? 崔秋:目前 TiDB 尚未相應的工具。若是真的須要在線從 Oracle 這邊分流的話,能夠考慮使用 Oracle 的觸發器,將數據的變化記錄下來,而後轉化爲 SQL,同步到 TiDB,固然這須要必定開發的工做量。

相關文章
相關標籤/搜索