MongoDB的分片集群配置
來源:程序員人生 發布時間:2015-07-28 08:05:29 閱讀次數:3467次
1、分片
概念:在Mongodb里面存在另外一種集群,就是分片技術,可以滿足MongoDB數據量大量增長的需求。
當MongoDB存儲海量的數據時,1臺機器可能不足以存儲數據也足以提供可接受的讀寫吞吐量。這時候,我們就能夠通過在多臺機器上分割數據,使得數據庫系統能存儲和處理更多的數據。
1.分片簡介
分片是指將數據拆分,將其分散存在不同機器上的進程.有時也叫分區.將數據分散在不同的機器上,不需要功能
強大的大型計算機就能夠存儲更多的數據,處理更大的負載.
使用幾近所有
數據庫軟件都能進行手動分片,利用需要保護與若干不同
數據庫服務器的連接,每一個連接還是完全
獨立的.利用程序管理不同
服務器上的不同數據,存儲查村都需要在正確的
服務器上進行.這類方法可以很好的工作,但是也
難以保護,比如向集群添加節點或從集群刪除節點都很困難,調劑數據散布和負載模式也不輕松.
MongoDB支持自動分片,可以擺脫手動分片的管理.集群自動切分數據,做負載均衡.
2.MongoDB的自動分片
MongoDB分片的基本思想就是將集合切分成小塊.這些塊分散到若干片里面,每一個片只負責總數據的1部份.利用程序沒必要知道
哪片對應哪些數據,乃至不需要知道數據已被拆分了,所以在分片之前要運行1個路由進程,進程名mongos,這個路由器知道
所有數據的寄存位置,所以利用可以連接它來正常發送要求.對利用來講,它僅知道連接了1個普通的mongod.路由器知道和片的
對應關系,能夠轉發要求到正確的片上.如果要求有了回應,路由器將其搜集起來回送給利用.
在沒有分片的時候,客戶端連接mongod進程,分片時客戶端會連接mongos進程.mongos對利用隱藏了分片的細節.
從利用的角度看,分片和不分片沒有區分.所以需要擴大的時候,沒必要修改利用程序的代碼.
甚么時候需要分片:
a.機器的磁盤不夠用了
b.單個mongod已不能滿足些數據的性能需要了
c.想將大量數據放在內存中提高性能
1般來講,先要從不分片開始,然后在需要的時候將其轉換成份片.
3.片鍵
設置分片時,需要從集合里面選1個鍵,用該鍵的值作為數據拆分的根據.這個鍵成為片鍵.
假定有個文檔集合表示的是人員,如果選擇名字"name"做為片鍵,第1篇可能會寄存名字以A-F開頭的文檔.
第2片存G-P開頭的文檔,第3篇存Q-Z的文檔.隨著增加或刪除片,MongoDB會重新平衡數據,是每片的流量比較
均衡,數據量也在公道范圍內(如流量較大的片寄存的數據也許會比流量下的片數據要少些)
4.將已有的集合分片
假定有個存儲日志的集合,現在要分片.我們開啟分片功能,然后告知MongoDB用"timestamp"作為片鍵,就要所有數據放到
了1個片上.可以隨便插入數據,但總會是在1個片上.
然后,新增1個片.這個片建好并運行了以后,MongoDB就會把集合拆分成兩半,成為塊.每一個塊中包括片鍵值在1定
范圍內的所有文檔,假定其中1塊包括時間戳在2011.11.11前的文檔,則另外一塊含有2011.11.11以后的文檔.其中
1塊會被移動到新片上.如果新文檔的時間戳在2011.11.11之前,則添加到第1塊,否則添加到第2塊.
5.遞增片鍵還是隨機片鍵
片鍵的選擇決定了插入操作在片之間的散布.
如果選擇了像"timestamp"這樣的鍵,這個值可能不斷增長,而且沒有太大的中斷,就會將所有數據發送到1個片上
(含有2011.11.11以后日期的那片).如果有添加了新片,再拆分數據,還是會都導入到1臺
服務器上.添加了新片,
MongoDB肯能會將2011.11.11以后的拆分成2011.11.11⑵021.11.11.如果文檔的時間大于2021.11.11以后,
所有的文檔還會以最后1片插入.這就不合適寫入負載很高情況,但依照片鍵查詢會非常高效.
如果寫入負載比較高,想均勻分散負載到各個片,就得選擇散布均勻的片鍵.日志例子中時間戳的散列值,沒有模式的"logMessage"
都是復合這個條件的.
不論片鍵隨機跳躍還是穩定增加,片鍵的變化很重要.如,如果有個"logLevel"鍵的值只有3種值"DEBUG","WARN","ERROR",
MongoDB不管如何也不能把它作為片鍵將數據分成多于3片(由于只有3個值).如果鍵的變化太少,但又想讓其作為片鍵,
可以把這個鍵與1個變化較大的鍵組合起來,創建1個復合片鍵,如"logLevel"和"timestamp"組合.
選擇片鍵并創建片鍵很像索引,以為2者原理類似.事實上,片鍵也是最經常使用的索引.
6.片鍵對操作的影響
終究用戶應當沒法辨別是不是分片,但是要了解選擇不同片鍵情況下的查詢有何不同.
假定還是那個表示人員的集合,依照"name"分片,有3個片,其名字首字母的范圍是A-Z.下面以不同的方式查詢:
db.people.find({"name":"Refactor"})
mongos會將這個查詢直接發送給Q-Z片,取得響應后,直接轉發給客戶端
db.people.find({"name":{"$lt":"L"}})
mongos會將其先發送給A-F和G-P片,然后將結果轉發給客戶端.
db.people.find().sort({"email":1})
mongos會在所有片上查詢,返回結果時還會做歸并排序,確保結果順序正確.
mongos用游標從各個
服務器上獲得數據,所以沒必要等到全部數據都拿到才向客戶端發送批量結果.
db.people.find({"email":"refactor@msn.cn"})
mongos其實不追蹤"email"鍵,所以也不知道應當將查詢發給那個片.所以他就向所有片順序發送查詢.
如果是插入文檔,mongos會根據"name"鍵的值,將其發送到相應的片上.
2.如何分片?
1.建立分片
建立分片有兩步:啟動實際的
服務器,然后決定怎樣切分數據.
分片1般會有3個組成部份:
a.片
片就是保存子集合數據的容器,片可是單個的mongod
服務器(開發和測試用),也能夠是副本集(生產用).所以1片
有多臺
服務器,也只能有1個主
服務器,其他的
服務器保存相同的數據.
b.mongos
mongos就是MongoDB配的路由器進程.它路由所有的要求,然后將結果聚合.它本身其實不存儲數據或配置信息
但會緩存配置
服務器的信息.
c.配置
服務器
配置
服務器存儲了集群的配置信息:數據和片的對應關系.mongos不永久存房數據,所以需要個地方寄存分片的配置.
它會從配置
服務器獲得同步數據.
8.啟動
服務器
首先要啟動配置
服務器和mongos.配置
服務器需要先啟動.由于mongos會用到其上的配置信息.
配置
服務器的啟動就像普通的mongod1樣
mongod --dbpath "F:mongodbsconfig" --port 20000 --logpath "F:mongologsconfigMongoDB.txt" --rest
配置
服務器不需要很多的空間和資源(200M實際數據大約占用1kB的配置空間)
建立mongos進程,1共利用程序連接.這類路由
服務器連接數據目錄都不需要,但1定要指明配置
服務器的位置:
mongos --port 30000 --configdb 127.0.0.1:20000 --logpath "F:mongologsmongosMongoDB.txt"
分片管理通常是通過mongos完成的.
添加片
片就是普通的mongod實例(或副本集)
mongod --dbpath "F:mongodbsshard" --port 10000 --logpath "F:mongologsshardMongoDB.txt" --rest
mongod --dbpath "F:mongodbsshard1" --port 10001 --logpath "F:mongologsshard1MongoDB.txt" --rest
連接剛才啟動的mongos,為集群添加1個片.啟動shell,連接mongos:
肯定連接的是mongos而不是mongod,通過addshard命令添加片:
>mongo 127.0.0.1:30000
mongos> db.runCommand(
... {
... "addshard":"127.0.0.1:10000",
... "allowLocal":true
... }
... )
Sat Jul 21 10:46:38 uncaught exception: error { "$err" : "can't find a shard to
put new db on", "code" : 10185 }
mongos> use admin
switched to db admin
mongos> db.runCommand(
... {
... "addshard":"127.0.0.1:10000",
... "allowLocal":1
... }
... )
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> db.runCommand(
... {
... "addshard":"127.0.0.1:10001",
... "allowLocal":1
... }
... )
{ "shardAdded" : "shard0001", "ok" : 1 }
當在本機運行片的時候,得設定allowLocal鍵為1.MongoDB盡可能避免由于毛病的配置,將集群配置到本地,
所以得讓它知道這僅僅是開發,而且我們很清楚自己在做甚么.如果是生產環境中,則要將其部署在不同的機器上.
想添加片的時候,就運行addshard.MongoDB會負責將片集成到集群.
切分數據 --- 繼續在mongos連接上操作
MongoDB不會將存儲的每條數據都直接發布,得先在
數據庫和集合的級別將分片功能打開.
E:mongoin>db.runCommand({"enablesharding":"test"})//將test
數據庫啟用分片功能.
對
數據庫分片后,其內部的集合便會存儲到不同的片上,同時也是對這些集合分片的前置條件.
在
數據庫級別啟用了分片以后,就能夠使用shardcollection命令堆積和進行分片:
db.runCommand({"shardcollection":"test.refactor","key":{"name":1}})//對test
數據庫的refactor集合進行分片,片鍵是name
如果現在對refactor集合添加數據,就會根據"name"的值自動分散到各個片上.
3.操作示例:
1.啟動配置服務器
D:mongodbmongo1in>mongod --dbpath=D:mongodbmongo1config --port 20000 --logpath=D:mongodbmongo1logsconfigMongoDB.txt --rest

2.
MongoDB配置的路由器進程服務器 -- 分片管理通常是通過mongos完成的.
D:mongodbmongo1in>mongos --port 3000 --configdb 127.0.0.1:20000 --logpath=D:mongodbmongo1logsmongosMongoDB.txt

3.建立分片,即普通的mongod實例
分片1:
D:mongodbmongo1in>mongod --port 10000 --dbpath=D:mongodbmongo1db1 --logpath=D:mongodbmongo1
logsshardMongoDB.txt --rest
分片2:
D:mongodbmongo1in>mongod --port 10001 --dbpath=D:mongodbmongo1db2 --logpath=D:mongodbmongo1
logsshard1MongoDB.txt --rest
4.
連接剛才啟動的mongos,為集群添加1個片.啟動shell,連接mongos:
D:mongodbmongo1in>mongos --port 3000 --configdb 127.0.0.1:20000 --logpath=D:mongodbmongo1logsmongosMongoDB.txt

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈