網站首頁 編程語言 正文
概述
介紹
分片(sharding)是MongoDB用來將大型集合分割到不同的服務器(或者說一個集群)上所采用的方法,盡管分片起源于關系型數據庫分區,但MongoDB分片完全又是另一回事。
和MySQL分區方案相比,MongoDB的最大區別在于它幾乎能自動完成所有事情,只要告訴MongoDB要分配數據,它就能自動維護數據在不同服務器之間的均衡。
分片的目的
高數據量和吞吐量的數據庫會對單機的性能造成較大壓力,大的查詢量會將單機的CPU耗盡,大的數據量對單機的存儲壓力較大,最終會耗盡系統的內存而將壓力轉移到磁盤IO上。
為了解決這些問題,有兩個基本的方法:垂直擴展和水平擴展。
垂直擴展:增加更多的CPU和存儲資源來擴展容量。
水平擴展:將數據集分布在多個服務器上,水平擴展即分片。
分片設計思想
分片為應對高吞吐量與大數據提供了方法,使用分片減少了每個分片需要處理的請求數,因此,通過水平擴展,集群可以提高自己的存儲容量和吞吐量,舉例來說,當插入一條數據時,應用只需要訪問存儲這條數據的分片。
使用分片減少了每個分片存儲的數據。
例如,如果數據庫1TB的數據集,并有4個分片,然后每個分片可能僅持有256GB的數據。如果有40個分片,那么每個分片可能只有25GB的數據。
分片機制的三種優勢
- 對集群進行抽象,讓集群“不可見”。
MongoDB自帶了一個叫作mongos的專有路由進程。mongos就是掌握統一路口的路由器,其會將客戶端發來的請求準確無誤的路由到集群中的一個或者一組服務器上,同時會把接收到的響應拼裝起來發回到客戶端。 - 保證集群總是可讀寫
MongoDB通過多種途徑來確保集群的可用性和可靠性,將MongoDB的分片和復制功能結合使用,在確保數據分片到多臺服務器的同時,也確保了每份數據都有響應的備份,這樣就可以確保有服務器壞掉時,其他的從庫可以立即接替壞掉的部分繼續工作。 - 使集群易于擴展
當系統需要跟多的空間和資源的時候,MongoDB使我們可以按需方便的擴充系統容量。
分片集群架構節點
組件 | 說明 |
---|---|
Config Server | 存儲集群所有節點、分片數據路由信息。默認需要配置3個Config Server節點。 |
Mongos | 提供對外應用訪問,所有操作均通過mongos執行,一般有多個mongos節點。 |
Mongod | 存儲應用數據記錄,一般有多個Mongod節點,達到數據分片目的。 |
集群架構圖
- mongos
數據路由,與客戶端打交道的模塊,mongos本身沒有任何數據,它也不知道該怎么處理這數據,去找config server。 - config server
所以shard節點的信息、存儲數據的方式,分片功能的一些配置信息,可以理解為真實數據的元數據。 - shard
真正的數據存儲位置,以chunk為單位存儲數據。
chunk(數據塊)是什么
在一個shard server內部,MongoDB還是會把數據分為chunks,每個chunks代表這個shard server內部一部分數據。chunk的產生,會有以下兩個用途:
- Splitting:當一個chunk的大小超過配置中的chunk size是,MongoDB的后臺進程會把這個chunk切分成更小的chunk,從而避免chunk過大的情況。
- Balancing:在MongoDB中,balancer(平衡器)是一個后臺進程,負責chunk的遷移,從而均衡各個shard server的負載,系統初始1個chunk,chunk size默認值64M,生產庫上選擇適合業務的chunk size是最好的。mongoDB會自動拆分和遷移chunks。
分片集群節點的數據分布
- 使用chunk來存儲數據。
- 集群搭建完成后,默認開啟一個chunk,大小是64M。
- 存儲需求超過64M,chunk會進行分裂,如果單位時間存儲需求很大,設置更大的chunk。
- chunk會被自動均衡遷移。
如何選擇chunksize
小的chunksize:數據均衡是遷移速度快,數據分布更均勻,數據分裂頻繁,路由節點消耗更多資源。
大的chunksize:數據分裂少。數據塊移動會集中消耗IO資源,chunk通常設置在100-200M。
適合業務的chunksize是最好的,一般默認就好;
chunk的分裂和遷移非常消耗IO資源;
chunk分裂的時機:在插入和更新時,讀數據不會分裂。
chunk分裂及遷移
隨著數據的增大,其中的數據大小超過了分配中的chunk size,默認是64M,則這個chunk就會分裂成兩個。
這時候,各個shard上的chunk數量就會不平衡。這時候,mongos中的一個組件balancer就會執行自動平衡,把chunk從chunk數量最多的shard節點挪到到數量最小的節點。
chunkSize對分裂及遷移的影響
- MongoDB默認的chunkSize為64MB,如無特殊需求,建議保持默認值;chunkSize會直接影響到chunk分裂、遷移的行為。
- chunkSize越小,chunk分裂及遷移越多,數據分布越均衡;反之,chunkSize越大,chunk分裂及遷移會更少,但可能導致數據分布不均勻。
- chunk自動分裂只會在數據寫入時觸發,所以如果將chunkSize改小,系統需要一定的時間來將chunk分裂到指定的大小。
- chunk只會分裂,不會合并,所以即使將chunkSize改大,現有的chunk數量不會減少,但chunk大小會隨著寫入不斷增長,直到達到目標大小。
shard key分片鍵
MongoDB中數據的分片是,以集合為基本單位的,集合中的數據通過片鍵(shard key)被分成多部分。其實片鍵就是在集合中選一個鍵,用該鍵的值作為數據拆分的依據。
所以一個好的片鍵對分片至關重要,片鍵必須是一個索引。
對集合進行分片時,你需要選擇一個片鍵,片鍵是每條記錄都必須包含的,且建立了索引的單個字段或復合字段,MongoDB按照片鍵將數據劃分到不同的數據塊中,并將數據塊均衡地分布到所有分片中。
分片鍵策略
- 一個自增的片鍵對寫入和數據均勻分布就不是很好。因為自增的片鍵總會在一個分片上寫入,后續達到某個閾值可能寫到別的分片,但是按照片鍵查詢會非常高效。
- 隨機片鍵對數據的均勻分布效果很好。注意盡量避免在多個分片上進行查詢,在所有分片上查詢,mongos會對結果進行歸并排序。
- MongoDB使用基于范圍的分片方式或者基于hash的分片方式。
- 注意事項:
- 分片鍵是不可變的。
- 分片鍵必須有索引。
- 分片鍵大小限制512bytes。
- 分片鍵用于路由查詢。
- 鍵的文檔(分片鍵字段不支持空值插入)。
基于范圍的分片方式
Sharded Cluster支持將單個集合的數據分散存儲到多shard上,用戶可以指定根據集合內文檔的某個字段即shard key來進行范圍分片(range sharding)。
對于基于范圍的分片,MongoDB按照片鍵的范圍把數據分成不同部分。
假設有一個數字的片鍵:想象一個從負無窮到正無窮的直線,每一個片鍵的值都在直線上畫一個點。MongoDB把這條直線劃分為更短的步重疊的片段,并稱之為數據塊,每個數據塊包含了片鍵在一定范圍內的數據。在使用片鍵做范圍劃分的系統中,擁有“相近”片鍵的文檔很可能存儲在同一個數據塊中,因此也會存儲在同一個分片中。
基于哈希的分片方式
分片過程中利用哈希索引作為分片的單個鍵,且哈希分片的片鍵只能使用一個字段,而基于哈希片鍵最大的好處就是保證數據在各個節點分片基本均勻。
對于基于哈希的分片,MongoDB計算一個字段的哈希值,并用這個哈希值來創建數據塊。在使用基于哈希分片的系統中,“相近”片鍵的文檔很可能不會存儲在同一個數據塊中,因此數據的分離性更好一些。
Hash分片與范圍分片互補,能將文檔隨機的分散到各個chunk中,充分的擴展寫能力,彌補了范圍分片的不足,但不能高效的服務范圍查詢,所有的范圍查詢,要分發到后端所有的shard,才能找出滿足條件的文檔。
分片集群部署的常見錯誤
- 配置可復制集作為分片節點與配置單獨使用的可復制集基本一樣。但啟動參數需要指定–shardsvr參數。否則,在啟動數據庫分片時報錯:{“code”:193,“ok”:0,“errormsg”:“Cannot accept sharding commands if not started with --shardsvr”}。
- 分片不會默認生成,需要現在數據庫中啟動分片(sh.enableSharding{“DBName”}),然后再設置集合分片(sh.shardCollection(“Collection”{片鍵}))。
原文鏈接:https://blog.csdn.net/tianzhonghaoqing/article/details/125702985
相關推薦
- 2021-12-10 addEventListener的執行函數使用具名函數并傳參,可使用removeEventListe
- 2022-08-16 Oracle數據庫事務的開啟與結束詳解_oracle
- 2023-06-19 阿里低代碼框架lowcode-engine設置默認容器詳解_React
- 2022-12-16 python實例方法的使用注意及代碼實例_python
- 2023-11-23 python怎么判斷電腦環境是32位還是64位
- 2022-09-04 django連接數據庫獲取數據的簡單步驟記錄_python
- 2022-11-23 關于vba代碼運行時錯誤1004?應用程序定義或對象定義錯誤問題_VBA
- 2022-05-13 python實現簡易圖書管理系統_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支