在現實的世界中,任何事情都有兩面性,在程序的世界中,亦然! 我們不論是在使用一門新的語言,還是一門新的技術,在了解它有多么的讓人興奮,讓人輕松,多么的優秀之余,還是很有必要了解一些他的局限性,方便你在實際開發過程中 遇到這些的時候 明白應該怎么處理,在涉及到這些地方的時候,能預先的判斷,文章翻譯自Mongo DB 官網,翻譯的不好,還望大家諒解,同時本人也在使用Mongo DB 對空間地理編碼進行一些操作, 希望大家多多交流 多多指教,在此先行謝過!!!
該筆記提供了一些關於使用Mongo DB時,對軟硬件的一些限定(MongoDB本身的限制)
翻譯至: http://docs.mongodb.org/manual/reference/limits/#shard-key-limitations
BSON 文件大小限制
1.BSON文件的最大限制為 單個文檔不超過16MB。
最大文件大小的限制有助於確保單個文件不會過多的占用內存,在傳輸過程中,不會占用過多的寬帶。當需要存儲到MongoDB中的單個文件大小超過了Mongo DB限制的最大文件大小時,MongoDB 提供了另外一套API—Grid FS 。
2.深度嵌套BSON 文檔
自Mongo DB 2.2版本更新之后, MongoDB 支持單個文件不超過100的BSON文件嵌套。
命名空間
命名空間的長度:在每一個命名空間中,包括數據庫名,集合名稱在內,不得超過123KB。
命名空間數量的限制:命名空間數量的限制 為命名空間的大小除以628. 例如:一個16mb的命名空間能提供約24,000個命名空間, 單個的集合名稱或者索引名稱均為一個命名空 間。
命名空間的文件大小: 命名空間的文件不能超過2047MB. 默認的命名空間大小為16MB,不過你可以通過nsSize 參數來配置命名空間的大小。
在創建數據庫時,系統會創建一個名為[db name].0的文件,當該文件有一半以上被使用時,系統會再次創建一個名為[db name].1的文件,該文件的大小是方才的兩倍。這個情況會持續不斷的發生,因此256、512、1024、2048大小的文件會被寫到磁盤上。最后,再次創建文件時大小都將為2048Mb。如果存儲空間是項目的一個限制,那么你必須要考慮這個情況。
索 引
1.索引鍵的限制 2.6版本更新對比
索引項的總大小(包括索引結構),取決於使用的數據類型(見下圖--BSON Type),但必須小於1024KB.
MongoDB 2.6版本更新后,MongoDB 對索引鍵的創建進行了很強的限制,具體限制內容如下:
a.如果集合的索引數目已經達到最大限制,Mongo DB 不會再為其創建索引項。在2.6 之前,MongoDB會為其創建索引,但不會再去索引這些文檔。
b.如果對索引條目超過索引鍵限制的字段重建索引則會出現錯誤。重建索引的操作會出現在以下情況:執行compact 和 repairDatabase 命令時,調用 db.collection.reIndex()方法時. 因為這些操作會刪除掉集合中現有的所有已建索引,然后嘗試重新創建索引,但索引鍵限制(出現的)錯誤會阻止對集合做任何的索引重建操作。但在使用repairDatabase命令的情況下,程序會繼續往下執行。
c.對於已經存在索引超過索引鍵限制的集合,MongoDB不會再插入任何創建過索引的文檔。相反,會提示一個錯誤。2.6之前,MongoDB會插入帶有索引的文檔,但是不會對插入的文檔進行索引操作。
d.在更新索引的過程中,如果更新的索引值引發了索引超過索引鍵限制(的錯誤),則會返回一個錯誤信息。
e.如果一個文檔中包含了 超過索引鍵限制的片鍵,對於該文件的任何更新,移動,都會出現錯誤。
If an existing document contains an indexed field whose index entry exceeds the limit, any update that results in the relocation of that document on disk will error.
f.mongorestore 和 mongoimport 不會對任何出現索引超過索引鍵限制的的集合插入新的文檔。
g.在 2.6版本中,如果索引超過了索引限制數目,在進行集成的初始同步時,二級副本集成員會繼續執行文件復制操作,但是會在日志中打印警告信息。
如果副本集中的MongoDB 不是同一個版本,主級版本為2.4,副級版本為2.6,副級會按照2.4的版本將已經插入或更新的文件復制到主服務器。但是,如果文檔中存在所建索引項超過索引創建限制的文檔,MongoDB會將錯誤信息打印到日志文件中.
h.對於現有的分片集合,如果數據塊有一個文檔,其中包含一個片鍵的索引條目超過索引鍵限制。執行 chunk migration (塊遷移)時會失敗。
2.每個集合的索引個數:每個集合可以創建(不超過)64個索引.
3.索引名稱長度: 完全限定名(包括名稱和點分隔符,例如databse.collection.indexName)不超過128個字符。
4.復合索引的片鍵:在創建復合索引時,復合索引中的字段不得超過31個。
5.查詢時,不能同時使用文本索引和地理空間索引:在進行一個查詢操作時,需要一個不同類型的特殊索引,你不能混合的使用 text命令來執行特殊的文本索引(text index)。 比如,你不能同時使用 text 和 $near 命令來進行查詢 ($near 用於地理編碼中的空間查詢,text 用於一般的文本檢索)
數 據
集合的最大文檔數上限
Mongo DB 2.4版本后, 如果你使用max參數來設定允許在集合中創建的最大文檔數,則文檔的最大限制數必須保證在2的32次方之內;如果創建集合時沒有指定最大文檔個數,那么可以創建的文檔個數是不受限制的。
數據大小
單個mongod實例不能管理一個數據集超過操作系統提供的最大虛擬內存地址空間。
數據庫中集合的數量
數據庫中集合的的最大數量是由命名空間文件的大小和集合中的索引數量決定的。 更多詳細信息請回看 命名空間 .
副 本 集
副本集中的成員數量: 一個副本集中最多能包含12個成員(節點),如果你的應用中集群的節點有12個以上,你就應該考慮使用主重復制了。
在副本集中能參與選舉的成員數量: 在副本集中,只有7個成員能在任意特定時間內具有選舉的權利,更多信息請參見--副本集選舉
自動創建的操作日志的最大值: 在2.6版本后,如果你沒有明確的指定操作日志的大小(比如 通過設置oplogSizeMB 或者--oplogSize),MongoDB 會自動創建一個不超過50GB的操作日志。
分 片 集 群
這里僅僅只提供分片集群的限制和閥值
分片操作限制
在分片環境下,不可以使用的操作:
1.在分片中, group 是無法使用的, 你應該用mapReduce 或者 aggregate 代替 group.
2.db.eval()在分片集合中是無法兼容的,你可能只有在分片集群中尚未進行分片的集合中使用db.eval().
3.$where 函數將不允許引用DB的對象,這在非分片的集合中是罕見的。
4.$isolated 在分片集群環境下更新修改器是不起效的。
5.$snapshot 在該環境下失效。
6.geoSearch命令也不支持分片。
分片集群中的覆蓋查詢:MongoDB中不支持在分片集合中進行覆蓋查詢。
現有(分片)集合的數據大小:
對於現有存在的集合,MongoDB支持對不大於256GB的文件集合進行分片。根據文件大小的分布,MongoDB最多能對高達400GB的集合文件進行分片。
MongoDB能精確的限制塊的大小和數據的大小
重要提示:當成功進行分片后,分片集合本身會占用一定的空間。
分片集合中的單文檔修改
在分片集合中進行的所有update()和remove()操作,必須明確的指定 justOne 或者 multi:false ,並且必須在查詢參數中包含有 片鍵(shard key) 或 _id 字段(mongodb 自帶的唯一標識符) 。 如果update() 和 remove()操作指定了 justOne 或者multi:false 但並未指定 片鍵(shard key)或者 _id 字段,那么將返回一個錯誤信息。 注:片鍵(shard key )可以包含集合中的多個字段(field)
分片集合中的唯一索引鍵
MongoDB不支持通過分片創建唯一索引鍵,除非該唯一索引鍵以完整的分片字段作為索引的前綴,在這種情況下,MongoDB會通過這個完整的字段強制創建一個唯一索引,而不再是對單一的一個字段創建索引。
參考:Enforce Unique Keys for Sharded Collections查看另外一種實現方式。
片鍵的限制
片鍵的大小限制: 片鍵的總長度不得超過512bytes.
片鍵的類型: 片鍵的類型可以是一個升序排列的索引 也可以是一個片鍵開頭並指定排列順序的復合索引 或者散列索引。
片鍵的索引不能被指定為下列類型的索引:multikey index , text index ,geospatial index.
片鍵是不可變的
在已經完成的分片集合中,不能再修改片鍵,如果必須要修改:
1. 將MongoDB中的所有數據轉成成其他格式
2.刪除掉之前的分片集合。
3.通過配置讓分片使用新的(需要修改成的)片鍵;
4.預划分片鍵的范圍,確保能在初始化的時候能均勻分布
5.還原之前的數據到MongoDB.
文檔中 片鍵的值是不可變的
在成功的向已分片的集合中新增一個文檔后,你不能修改這個文檔中被用於創建索引的字段的值, update()操作也不會再更新這個文檔中被用於創建索引的字段的值。
遞增的片鍵能有效的限制插入的吞吐量
對於新增操作量很大的集群,遞增的片鍵能很好的有效的限制插入的吞吐量。如果你的片鍵是_id,你需要注意的是 ObjectId類型的_id,其值通常是自增的。
通過遞增索引來插入文檔,所有插入的文檔都屬於同一個分片中的塊,系統最終會接收所有的寫入操作並合理的將寫入的內容分配到不同的塊中,目的是為平均的分配數據。 然而,在任何時候集群會直接將新增文檔插入到一個分片中,這就造成了插入時吞吐量的瓶頸。
如果集群主要負責讀取和更新操作,那么這種限制並不影響集群。
為了避免這種約束,可以使用散列片鍵或者選擇一個非自增或者減少自增的字段(select a field that does not increase or decrease monotonically.)。
在2.4的版本中:散列片鍵和散列索引 按照值的順序排列來存儲起索引鍵。
操 作
存儲文檔
如果排序操作所使用的內存不到32MB,那么MongoDB 將只返回沒有片鍵的排序結果
聚合管道操作
在2.6的版本更新中,管道階段將對內存有一個100MB的限制,如果該段超過了這個限制,MongoDB會產生一個錯誤,為了允許處理大數據集,可以使用 allowDiskUse參數來確保在聚合管道階段能將數據寫入臨時文件。 請參見$sort and Memory Restrictions and $group Operator and Memory.
使用 2d進行空間查詢時,不能使用 $or 操作符,請參見$or and 2d Index Internals.
球面多邊形必須適合半球操作
任何使用GeoJSON中的$geoIntersects 或 $geoWithin進行幾何查詢時,必須適合半球。MongoDB在解析幾何圖形時,超過一半的球體將作為互補的較小的幾何圖形來進行的查詢。
寫入命令操作的 限制大小
寫入命令能接收不超過1000個的操作。mongo腳本中的Bulk()及類似的方法則對此沒有限制。
命名的限制
數據庫名嚴格區分大小寫:MongoDB 不允許僅通字母的大小寫來卻分數據庫的名稱。例如test和Test
Window操作系統中數據庫名稱的限制(2.2版本中更新):
如果MongoDB的開發環境在Windows系統下,MongoDB不允許在數據庫的名字中出現以下字符:/\. "*<>:|?
同時,數據庫名不能包含空字符
Unix/Linux系統下命名的限制
如果MongoDB的開發環境在Windows系統下,MongoDB不允許在數據庫的名字中出現以下字符: /\. "
同時,數據庫名不能包含空字符
數據庫名稱的長度限制:數據庫名稱不能為空且必須控制在64個字符范圍內。
集合名稱的限制(2.2版本中更新):
集合的名稱應該以下划線或者字母開頭,並且名稱中不能包含: $ , 空字符串(空格), 空字符(null character),不能以system作為前綴。在mongo腳本中,使用db.getCollection()來指定集合名稱可能會和腳本沖突,或者被當做不被驗證通過的JAVAScript.
字段名稱的限制:字段名稱中不能包含" . ","$" , 或者 空字符(null character) 參見 Dollar Sign Operator Escaping 查閱另一種方式。