1、MongoDB分片
1.1 為什么需要Sharded cluster?
MongoDB目前3大核心優勢:靈活模式+ 高可用性 + 可擴展性。通過Json文檔格式來實現靈活模式,通過復制集來保證高可用,通過Sharded cluster來保證可擴展性。
分片技術,使得集合中的數據分散到多個分片集中。使得MongoDB具備橫向的發展。
1.2 何時使用分片技術
- 存儲容量需求超出單機磁盤容量
- 活躍的數據集超出單機內存容量,導致很多請求都要從磁盤讀取數據,影響性能
- 寫IOPS超出單個MongoDB節點的寫服務能力
1.3 分片概述
- 當數據量比較大的時候,我們需要把數分片運行在不同的機器中,以降低CPU、內存和Io的壓力,Sharding就是數據庫分片技術。
- MongoDB分片技術類似MySQL的水平切分和垂直切分,數據庫主要由倆種方式做Sharding:垂直擴展和橫向切分。
- 垂直擴展的方式就是進行集群擴展,添加更多的CPU,內存,磁盤空間等。
-
橫向切分則是通過數據分片的方式,通過集群統一提供服務。
image.png
2 MongoDB分片架構原理
2.1 分片組成
Sharded cluster 組成:Shard、Mongos和Config server 3個組件構成。
Mongos是Sharded cluster的訪問入口,
Mongos本身并不持久化數據,Sharded cluster所有的元數據都會存儲到Config Server
而用戶的數據則會分散存儲到各個shard。Mongos啟動后,會從config server加載元數據,開始提供服務,將用戶的請求正確路由到對應的Shard。
2.2 MongoDB分片架構中的角色
1、數據分片(Shards)
用來保存數據,保證數據的高可用性和一致性。可以是一個單獨的mongod實例,也可以是一個副本集。在生產環境下Shard一般是一個Replica Set,以防止該數據片的單點故障。所有Shard中有一個PrimaryShard,里面包含未進行劃分的數據集合:
2、查詢路由(Query Routers)
路由就是mongos的實例,客戶端直接連接mongos,由mongos把讀寫請求路由到指定的Shard上去。
一個Sharding集群,可以有一個mongos,也可以有多個mongos以減輕客戶端請求的壓力。
3、配置服務器(Config servers)
保存集群的元數據(metadata),包含各個Shard的路由規則。
總結:
1、配置服務器。是一個獨立的mongod進程,保存集群和分片的元數據,即各分片包含了哪些數據的信息。最先開始建立,啟用日志功能。像啟動普通的mongod一樣啟動配置服務器,指定configsvr選項。不需要太多的空間和資源,配置服務器的1KB空間相當于真是數據的200MB。保存的只是數據的分布表。當服務不可用,則變成只讀,無法分塊、遷移數據。
2、 路由服務器。即mongos,起到一個路由的功能,供程序連接。本身不保存數據,在啟動時從配置服務器加載集群信息,開啟mongos進程需要知道配置服務器的地址,指定configdb選項。
3、分片服務器。是一個獨立普通的mongod進程,保存數據信息。可以是一個副本集也可以是單獨的一臺服務器。
2.4 Sharding分片技術(混合模式)高可用方案的架構圖
3 數據讀寫流程
3.1 Sharding分片技術(混合模式)高可用架構下MongoDB數據寫入流程
寫入流程:
第一步:客戶端訪問路由服務器(Mongos),路由服務器接收到請求。
第二步:路由服務器將客戶端訪問配置服務器,配置服務器(Config)根據根據請求信息將數據信息寫入到元數據中。
第三步:配置服務器將根據自身記錄的元數據信息,指定數據存儲位置,并將元數據信息(數據存儲位置)返回給路由服務器。
第四步:路由服務器根據Config服務器返回的配置信息,將數據存儲到mongod中(數據存儲服務器)。存儲服務器對數據進行備份和分片存儲。
3.2 高可用集群下從MongoDB讀取數據流程
讀取數據流程:
第一步:Mongos接受客戶端請求,根據并判斷請求是否合理(數據庫地址是否正確,連接數是否超過最大)
第二步:路由服務器與客戶端建立連接,并根據請求信息,去Config服務器中查詢元數據信息。
第三步:config服務器將數信息返回給路由服務器。
第四步: config服務器根據元數據信息(數據存儲位置),去MongoD服務器中,查詢數據。
第五步:數據服務器將數據查詢結果返回給路由服務器。
4 數據分布策略
分片支持單個集合的數據分散在多個分片上。目前主要有兩種數據分片的策略。
范圍分片(Range based sharding)
hash分片(Hash based sharding)
4.1 范圍分片策略
如圖,集合是根據字段來進行分片。根據字段的范圍不同將一個集合的數據存儲在不同的分片中。 在同一個Shard上,每個Shard可以存儲很多個chunk,chunk存儲在哪個shard的信息會存儲在Config server種,mongos也會根據各個shard上的chunk的數量來自動做負載均衡。 范圍分片適合滿足在一定范圍內的查找,例如查找X的值在【100-200】之間的數據,mongo 路由根據Config server中存儲的元數據,可以直接定位到指定的shard的Chunk中 缺點 如果shardkey有明顯遞增(或者遞減)趨勢,則新插入的文檔多會分布到同一個chunk,無法擴展寫的能力
4.2 Hash分片
Hash分片是根據用戶的shard key計算hash值(64bit整型),根據hash值按照『范圍分片』的策略將文檔分布到不同的chunk
優點:Hash分片與范圍分片互補,能將文檔隨機的分散到各個chunk,充分的擴展寫能力,彌補了范圍分片的不足,
缺點:但不能高效的服務范圍查詢,所有的范圍查詢要分發到后端所有的Shard才能找出滿足條件的文檔。
合理的選擇shard key
選擇shard key時,要根據業務的需求及『范圍分片』和『Hash分片』2種方式的優缺點合理選擇,要根據字段的實際原因對數據進行分片,否則會產生過大的Chunk
Mongos
Mongos作為Sharded cluster的訪問入口,所有的請求都由mongos來路由、分發、合并,這些動作對客戶端driver透明,用戶連接mongos就像連接mongod一樣使用。
查詢請求
查詢請求不包含shard key,則必須將查詢分發到所有的shard,然后合并查詢結果返回給客戶端
查詢請求包含shard key,則直接根據shard key計算出需要查詢的chunk,向對應的shard發送查詢請求寫請求
寫操作必須包含shard key,mongos根據shard key算出文檔應該存儲到哪個chunk,然后將寫請求發送到chunk所在的shard。更新/刪除請求
更新、刪除請求的查詢條件必須包含shard key或者_id,如果是包含shard key,則直接路由到指定的chunk,如果只包含_id,則需將請求發送至所有的shard。其他命令請求
Config Server
config database
Config server存儲Sharded cluster的所有元數據,所有的元數據都存儲在config數據庫
Config Server可部署為一個獨立的復制集,極大的方便了Sharded cluster的運維管理。
config.shards
config.shards集合存儲各個Shard的信息,可通過addShard、removeShard命令來動態的從Sharded cluster里增加或移除shard
config.databases
config.databases集合存儲所有數據庫的信息,包括DB是否開啟分片,primary shard信息,對于數據庫內沒有開啟分片的集合,所有的數據都會存儲在數據庫的primary shard上。
config.colletions
數據分片是針對集合維度的,某個數據庫開啟分片功能后,如果需要讓其中的集合分片存儲,則需調用shardCollection命令來針對集合開啟分片。
config.chunks
集合分片開啟后,默認會創建一個新的chunk,shard key取值[minKey, maxKey]內的文檔(即所有的文檔)都會存儲到這個chunk。當使用Hash分片策略時,也可以預先創建多個chunk,以減少chunk的遷移。
config.settings
config.settings集合里主要存儲sharded cluster的配置信息,比如chunk size,是否開啟balancer等
其他集合
config.tags主要存儲sharding cluster標簽(tag)相關的你洗
config.changelog主要存儲sharding cluster里的所有變更操作,比如balancer遷移chunk的動作就會記錄到changelog里
config.mongos存儲當前集群所有mongos的信息
config.locks存儲鎖相關的信息,對某個集合進行操作時,比如moveChunk,需要先獲取鎖,避免多個mongos同時遷移同一個集合的chunk。
至此:分片集群架構及原理介紹完畢。