fbpx

MongoDB Sharding 分散式儲存架構建置 (概念篇)

MongoDB Sharding 簡介

Sharding 為 MongoDB 所擁有的一種資料分散處理架構,簡單的說就是將資料分片 (Shard) 儲存到不同的機器中,最常應用在大數據的案例上。在海量資料的儲存情境上,垂直擴充架構是無法滿足的,必須透過水平擴充來實現。

MongoDB Sharded Cluster 基本的架構示意如下:

sharded-collection

在這樣的機制下,儲存進 Collection 的資料會被盡可能平均地分散到每一個 Shard 上,每一個 Shard 都是由獨立的 mongod 實體或者 Replica Set 所構成 (想了解 Replica Set 可以看看之前的文章)。上圖我們也可以看到,Sharding 機制本身是不負責備份的,在產品上線的環境中,強烈建議使用 Replica Set 來搭建 MongoDB Sharded Cluster。在這個架構中,假設我們有 1TB 的資料,可以透過 Sharding 機制將資料切分為四個 Shard,每一個 Shard 負責儲存 256G,應該很好理解。

MongoDB Sharded Cluster 運作機制

那麼 MongoDB Sharded Cluster 是如何運作的呢?我們先看看下面的架構圖:

sharded-cluster-production-architecture

當使用者或應用程式 (Driver) 要操作 MongoDB Sharded Cluster 時,是透過 mongos 來進行連接,mongos 扮演 Router 的角色,Router 通常由多個實體組成,可以將 Loading 分散處理,保持高可用性 (HA)。對於應用程式來說,並不需要瞭解 MongoDB Sharding 怎麼運作的,他們看到的只是一個資料庫,所以使用上基本不會有太大的差別。如下所示:

sharded-cluster

之前提到,雖然每一個 Shard 都是由一個 mongod 或 Replica Set 構成,但如果沒有透過 mongos (Router) 進行連線操作,而直接對 Shard 進行連線,那麼你看到 Collection 的資料就不會是完整的集合,而只是單一個 Shard 的資料。那麼 Cluster 是如何分配資料呢,這裡有一個很重要的角色,就是 Config Server。

Config Server

Config Server 是 MongoDB Sharding 架構中相當重要的一個角色,它存放了資料的 Metadata,包括透過 Shard Key 計算出來的索引,用來記錄每一個資料存放的 Shard 位置,好讓 Router 可以正確的 Query 資料,如果沒有這些索引,那麼每一個用來存放資料的 mongod 實體,就「純粹」只是獨立存放分散的資料,無法協同工作。Config Server 聽起來很重要對吧!?因此 Config Server 部署時必須要多台機器,在新版 3.2 之後也可以用 Replica Set 架設 Config Server。

Data Partitioning 機制

為了將資料分散儲存,就必須找一個方法來管理 Index,我們必須將 Document 某一個欄位定義為 Shard Key,然後透過 range based partitioning 或 hash based partitioning 其中一中方式將資料分配到 chunks 中 (每一個 Chunks 預設的大小為 64MB),最後才將 Chunks 分散到不同的 Shard 上。接下來我們先看看兩種不同的 Partitioning 機制:

Range Based Sharding

這種方式就是將 Document Shard Key 欄位的值,以線性的方式進行分群,透過 Range 範圍進行切割,相近的值理所當然會被分到同一個 Chunk 中,Chunk 分配的情況會直接受到 Range 的影響(比如某一段 Range 出現頻率高,Chunk 資料就比較大)。用這種方法我們必須考慮 Shard Key 的範圍,如下所示:

sharding-range-based

Hash Based Sharding

這種方法顧名思義就是透過「雜湊函式」將我們指定的 Shard Key 欄位進行雜湊,這樣的方式資料比較容易分散到每個 Shard 中,如果資料量足夠豐富,佔用空間的分配也會比較平均。如下:

sharding-hash-based

比較一下兩種方法,Range Based 實際在 Query 時,Router 可以很輕易地判斷資料的位置,然後正確地派送運算到所屬的 Shard 上。但如果要查詢的資料片段大小差異過高,且又分散在不同的 Shard 上,查詢必定會「等待」其他 Shard 處理的情況產生。來看看 Hash Based,Shard Key 透過 Hash 計算後,很容易分散在不同的 Chunk,資料分散性佳,擴充也比較容易。但是在 Query 時就必須要經過比較多的 Shard 計算,才能由 Router 返回最後的結果。兩種方法各有利弊,可以依照實際的應用情況選用。那如果想要自行實作資料分散的邏輯呢?MongoDB 當然也是支援的,就是透過 Tag 這個功能,但我沒有研究,所以就無從介紹了。有興趣可以看看官方 Tag Aware Sharding 相關介紹。

MongoDb Sharding 的概念先介紹到這裡了,下個單元繼續介紹實做的方法,敬請期待.......嗚喔~

MongoDB 系列文章

發佈留言