前言:
相信維護過有大數據的MySQL的運維人員一定對sharding這個非常了解,MySQL數據庫切分自身沒有工具需要借助第三方工具進行;MySQL切片是一件非常頭疼而又難做的一件事,一旦切分錯誤,不僅不能優化數據庫,反而會加劇數據庫負載;mongodb相對于MySQL來說,數據庫切分是mongodb與生俱來的功能,mongodb會自動切分數據庫;只需要執行切分鍵,mongodb就會自動切分,這大大減少了運維工作人員的工作量。
mongodb切分結構如圖所示:
Config Server節點:保存了所有數據庫的Collection,在實際生產中建議使用復制集
Router:路由節點,通過查找Config Server,將數據存儲到指定的Shard節點,建議在生產環境中使用keepalived或heartbeat等高可用方案
Shard:存儲節點,實際存儲數據的節點;在實際生產中建議每個shard做一個復制集
mongodb切分類型:
詳細信息請查官網地址:http://docs.mongodb.org/manual/core/sharding-introduction/
(1)基于范圍切分:range
(2)基于列表切分:list
(3)基于hash切分:hash
實驗環境:
(1)確保所使用主機iptables已經SELinux都以關閉
(2)本次實驗中mongodb的各個節點角色如下:
node1: 172.16.2.12 mongodb的shard節點
node2:172.16.2.13 mongodb的shard節點
node3:172.16.2.14 mongodb的config-server節點
node4: 172.16.2.15 mongodb的route節點
(3)確保各節點時間保持一致
二、配置過程:
[mongodb-org-2.6] \\準備yum源 name=MongoDB 2.6 Repository baseurl=http://downloads-distro.mongodb.org/repo/redhat/os/x86_64/ gpgcheck=0 enabled=1
(1)安裝配置config server節點
[root@node3 ~]# yum -y install mongodb-org-server mongodb-org-shell mongodb-org-tools
編輯mongodb配置文件:/etc/mongod.conf;修改信息如下
[root@node3 ~]# mkdir -pv /mongodb/data/;chown -R mongod.mongod /mongodb/ \\創建數據存放目錄 [root@node3 ~]# cat /etc/mongod.conf # mongod.conf #where to log logpath=/var/log/mongodb/mongod.log logappend=true # fork and run in background fork=true #port=27017 dbpath=/mongodb/data # location of pidfile pidfilepath=/var/run/mongodb/mongod.pid # Listen to local interface only. Comment out to listen on all interfaces. #bind_ip=127.0.0.1 # Disables write-ahead journaling # nojournal=true # Enables periodic logging of CPU utilization and I/O wait #cpu=true # Turn on/off security. Off is currently the default #noauth=true #auth=true # Verbose logging output. #verbose=true # Inspect all client data for validity on receipt (useful for # developing drivers) #objcheck=true # Enable db quota management #quota=true # Set oplogging level where n is # 0=off (default) # 1=W # 2=R # 3=both # 7=W+some reads #diaglog=0 # Ignore query hints #nohints=true # Enable the HTTP interface (Defaults to port 28017). #httpinterface=true #rest=true # Turns off server-side scripting. This will result in greatly limited # functionality #noscripting=true # Turns off table scans. Any query that would do a table scan fails. #notablescan=true # Disable data file preallocation. #noprealloc=true # Specify .ns file size for new databases. # nssize=<size> # Replication Options # in replicated mongo databases, specify the replica set name here #replSet=one #replIndexPrefetch=_id_only # maximum size in megabytes for replication operation log #oplogSize=1024 # path to a key file storing authentication info for connections # between replica set members #keyFile=/path/to/keyfile configsvr=true \\添加此選項,開啟此主機的mongodb中的server config角色
[root@node3 ~]# /etc/init.d/mongod start \\啟動mongodb的server config節點 Starting mongod: [ OK ]
[root@node3 ~]# netstat -tpln | grep mongod \\查看監聽端口,會發現有原來的TCP/27017更改為TCP/28019 tcp 0 0 0.0.0.0:27019 0.0.0.0:* LISTEN 29526/mongod
(2)配置router節點
[root@node4 ~]# yum -y install mongodb-org-mongos \\只需要安裝這一個軟件包即可
[root@node4 ~]# mkdir -pv /var/log/mongos/;touch /var/log/mongos/mongos.log \\創建mongos的日志存放位置 [root@node4 ~]# mongos --configdb=172.16.2.14:27019 --logpath=/var/log/mongos/mongos.log --fork 2015-08-22T21:03:08.106+0800 warning: running with 1 config server should be done only for testing purposes and is not recommended for production about to fork child process, waiting until server is ready for connections. forked process: 12939 \\進程pid child process started successfully, parent exiting 參數解釋: --configdb:指定mongodb的config server地址 --logpath: 指定日志文件路徑 --fork:指定在后端運行 常用參數請查看mongos -h
(3)配置shard節點
[root@node1 ~]# yum -y install mongodb-org-server mongodb-org-shell mongodb-org-tools \\node2節點安裝方法相同
編輯mongodb的配置文件:/etc/mongod.conf;修改如下
[root@node1 ~]# mkdir -pv /mongodb/data/;chown -R mongod.mongod /mongodb/ \\創建數據存放目錄;node2節點同樣需要創建 [root@node1 ~]# cat /etc/mongod.conf # mongod.conf #where to log logpath=/var/log/mongodb/mongod.log logappend=true # fork and run in background fork=true #port=27017 dbpath=/mongodb/data # location of pidfile pidfilepath=/var/run/mongodb/mongod.pid # Listen to local interface only. Comment out to listen on all interfaces. #bind_ip=127.0.0.1 # Disables write-ahead journaling # nojournal=true # Enables periodic logging of CPU utilization and I/O wait #cpu=true # Turn on/off security. Off is currently the default #noauth=true #auth=true # Verbose logging output. #verbose=true # Inspect all client data for validity on receipt (useful for # developing drivers) #objcheck=true # Enable db quota management #quota=true # Set oplogging level where n is # 0=off (default) # 1=W # 2=R # 3=both # 7=W+some reads #diaglog=0 # Ignore query hints #nohints=true # Enable the HTTP interface (Defaults to port 28017). #httpinterface=true #rest=true # Turns off server-side scripting. This will result in greatly limited # functionality #noscripting=true # Turns off table scans. Any query that would do a table scan fails. #notablescan=true # Disable data file preallocation. #noprealloc=true # Specify .ns file size for new databases. # nssize=<size> # Replication Options # in replicated mongo databases, specify the replica set name here #replSet=one #replIndexPrefetch=_id_only # maximum size in megabytes for replication operation log #oplogSize=1024 # path to a key file storing authentication info for connections # between replica set members #keyFile=/path/to/keyfile
[root@node1 ~]# scp /etc/mongod.conf node2:/etc/ \\把配置文件復制給node2節點一份
[root@node1 ~]# /etc/init.d/mongod start \\啟動node1節點 Starting mongod: [ OK ] [root@node2 ~]# /etc/init.d/mongod start \\啟動node2節點 Starting mongod: [ OK ]
[root@node1 ~]# netstat -tpln | grep mongod ;ssh node2 'netstat -tpln | grep mongod' \\查看監聽端口,shard節點的監聽端口為tcp/27017 tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 27619/mongod tcp 0 0 0.0.0.0:27017 0.0.0.0:* LISTEN 2468/mongod
(4)在shard節點連接router節點,測試切分環境是否搭建成功
[root@node1 ~]# mongo 172.16.2.15 MongoDB shell version: 2.6.11 connecting to: 172.16.2.15/test mongos>
(5)基礎環境已經搭建完成,接下來進行sharding具體操作
mongos> sh.addShard("172.16.2.12") \\添加node1節點到mongos(router節點) { "shardAdded" : "shard0000", "ok" : 1 } mongos> sh.addShard("172.16.2.13") \\添加node2節點到mongos(router節點) { "shardAdded" : "shard0001", "ok" : 1 }
mongos> sh.enableSharding("stu") \\指明要切分的數據庫,此數據可以不存在,事后創建即可 { "ok" : 1 } mongos> sh.shardCollection("stu.net12", {name: 1}) \\指明要切分的collection,并且指定以那個字段作為切分字段 { "collectionsharded" : "stu.net12", "ok" : 1 } \\這里指明的collection是”net12",指定時要寫完整的名稱,"dbname.collection_name";以name字段進行切分
mongos> sh.status() \\sharding配置完成,查看各個節點信息 --- Sharding Status --- sharding version: { "_id" : 1, \\表示符 "version" : 4, \\sharding版本 "minCompatibleVersion" : 4, "currentVersion" : 5, 當前版本 "clusterId" : ObjectId("55d872a44a05a590332d1d91")\\集群節點id } shards: \\各個shard節點信息 { "_id" : "shard0000", "host" : "172.16.2.12:27017" } { "_id" : "shard0001", "host" : "172.16.2.13:27017" } databases: \\數據庫信息 { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : false, "primary" : "shard0000" } { "_id" : "stu", "partitioned" : true, "primary" : "shard0000" } \\此處顯示"stu"數據庫可以sharding,主庫為shard000即為node1節點 stu.net12 shard key: { "name" : 1 } chunks: shard0000 1 { "name" : { "$minKey" : 1 } } -->> { "name" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 0)
(6)在mognos中往stu數據庫中插入大量數據,查看切分結果
mongos> for(i=1;i<=1000000;i++) db.net12.insert({name: "stu"+i, class: "Network Class", comment: " \\插入數據
mongos> sh.status() \\插入完成后查看各節點信息 --- Sharding Status --- sharding version: { "_id" : 1, "version" : 4, "minCompatibleVersion" : 4, "currentVersion" : 5, "clusterId" : ObjectId("55d872a44a05a590332d1d91") } shards: { "_id" : "shard0000", "host" : "172.16.2.12:27017" } { "_id" : "shard0001", "host" : "172.16.2.13:27017" } databases: { "_id" : "admin", "partitioned" : false, "primary" : "config" } { "_id" : "test", "partitioned" : false, "primary" : "shard0000" } { "_id" : "stu", "partitioned" : true, "primary" : "shard0000" } stu.net12 shard key: { "name" : 1 } chunks: shard0001 2 \\每個shard節點都各自有兩個chunk shard0000 2 { "name" : { "$minKey" : 1 } } -->> { "name" : "stu1" } on : shard0001 Timestamp(2, 0) { "name" : "stu1" } -->> { "name" : "stu25846" } on : shard0000 Timestamp(3, 2) { "name" : "stu25846" } -->> { "name" : "stu999" } on : shard0000 Timestamp(3, 3) { "name" : "stu999" } -->> { "name" : { "$maxKey" : 1 } } on : shard0001 Timestamp(3, 0)
至此實驗完成,對mongodb接觸不多,還請大家多多給意見。O(∩_∩)O
原創文章,作者:馬行空,如若轉載,請注明出處:http://www.www58058.com/7812
剛好馬內利也有這塊的疑問,剛巧共同探討下 :cool: