1. 程式人生 > >從零開始搭建MongoDB資料庫即服務

從零開始搭建MongoDB資料庫即服務

講師介紹

鄭涔

阿里雲資料庫技術專家

  • 目前主要參與阿里雲MongoDB雲資料庫的研發,致力於讓開發者用上最好的MongoDB雲服務;
  • 主要關注分散式儲存、NoSQL等技術領域

分享大綱:

  1. 什麼是資料庫即服務
  2. MongoDB
  3. 如何搭建一個MongoDB資料庫即服務

一、什麼是資料庫即服務(DBaaS)

資料庫

首先介紹一下『資料庫即服務』。『資料庫即服務』其實是『Database-as-a-service』的中文翻譯,我們看看它在維基百科中的定義:

『資料庫即服務』是這樣一種服務模式,它使得應用開發者不再需要自己安裝和維護資料庫,而是由專門的資料庫服務提供商來做,應用開發者可以根據自己的需要去直接使用資料庫服務,併為使用量支付費用即可。我們知道,現在有很多的as-a-service,比如Infrastructure as a Service(IaaS)、Platform as a Service(Paas)還有Software as a Service(Saas)。他們到底都是什麼呢?有什麼區別?

這張圖應該可以很好地解釋這些X-aaS。最左邊是傳統企業的IT,所有的活都要自己幹,從資料中心伺服器到作業系統資料庫再到上層業務系統。IaaS開始就進入雲端計算的範疇了,最基礎的是雲伺服器,不需要再關心機房啊硬體拉,直接就可以用。然後再往右客戶需要關注的越來越少,髒活累活都交給服務提供商來幹。

那麼『資料庫即服務』的情況是怎麼樣呢?

資料庫即服務的優勢

資料庫即服務

資料庫即服務』其實可以認為是PaaS的一種變種,主要關注點在資料庫上,客戶不再需要去自己部署資料庫,而是隻需要按需使用由服務提供商提供的資料庫即可,資料庫的維護都交給服務提供商來完成,這樣客戶只需關注應用本身即可。

資料庫

我們來具體看一下使用『資料庫即服務』和原來有什麼不同,這裡除了列舉傳統全部DIY的方式之外,還對比了一種利用IaaS來自建資料庫的方式,這也是現在比較常見的一種做法。我們看到傳統方式,需要做很多事情,這當中還需要涉及多個團隊來協作,非常不容易。然後看看第二種方式,利用IaaS來自建,這裡以阿里雲的雲伺服器ECS為例,這種方式和剛剛相比,省了不少事,但是仍然是比較麻煩的,也可能還需要涉及跨團隊協作。

我們再來看看如果是使用『資料庫即服務』呢?只需要點下頁面上的部署按鈕,就可以等著用了,已經進化為完全自助服務了。從時間上來看,第一種方式可能需要花費數月,第二種可能需要花費數天,第三種則只需要數小時即可。可見『資料庫即服務』的優勢還是很明顯的。

為什麼要即服務

即服務

所以說為什麼要『即服務』,其實是一個進化的趨勢。我們經常說人不能太懶,但是懶這個字用在程式猿身上可能並不是不好的東西,因為懶,促使我們會去自動化。最早我們通過人肉操作,下載軟體,編譯部署,然後配置。有一天我們發現經常需要這麼幹很累很浪費時間,就開始寫指令碼來完成這些操作,生產力開始提高。等到規模更大的時候,比如要同時管理數十臺數百臺機器,這時候可能分發指令碼也嫌麻煩了,開始寫一些自動化的工具來做這個事情。到最高階階段,就是完全實現自助服務,這是懶的最高境界。

二、MongoDB簡介

說完了『即服務』以及其重要性,接下來我們看一下今天的另一個主角:MongoDB,因為有些同學可能對這個不瞭解,所以還是簡單介紹一下。

MongoDB

首先,MongoDB是什麼呢,它是一個Document Store,文件型資料庫,也是我們經常說的NoSQL。根據DB-Engines的資料庫排名,MongoDB長期霸佔著NoSQL老大的地位,現在是資料庫界一位重量級選手。

MongoDB

事實上,MongoDB可以稱為是一種NewSQL,它融合了傳統關係型資料庫和NoSQL的一些優點。

最左邊的3個能力是來自於關係型資料庫:

  • 首先,它具備豐富的查詢語句和二級索引。通過這點,使用者可以以足夠複雜的方式來訪問和組織資料。
  • 第二點,強一致性。MongoDB支援一個靈活的一致性模型。你可以選擇使用強一致性,或最終一致性,取決於你的業務場景。
  • 第三點,MongoDB能很好的整合到多企業現有技術架構中。

右邊3個能力來自NoSQL:

  • 首先是靈活的資料模型,MongoDB的文件模型允許動態修改schema,不用擔心有任何的效能影響。
  • 其次是高效能和高可擴充套件性,MongoDB可以輕鬆進行水平擴充套件,從而帶來更高的吞吐和更低的延遲。
  • 最後,是全球部署,也就是高可用。接下來我們就來具體講下MongoDB的幾個關鍵特性。

MongoDB的關鍵特性

MongoDB的關鍵特性主要是3個,第一個就是靈活動態的文件模型,第二個是高可用副本集,第三個是MongoDB的水平擴充套件,也就是sharding。

1、靈活動態的文件模型

MongoDB以一種叫做BSON(二進位制JSON)的儲存形式將資料作為文件儲存。具有相似結構的文件通常被組織成集合。可以把集合看成類似於關係資料庫中的的表:文件對應的是行,欄位對應的是列。

MongoDB將一條記錄的所有資料聚合在一個文件中,而在關係資料庫中則傾向於將資料分佈在多個表中。這樣做有幾個好處,一是由於資料聚集,減少了多表JOIN的需求,這樣只需要讀一次就可以讀到所有資料,在效能上會有很大優勢。

另外,這種模型更加接近我們平時程式語言中的物件結構,可以方便開發者進行資料對映。

最後就是這種模型是schema-less的,也就是在MongoDB中不需要像關係資料庫一樣去事先定義每個表的schema。MongoDB一個集合內的文件之間可以擁有不同的結構,可以輕鬆為一個新的文件新增和減少欄位,不會有任何的效能影響。這個特性非常適合開發一些新產品,可以快速迭代。

當然,過於靈活就可能導致混亂。有時候我們想要求文件必須要有某些欄位,某些欄位必須要有固定的型別。為此,MongoDB提供了一個文件驗證功能來對文件的格式進行約束。

2、高可用副本集

高可用

接下來說MongoDB的第二個關鍵特性,高可用副本集(也可以翻譯成複製集)。

MongoDB副本集由一組Mongo例項(程序)組成,包含一個Primary節點和多個Secondary節點,Mongodb Driver(客戶端)的所有資料都寫入Primary,Secondary從Primary同步寫入的資料,以保持副本集內所有成員儲存相同的資料集,提供資料的高可用。

上圖是一個典型的MongDB副本集,包含一個Primary節點和2個Secondary節點。

副本集通過replSetInitiate命令(或mongo shell的rs.initiate())進行初始化,初始化後各個成員間開始傳送心跳訊息,併發起Primary選舉操作,獲得『大多數』成員投票支援的節點,會成為Primary,其餘節點成為Secondary。

這裡『大多數』的定義是副本集內可投票成員的一半以上,當副本集記憶體活成員數量不足大多數時,整個副本集將無法選舉出Primary,此時副本集將無法提供寫服務,處於只讀狀態。通常建議將副本整合員數量設定為奇數,因為偶數個節點能容忍的節點失效和比它少1個節點的奇數個節點是一樣的,但是可以節省一個節點的資料儲存成本。

除了初始化的時候會進行選舉,MongoDB副本集的高可用服務體現在,當副本集中沒有Primary節點時,選舉都會進行。比如當Primary節點宕機時,剩下的Secondary節點中會選舉出新的Primary(只需要滿足大多數成員存活的條件)。選舉使用的演算法是基於Raft協議,但是可以通過為節點配置選舉優先順序對選舉結果進行控制。

此外需要提一下,有一些比較常見的特殊的Secondary。一個是Hidden,Hidden節點和普通的Secondary的區別是它是對Driver隱藏的節點,也就是客戶端無法訪問到Hidden,另外就是它的選舉優先順序是0,也就是它不能被選舉為Primary。Hidden節點上擁有資料,因此通常會用來作一些運維任務,如資料備份、計算分析等。

另外還有一個是Arbiter,Arbiter是隻參與投票,但是不儲存資料的節點,這可以用在對可用性有要求,又要嚴格控制成本的場景。

此外還有如Priority0節點、Delayed節點等。

3、MongoDB的水平擴充套件

MongoDB提供了一種水平擴充套件的方式,叫做sharding,通過這種方式對資料庫進行擴容,對應用是透明的。通過sharding,可以將一個集合的資料散到多個shard節點上。這裡每個shard都可以是一組副本集。應用程式通過一個路由節點(mongos)來訪問sharding叢集的資料。有了sharding,MongoDB就可以突破單機的限制,比如磁碟、記憶體和IOPS等,從而提供更強大的服務能力。

Sharded cluster由Shard、Mongos和Config server 3個元件構成。Mongos本身並不持久化資料,Sharded cluster所有的元資料都會儲存到Config Server,而使用者的資料則會分散儲存到各個shard。Mongos啟動後,會從config server載入元資料,開始提供服務,將使用者的請求正確路由到對應的Shard。

Sharded cluster支援將單個集合的資料分散儲存在多個shard上,使用者可以指定根據集合內文件的某個欄位即shard key來分佈資料,目前主要支援2種資料分佈的策略,範圍分片(Range based sharding)或hash分片(Hash based sharding)。

範圍分片下,文件是根據其shard key的值進行分片。shard key的值相鄰近的文件比較有可能會被放在同一個shard上,這種方式適用於需要使用範圍查詢的業務。

雜湊分片下,文件根據其shard key的hash值進行分片。這會保證資料分佈比較均勻,但是不利於範圍查詢。

隨著資料量的增多,MongoDB也會自動在後臺對資料以chunk為單位進行負載均衡。

三、如何搭建MongoDB資料庫即服務

接下來介紹一下今天的重點內容,如何搭建一個MongoDB資料庫即服務。

資料庫

首先,在我看來,資料庫即服務,應該具備這些特性:自動化、按需服務、彈性、安全、高可用和可量化:

  • 第一個,自動化,這是非常關鍵的,是實現自助服務的基礎,所有可以被自動化操作的流程都應該被自動化,不需要人工干預。
  • 第二個,按需服務,資料庫即服務應該是由使用者驅動的,後臺應該要有一個工作流的機制來對需求進行響應。
  • 第三個,彈性,可以按需動態擴縮容。
  • 第四個,安全,這是毋庸置疑的。
  • 第五個,高可用,宕機自動切換。
  • 第六個,可量化,服務的使用量可以被衡量、報告並且是可控的。

此圖為資料庫即服務應具備的功能大圖。主要包括生命週期管理、容災體系、監控報警、資料管理和增值服務:

  • 生命週期管理包括資料庫例項的新建、釋放、擴縮容等,這是資料庫即服務最基礎的功能。
  • 容災體系包括高可用、備份恢復,甚至更高階的如異地容災/多活等等。
  • 監控報警一方面就是服務使用量的監控,另一方面則是報警,包括服務不可用的報警,以及一些監控資料異常的報警。
  • 資料管理指的就是可以方便的對資料進行管理,如可以提供一些圖形化介面等。
  • 增值服務包括審計、診斷服務等。其中審計是資料庫的一個非常重要的功能,一方面可以幫助查證問題,另一方面可以為一些資料分析或診斷提供資料來源。診斷服務一方面跟蹤服務的資源使用量,為是否需要擴縮容提供決策依據,另一方面主要為慢查詢提供優化建議。

資料庫

資料庫即服務的核心架構就是工作流引擎,這是實現自動化及按需服務的基礎。

1、生命週期管理

生命週期管理功能包括資料庫例項的新建、釋放、擴縮容以及遷移。新建一個數據庫例項包括分配資源(主要是主機資源)、安裝資料庫、初始化配置。對MongoDB來說,副本集涉及多個節點,涉及到資源的分配策略,Sharding更多。另外副本集還需要一些初始化工作,sharding需要有一個各元件的組合。釋放例項比較簡單,主要是資源的回收。擴縮容可以分為本地和跨機的擴縮容,其實跨機的擴縮容就是遷移。對於MongoDB來說,遷移可以直接利用MongoDB的新增節點自動同步的特性,還是比較方便的。

生命週期管理功能主要涉及這幾個元件,包括資源管理、規格及配置管理、軟體棧管理和負載均衡:

  • 資源管理主要是指主機資源的管理,這裡主機可以是物理機,也可以是虛擬機器,如雲主機等。資源管理主要負責資源的分配和回收,此外還包括如何實施資源隔離。
  • 規格及配置管理一個是需要為資料庫例項制定一些規格,以方便擴容和縮容,另一方面是負責資料庫相關配置的維護。
  • 軟體棧管理則包括資料庫軟體以及其依賴的軟體的安裝維護等,包括作業系統。
  • 除了這些,還需要一個負載均衡元件來保證資料庫例項在資源上的分佈的均衡,當有主機資源需要下線的時候,能夠做到自動對其上的資料庫例項進行遷移。

對於MongoDB來說,在實施資源分配策略時需要注意的一點是需要保證不要破壞副本集原本的高可用特性。雖然MongoDB副本集自帶了高可用,但是如果你把副本集的所有節點都分佈在一臺物理機上,那如果這個物理機掛了,整個副本集都沒用了。所以一個起碼的原則是要保證MongoDB多副本的主機安全性,儘可能夠做到機架安全。

現在我們的MongoDB資料庫即服務的架構可以稍微擴充一下了,多了資源服務、規格及配置服務、軟體棧服務以及負載均衡服務這幾個元件。

2、容災體系

接下來看一下容災體系,這包括高可用、備份/恢復、異地容災/多活。高可用需要有一個負責健康檢查的巡檢服務,另外還需要有一個容災切換的元件。備份/恢復也是容災體系非常重要的一環,這裡有一個很容易被忽視的事情是需要做備份的有效性驗證。如果備份不是有效的,那等於沒有備份。異地容災/多活是比較高階的容災能力,實施起來比較複雜,有興趣的同學可以參考我之前做過的一個分享《MongoDB異地容災多活實踐》。

(連結:https://yq.aliyun.com/articles/96598)

MongoDB副本集自帶了高可用,我們還需要做什麼工作呢?主要是需要保證容災切換的一個可控。以一個經典的3節點P/S/H副本集為例,一方面我們可以通過配置選舉優先順序的方式來保持Primary和Secondary的角色穩定性。另一方面,我們希望在任意時刻,使用者都可以有兩個節點是可訪問的,因此我們需要對節點宕機後的副本集做一些reconfig操作,保證宕機節點最終都會變成Hidden,然後統一對Hidden進行處理,比如重搭等。

容災

容災體系第二個比較重要的點就是備份恢復。備份主要需要做的是需要提供自動/手動的備份方式以及支援一些靈活的備份策略制定,如備份週期/備份保留時間等。恢復主要是看對恢復的形態做成什麼樣,是覆蓋原來的例項還是克隆出一個新的例項來,還有就是恢復的粒度,這取決於備份能力,是隻能恢復到某個全量備份,還是可以恢復到任意時間點。關於備份儲存,我們要求的最要 能力是高可靠性。另外就是剛剛提過的備份有效性驗證,不能等到火燒眉毛了才發現備份不可用,需要防範於未然。

關於MongoDB的備份方法,相關的文件和分享已經有很多了,這裡再簡單提一下。全量備份從實施方式上可以分為兩種,邏輯備份和物理備份。其中邏輯備份主要使用官方提供的mongodump/mongorestore工具。物理備份則可以在檔案系統或是更底層的邏輯卷、塊裝置這層去做。

從各個指標上對比邏輯備份和物理備份,在備份和恢復效率上,物理備份的優勢比較明顯,不過邏輯備份在相容性上會比較好。

MongoDB的增量備份主要通過持續的抓取oplog來實現。有了全量備份加增量備份,就可以實現恢復到任意時間點。

至此,我們的MongoDB資料庫即服務的架構又可以得到一個比較大的擴充,主要增加了高可用以及備份相關的一些服務。

3、監控報警

接下來看下資料庫的監控報警,效能監控主要涉及效能資料的採集、儲存和展示。採集粒度越細越好,最好能做到秒級。報警則可以分為可用性的報警和效能資料的報警。

具備監控報警能力後的架構圖已經有點滿了,這裡報警服務可以通過巡檢服務和效能資料儲存收集相關資料。

4、增值服務

來看最後一個增值服務,一個是審計,主要涉及審計日誌的採集、儲存和分析。另一個是診斷服務,一個是資源使用量上的診斷,另外一個是慢查詢的診斷,可以做一些索引推薦等。

這就是我們的MongoDB資料庫即服務的完整架構,可以看到元件還是比較多的,做一個數據庫即服務還不是那麼容易的。

總結

最後做一下總結,我認為資料庫即服務的核心特性有兩點,一個是資源池化,另外一個是服務可量化。

資源池化後才可以進行資源的自動管理,而我們需要的服務是要能夠被量化的,並且是可控的。現在回顧一下之前的一鍵安裝資料庫,其實背後有許多工作要做。當然,如果覺得自己搭建一個數據庫即服務太麻煩,可以考慮使用現成的雲服務,比如阿里雲MongoDB資料庫服務:)

Q&A
Q1:這些阿里雲上都有嗎?還是內部再用?池化是多例項還是Docker ?

A1:這些服務,現在阿里雲上的雲資料庫MongoDB都做了,雖然有些功能可能還沒有暴露在控制檯上。多例項還是Docker,具體選擇的技術,其實都可以的。

Q2:想把MySQL的指定表資料儲存到阿里雲的MONGODB有好的實現方式麼?

A2:這個有一些工具可以幹這個事情,可以關注阿里雲的DTS服務,主要是在資料庫中進行資料遷移,另外還有一個datax可以做異構資料庫之間的匯入匯出。

Q3:Mongo單個collection資料達到億級別需要考慮拆分嗎

A3:億級別可以考慮使用sharding了。

Q4:它與Redis的區別主要是什麼?

A4:Redis更多可能還是快取場景吧,MongoDB支援二級索引,可以支援很複雜的查詢。

Q5:測試插入200W資料,為什麼各個分片分配不均衡呢,其中一個分片佔比非常高。shard key 是遞增的。

A5:shard key遞增就會導致在插入時都插入在一個shard上,發揮不了sharding的優勢,可以考慮再組合一個欄位作為shard key。

https://m.qlchat.com/topic/details?topicId=270000444113427&isGuide=Y

密碼:221

原文來自微信公眾號:DBAplus社群