7.3.6 開啓認證
#sed -i “s/#keyFile/keyFile/”/opt/mongodb/security/*.conf
重啓mongod,mongios服務:
l Server1 :
# pkill mongod
# pkill mongios
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard10001.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard20001.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard30001.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/config1.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/mongos1.conf
#/opt/mongodb/bin/mongos -f /opt/mongodb/security/mongos1.conf
l Server2:
# pkill mongod
# pkill mongios
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard10002.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard20002.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard30002.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/config2.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/mongos2.conf
#/opt/mongodb/bin/mongos -f /opt/mongodb/security/mongos2.conf
l Server3 :
# pkill mongod
# pkill mongios
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard10003.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard20003.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/shard30003.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/config3.conf
#/opt/mongodb/bin/mongod -f /opt/mongodb/security/mongos3.conf
#/opt/mongodb/bin/mongos -f /opt/mongodb/security/mongos3.conf
7.3.7測試分片實例:
root@debian:~# /opt/mongodb/bin/mongo 10.15.62.202:30000/admin
MongoDB shell version: 2.4.6
connecting to: 10.15.62.202:30000/admin
> db.auth("clusterAdmin","pwd")
1
mongos> show collections
system.indexes
system.users
mongos> use test
switched to db test
mongos> show collections
#對test數據庫新建用戶:
mongos> db.addUser({user:"test",pwd:"123456",roles:["readWrite","dbAdmin"]})
{
"user" : "test",
"pwd" : "c8ef9e7ab00406e84cfa807ec082f59e",
"roles" : [
"readWrite",
"dbAdmin"
],
"_id" : ObjectId("5241e3ffdaf821e8d4c5b9e7")
}
mongos>
mongos> show collections
system.indexes
System.users
#查看users集合中的內容:
mongos> db.system.users.find()
{ "_id" : ObjectId("5241e3ffdaf821e8d4c5b9e7"), "user" : "test", "pwd" : "c8ef9e7ab00406e84cfa807ec082f59e", "roles" : [ "readWrite", "dbAdmin" ] }
mongos> db
test
mongos> use admin
switched to db admin
#對數據庫分片,test代表要分片的數據庫
mongos> db.runCommand({enablesharding:"test"})
{ "ok" : 1 }
# 對集合分片,在test數據庫的users表上分片,同時指明shard key是id這一列
mongos> db.runCommand({shardcollection:"test.users",key:{_id:1}})
{ "collectionsharded" : "test.users", "ok" : 1 }
mongos> db
admin
mongos> use test
switched to db test
mongos> show collections
system.indexes
system.profile
system.users
Users
#循環向test.users表中插入30萬條數據,然後使用命令db.users.stats()查看錶的分片情況.
mongos> for(var i=1;i<300000;i++) db.users.insert({name:"user"+i,age:i,email:"[email protected]"})
mongos> show collections
system.indexes
system.profile
system.users
Users
#查看結果集
mongos> db.users.find()
{ "_id" : ObjectId("5241e618daf821e8d4c707a5"), "name" : "user85438", "age" : 85438, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45a"), "name" : "user6771", "age" : 6771, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9e8"), "name" : "user1", "age" : 1, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707a6"), "name" : "user85439", "age" : 85439, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45b"), "name" : "user6772", "age" : 6772, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9e9"), "name" : "user2", "age" : 2, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707a7"), "name" : "user85440", "age" : 85440, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45c"), "name" : "user6773", "age" : 6773, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9ea"), "name" : "user3", "age" : 3, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707a8"), "name" : "user85441", "age" : 85441, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45d"), "name" : "user6774", "age" : 6774, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9eb"), "name" : "user4", "age" : 4, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707a9"), "name" : "user85442", "age" : 85442, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45e"), "name" : "user6775", "age" : 6775, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9ec"), "name" : "user5", "age" : 5, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707aa"), "name" : "user85443", "age" : 85443, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d45f"), "name" : "user6776", "age" : 6776, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e5ffdaf821e8d4c5b9ed"), "name" : "user6", "age" : 6, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e618daf821e8d4c707ab"), "name" : "user85444", "age" : 85444, "email" : "[email protected]" }
{ "_id" : ObjectId("5241e600daf821e8d4c5d460"), "name" : "user6777", "age" : 6777, "email" : "[email protected]" }
Type "it" for more
mongos> db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 299999,
"numExtents" : 20,
"size" : 26399928,
"storageSize" : 60162048,
"totalIndexSize" : 10808672,
"indexSizes" : {
"_id_" : 10808672
},
"avgObjSize" : 88.00005333351112,
"nindexes" : 1,
"nchunks" : 14,
"shards" : {
"shard1" : {
"ns" : "test.users",
"count" : 60185,
"size" : 5296288,
"avgObjSize" : 88.00013292348592,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 2984240,
"indexSizes" : {
"_id_" : 2984240
},
"ok" : 1
},
"shard2" : {
"ns" : "test.users",
"count" : 200481,
"size" : 17642328,
"avgObjSize" : 88,
"storageSize" : 37797888,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 15290368,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 6540800,
"indexSizes" : {
"_id_" : 6540800
},
"ok" : 1
},
"shard3" : {
"ns" : "test.users",
"count" : 39333,
"size" : 3461312,
"avgObjSize" : 88.00020339155417,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 1283632,
"indexSizes" : {
"_id_" : 1283632
},
"ok" : 1
}
},
"ok" : 1
}
mongos>
7.4增加移除sharding節點
7.4.1 增加sharding節點:
1 查看當前分分片信息:
可以看到:存在3個切片,每個切片中存在3個節點
2 刪除運行中的節點:
這裏操作切片爲:shard1 中的節點:
shard1:PRIMARY> rs.remove("10.15.62.203:10001")
Fri Sep 27 09:20:30.768 DBClientCursor::init call() failed
Fri Sep 27 09:20:30.770 Error: error doing query: failed at src/mongo/shell/query.js:78
Fri Sep 27 09:20:30.772 trying reconnect to 127.0.0.1:10001
Fri Sep 27 09:20:30.775 reconnect 127.0.0.1:10001 ok
shard1:PRIMARY>
3 查看日誌:
Fri Sep 27 09:20:35.784 [conn6] SocketException handling request, closing client connection: 9001 socket exception [SEND_ERROR] server [10.15.62.203:24188]
Fri Sep 27 09:20:35.785 [conn29] SocketException handling request, closing client connection: 9001 socket exception [SEND_ERROR] server [10.15.62.205:3114]
4 再次查看當前分片信息驗證:
發現節點 10.15.62.203:10001 已經被移除
5 關閉10.15.62.203:10001 上的mongod進程即可
7.4.2 增加節點:
這裏已剛纔剛纔刪除的節點10.15.62.203:10001爲例
1 啓動新增的節點的mongo進程
2 將新增的節點加入到切片中:
當前切片的節點信息:
3 增加節點操作:
shard1:PRIMARY> rs.add("10.15.62.203:10001")
{ "down" : [ "10.15.62.203:10001" ], "ok" : 1 }
shard1:PRIMARY>
4 查看後臺日誌:
可以看到已經添加到切片中了
5 查看切片狀態
6 查看所有切片信息:
7.5增加移除切片rep-set:
目前40w條數據存儲在shard1,shard2,shard3上,考慮到數據分散不均勻,移除rep-set需要就行數據轉移,這裏選擇數據較少的shard3:
1 查看test.user集合中的數據狀態:
mongos> db.users.stats();
{
"sharded" : true,
"ns" : "test.users",
"count" : 399998,
"numExtents" : 20,
"size" : 35141840,
"storageSize" : 60162048,
"totalIndexSize" : 14406112,
"indexSizes" : {
"_id_" : 14406112
},
"avgObjSize" : 87.85503927519638,
"nindexes" : 1,
"nchunks" : 17,
"shards" : {
"shard1" : {
"ns" : "test.users",
"count" : 73297,
"size" : 6450144,
"avgObjSize" : 88.00010914498547,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 3752784,
"indexSizes" : {
"_id_" : 3752784
},
"ok" : 1
},
"shard2" : {
"ns" : "test.users",
"count" : 274257,
"size" : 24076616,
"avgObjSize" : 87.78851952730469,
"storageSize" : 37797888,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 15290368,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 8944544,
"indexSizes" : {
"_id_" : 8944544
},
"ok" : 1
},
"shard3" : {
"ns" : "test.users",
"count" : 52444,
"size" : 4615080,
"avgObjSize" : 88.00015254366562,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 1708784,
"indexSizes" : {
"_id_" : 1708784
},
"ok" : 1
}
},
"ok" : 1
}
2 執行移除操作:
mongos> db.runCommand({"removeshard":"shard3"});
{
"msg" : "removeshard completed successfully",
"state" : "started",
"shard" : "shard3",
"ok" : 1
}
3 查看遷移狀態:
我們可以反覆執行上面語句,查看執行結果。
mongos> db.runCommand({"removeshard":"shard3"});
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(5),
"dbs" : NumberLong(0)
},
"ok" : 1
}
從上面可以看到,正在遷移,還剩下5塊沒遷移完。
當remain爲0之後,這一步就結束了。
mongos> db.runCommand({"removeshard":"shard3"});
{
"msg" : "draining ongoing",
"state" : "ongoing",
"remaining" : {
"chunks" : NumberLong(2),
"dbs" : NumberLong(0)
},
"ok" : 1
}
mongos> db.runCommand({"removeshard":"shard3"});
{
"msg" : "removeshard completed successfully",
"state" : "completed",
"shard" : "shard3",
"ok" : 1
}
4 查看所有的sharding:
Shard3 已經不在了
5 查看數據是否被切換到另外2個sharding上:
mongos> db.users.stats()
{
"sharded" : true,
"ns" : "test.users",
"count" : 399998,
"numExtents" : 20,
"size" : 35141832,
"storageSize" : 60162048,
"totalIndexSize" : 15738800,
"indexSizes" : {
"_id_" : 15738800
},
"avgObjSize" : 87.85501927509638,
"nindexes" : 1,
"nchunks" : 17,
"shards" : {
"shard1" : {
"ns" : "test.users",
"count" : 99519,
"size" : 8757680,
"avgObjSize" : 88.00008038665983,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 5257168,
"indexSizes" : {
"_id_" : 5257168
},
"ok" : 1
},
"shard2" : {
"ns" : "test.users",
"count" : 300479,
"size" : 26384152,
"avgObjSize" : 87.806974863468,
"storageSize" : 37797888,
"numExtents" : 8,
"nindexes" : 1,
"lastExtentSize" : 15290368,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 10473456,
"indexSizes" : {
"_id_" : 10473456
},
"ok" : 1
},
"shard3" : {
"ns" : "test.users",
"count" : 0,
"size" : 0,
"storageSize" : 11182080,
"numExtents" : 6,
"nindexes" : 1,
"lastExtentSize" : 8388608,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 0,
"totalIndexSize" : 8176,
"indexSizes" : {
"_id_" : 8176
},
"ok" : 1
}
},
"ok" : 1
}
mongos>
6 關閉對應的mongod進程
7 注意:
① 在操作之前確保三臺服務器同步時間一致,剛開始操作的時候沒注意到這個問題,造成在刪除切片的時候一直卡着不動,後臺日誌顯示:
caught exception while doing balance: error checking clock skew of cluster 10.15.62.202:20
000,10.15.62.203:20000,10.15.62.205:20000 :: caused by :: 13650 clock skew of the cluster 10.15.62.202:20000,10.15.62.203:200
00,10.15.62.205:20000 is too far out of bounds to allow distributed locking.
② 如果該sharding中存在非切片數據,需要先將非sharding數據移除:
db.runCommand( { movePrimary: "非切片數據", to: "sharding" })至於非切片數據在進行移除切片數據的時候會報錯,看報錯信息就可以知道了
③ 增加sharding同上面一致
7.6 Replica Set 節點切換和 failover
MongoDB的sharding屬性增加了數據的安全性和可靠性,而rep-set增加的則是數據的可用性,水平擴展了數據庫的性能,replica set 特性支持自動 failover,當主節點由於某種原因掉線時,replica set 的其它節點可通過競選產生新的主節點,因爲同一個切片中sharding節點之間存在的數據都是一樣的,默認情況下主節點primary具有可讀寫屬性,secondary沒有讀寫權限,當primary斷掉後會進行重新選舉出primary接管該sharding,至於如何重新選舉,如何控制選舉時間可以作爲mongo性能優化的一個在後續說明,後面的mongodb維護文檔中做過這方面的測試,這裏就不特別指出了。
7.7關於sharding的幾點說明:
① 關於keyfile和auth參數的問題
keyfile包含了auth參數,而且優先級更高,只有你設定了keyfile,auth參數被忽略,也就是開啓了用戶認證
② 對於shard和config實例,沒添加用戶前可以本地無驗證登錄,一旦添加用戶,認證即可生效,連當前的session都會失效,需要從新登錄
對於mongos實例由於它的一切信息來自config實例,必須要通過用戶認證
③ 注意:keyfile參數必須子所有實例中指定,而且必須是同一個key
④ admin數據庫的問題
admin是一個特殊的數據庫,它不在整個sharding中複製
shard實例中的admin數據庫是本地的,當然在同一個replica set是一樣的,它僅限於登錄shard實例
config實例中的admin同時給config實例和mongos實例用於實例認證
在mongos中添加的用戶會同步到所有的config實例中
在config中添加的用戶不會同步到其它config實例中,因爲它不知道其它實例的存在