MongoDB非關系型資料庫
MongoDB是有C++語言編寫的,是一個基于分布式檔案存儲的開源資料庫系統,屬于NoSQL。在高負載的情況下,可以添加更多的節點,可以保證伺服器的性能。
MongoDB旨在為WEB應用提供可擴充的高性能資料存儲解決方案。
MongoDB将資料存儲為一個文檔,資料結構由鍵值(key-->value)對組成。MongoDB文檔類似于JSON對象,字段值可以包含其他文檔,數組及文檔數組。
MongoDB和關系型資料庫對比
SQL術語概念 | MongoDB術語概念 | 解釋/說明 |
database | 資料庫 | |
table | collection | 資料庫表/集合 |
row | document | 資料記錄/文檔 |
column | field | 資料字段/域 |
index | 索引 | |
table joins | 表連接配接,MongoDB不支援 | |
primary key | 主鍵,MongoDB自動将_id字段設定為主鍵 |
MongoDB安裝
- 搭建yum源
# vim /etc/yum.repos.d/mongodb-org-3.0.repo
[mongodb-org-3.0]
name=MongoDB Repository
baseurl=http://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.0/x86_64/
gpgcheck=0
enabled=1
1、安裝mongodb-org
# yum install mongodb-org
Dependencies Resolved
=======================================================================================
Package Arch Version Repository Size
=======================================================================================
Installing:
mongodb-org x86_64 3.0.11-1.el6 mongodb-org-3.0 5.8 k
Installing for dependencies:
mongodb-org-mongos x86_64 3.0.11-1.el6 mongodb-org-3.0 4.7 M
mongodb-org-server x86_64 3.0.11-1.el6 mongodb-org-3.0 9.8 M
mongodb-org-shell x86_64 3.0.11-1.el6 mongodb-org-3.0 5.0 M
mongodb-org-tools x86_64 3.0.11-1.el6 mongodb-org-3.0 34 M
Transaction Summary
=======================================================================================
Install 5 Package(s)
Total download size: 53 M
Installed size: 166 M
Is this ok [y/N]: y
/etc/init.d/mongod /etc/mongod.conf /var/lib/mongo/
/etc/mongod.conf配置檔案
processManagement:
fork: true
pidFilePath: /var/run/mongodb/mongod.pid
# network interfaces
net:
port: 27017
bindIp:
啟動mongodb
# /etc/init.d/mongod start
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
vim /etc/security/limits.conf //加入
mongodb soft nofile 64000
mongodb hard nofile 64000
mongodb soft nproc 32000
mongodb hard nproc 32000
啟動:mongodb
啟動過程會比較慢,這是它在寫資料/var/lib/mongodb
[root@3f63e6ba4d83 ~]# du -sh /var/lib/mongo/
81M/var/lib/mongo/
使用mongod -f /etc/mongod.conf啟動方式
[root@3f63e6ba4d83 ~]# /etc/init.d/mongod stop
[root@3f63e6ba4d83 ~]# kill -9 mongodb_pid
[root@3f63e6ba4d83 ~]# ps -ef
root@3f63e6ba4d83 ~]# mongod -f /etc/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 510
child process started successfully, parent exiting
[root@3f63e6ba4d83 ~]# ps -ef |grep mongo
mongod 546 1 1 00:59 ? 00:00:04 /usr/bin/mongod -f /etc/mongod.conf
[root@3f63e6ba4d83 ~]# netstat -nlp | grep mongo
unix 2 [ ACC ] STREAM LISTENING 99391 - /tmp/mongodb-27017.sock
連接配接mongodb
1、在本機可以直接運作指令mongo進入到mongodb shell中
2、如果mongodb監聽的端口并不是預設的27017,則在連接配接的時候加上--port選項,如:
mongo --port 27018
3、遠端連接配接mongodb,需要加--host,如:mongo --host 127.0.0.1
4、如果設定了驗證,則在連接配接的時候加使用者名和密碼mongo -uusername -ppasswd
mongodb使用者管理
- 首先mongodb使用者是針對庫來的,建立使用者時要先進入傲對應的庫裡
- use test #切換到test庫下
- db.createUser({user:"admin",pwd:"123456",roles:[{role:'dbOwner',db:'userdb'}]})
- use admin #切換到admin庫
- db.system.users.find() #列出所有使用者,需要切換到admin庫
- show users #檢視目前庫下的所有使用者
- db.dorpUser('admin') #删除使用者
- 關于使用者角色,參考文檔http://bbs.51cto.com/thread-1146654-1.html
> use test
switched to db test
> db.createUser({user:"admin",pwd:"123456",roles:[{role:'dbOwner',db:'userdb'}]})
Successfully added user: {
"user" : "admin",
"roles" : [
{
"role" : "dbOwner",
"db" : "userdb"
}
]
}
>
列出所有使用者
> use admin
switched to db admin
> db.system.users.find()
{ "_id" : "test.admin", "user" : "admin", "db" : "test", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "pMWz7+kTk9/cs/L4BHHT9Q==", "storedKey" : "Hhq0U71m7WhJlg7+s36fTWHl3x0=", "serverKey" : "9lPAV69Kgn3s4GHpQ4qMsFd/7KY=" } }, "roles" : [ { "role" : "dbOwner", "db" : "userdb" } ] }
删除使用者,需要切換到對應的庫
> use test
switched to db test
> show users;
{
"_id" : "test.admin",
"user" : "admin",
"db" : "test",
"roles" : [
{
"role" : "dbOwner",
"db" : "userdb"
}
]
}
> show users;
>
MongoDB庫和集合管理
檢視版本
> db.version()
3.0.11
檢視資料庫
> show dbs
admin 0.078GB
local 0.078GB
建立庫
switched to db userdb
> show dbs
admin 0.078GB
local 0.078GB
> db.createCollection('name')
{ "ok" : 1 }
> show dbs
admin 0.078GB
local 0.078GB
userdb 0.078GB
删除庫
> db.dropDatabase()
{ "dropped" : "userdb", "ok" : 1 }
檢視狀态
> db.stats()
{
"db" : "admin",
"collections" : 5,
"objects" : 13,
"avgObjSize" : 67.6923076923077,
"dataSize" : 880,
"storageSize" : 36864,
"numExtents" : 5,
"indexes" : 4,
"indexSize" : 32704,
"fileSize" : 67108864,
"nsSizeMB" : 16,
"extentFreeList" : {
"num" : 0,
"totalSize" : 0
},
"dataFileVersion" : {
"major" : 4,
"minor" : 22
},
"ok" : 1
}
>
MongoDB建立集合
-
db.createCollection("mycol",{capped:true,autoindexID:true,size:6142800,max:10000})
#文法:db.createCollection(name,options)
- name就是集合的名字,options可選,用來配置集合的參數,參數如下:
- capped true/false(可選)如果為true,則啟用封頂集合。封頂集合是固定大小的集合,當它達到其最大大小,會自動覆寫最早的條目。如果指定true,則也需要指定尺寸參數
- autoindexID true/false(可選)如果為true,自動建立索引_id字段的預設值是false
- size(可選),指定最大大小位元組封頂集合。如果封頂是true,那麼還需要指定這個字段。機關B
- max(可選),指定封頂集合允許在檔案的最大數量
1、
> use mydb
switched to db mydb
> db.createCollection("mycol",{capped:true,autoindexID:true,size:6142800,max:10000})
{ "ok" : 1 }
MongoDB資料管理
- show collections #檢視集合,或者使用show tables
- db.Account.insert({AccoutID:1,UserName:"123",password:"123456"})
#如果集合不存在,直接插入資料,則mongodb會自動建立集合db.Account.update({AccountID:1},{"$set":{"Age":20}}) #更新db.Account.find() #檢視所有文檔db.Account.find({AccountID:1}) #根據條件查詢db.Account.remove({AccountID:1}) #根據條件删除db.Account.drop() #删除所有文檔,即删除集合use dbname #先進入對應的庫db.printCollectionStats() #然後檢視集合狀态
MongoDB副本集搭建
實驗準備:三台機器
dnode1:172.17.0.2(primary)
dnode2:172.17.0.3(secondary)
dnode3:172.17.0.4(secondary)
編輯三台機器的配置檔案,增加:
replication:
##oplog大小
oplogSizeMB: 20
##複制集名稱
replSetName: vnode
分别重新開機三台機器
連接配接主,在主上運作指令mongo
> use admin
> config={_id:"vnode",members:[{_id:0,host:"172.17.0.2:27017"},{_id:1,host:"172.17.0.3:27017"},{_id:2,host:"172.17.0.4:27017"}]}
> rs.initiate(config)
> rs.add("172.17.0.3") #手動添加
> rs.add("172.17.0.4")
> rs.status() #檢視狀态
如果兩個從上的狀态為stateStr:"STARTUP",則需要進行如下操作
> var
config={_id:"vnode",members:[{_id:0,host:"172.17.0.2:27017"},{_id:1,host:"172.17.0.3:27017"},{_id:2,host:"172.17.0.4:27017"}]}
> rs.reconfig(config)
此時再次檢視rs.status()會發現從的狀态變為SECONDARY
> use admin
switched to db admin
> config={_id:"vnode",members:[{_id:0,host:"172.17.0.2:27017"},{_id:1,host:"172.17.0.3:27017"},{_id:2,host:"172.17.0.4:27017"}]}
{
"_id" : "vnode",
"members" : [
{
"_id" : 0,
"host" : "172.17.0.2:27017"
},
{
"_id" : 1,
"host" : "172.17.0.3:27017"
},
{
"_id" : 2,
"host" : "172.17.0.4:27017"
}
]
}
> rs.initiate(config)
{ "ok" : 1 }
vnode:SECONDARY>
檢視叢集狀态:
de:SECONDARY> rs.status()
{
"set" : "vnode",
"date" : ISODate("2016-04-04T09:17:10.703Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.17.0.2:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 262,
"optime" : Timestamp(1459761332, 1),
"optimeDate" : ISODate("2016-04-04T09:15:32Z"),
"electionTime" : Timestamp(1459761334, 1),
"electionDate" : ISODate("2016-04-04T09:15:34Z"),
"configVersion" : 1,
"self" : true
},
{
"_id" : 1,
"name" : "172.17.0.3:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 97,
"optime" : Timestamp(1459761332, 1),
"optimeDate" : ISODate("2016-04-04T09:15:32Z"),
"lastHeartbeat" : ISODate("2016-04-04T09:17:08.859Z"),
"lastHeartbeatRecv" : ISODate("2016-04-04T09:17:08.859Z"),
"pingMs" : 0,
"configVersion" : 1
},
{
"_id" : 2,
"name" : "172.17.0.4:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 97,
"optime" : Timestamp(1459761332, 1),
"optimeDate" : ISODate("2016-04-04T09:15:32Z"),
"lastHeartbeat" : ISODate("2016-04-04T09:17:08.861Z"),
"lastHeartbeatRecv" : ISODate("2016-04-04T09:17:08.861Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "could not find member to sync from",
"configVersion" : 1
}
],
"ok" : 1
}
vnode:PRIMARY>
vnode:PRIMARY> rs.config()
{
"_id" : "vnode",
"version" : 1,
"members" : [
{
"_id" : 0,
"host" : "172.17.0.2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 1,
"host" : "172.17.0.3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 2,
"host" : "172.17.0.4:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatTimeoutSecs" : 10,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
}
}
}
vnode:PRIMARY>
檢視從上,變成了SECONDARY狀态
root@99caf161a55c ~]# mongo
MongoDB shell version: 3.0.11
connecting to: test
Welcome to the MongoDB shell.
vnode:SECONDARY>
[root@f3eaa845de59 ~]# mongo
MongoDB shell version: 3.0.11
connecting to: test
Welcome to the MongoDB shell.
vnode:SECONDARY>
MongoDB副本集測試
vnode:PRIMARY> use testdb
switched to db testdb
vnode:PRIMARY> show dbs
admin 0.078GB
local 0.078GB
mydb 0.078GB
vnode:PRIMARY> db.createCollection('test')
{ "ok" : 1 }
vnode:PRIMARY> show dbs
admin 0.078GB
local 0.078GB
mydb 0.078GB
testdb 0.078GB
在從上檢視
vnode:SECONDARY> rs.slaveOk()
vnode:SECONDARY> show dbs;
admin 0.078GB
local 0.078GB
mydb 0.078GB
testdb 0.078GB
vnode:SECONDARY> show tables
vnode:SECONDARY> use testdb
switched to db testdb
vnode:SECONDARY> show tables
system.indexes
test
MongoDB副本集更改權重模拟主當機
預設三台機器權重都為1,如果任何一個權重設定為比其他的高,則該台機器馬上切換為primary角色,是以我們預設三台叢集的權重分别為:
172.17.0.2:3
172.17.0.3:2
172.17.0.4:1
在主上執行:
cfg=rs.conf()
cfg.members[0].priority=3
cfg.members[1].priority=2
cfg.members[2].priority=1
rs.reconfig(cfg)
這樣的話,第二個節點将會成為候選主節點
主上執行:iptables -I INPUT -p tcp --dport 27017 -j DROP
vnode:PRIMARY> cfg=rs.conf()
vnode:PRIMARY> cfg.members[0].priority=3
3
vnode:PRIMARY> cfg.members[1].priority=2
2
vnode:PRIMARY> cfg.members[2].priority=1
1
vnode:PRIMARY> rs.reconfig(cfg)
{ "ok" : 1 }
檢視權重
vnode:PRIMARY> rs.config()
{
"_id" : "vnode",
"version" : 2,
"members" : [
{
"_id" : 0,
"host" : "172.17.0.2:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 1,
"host" : "172.17.0.3:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
},
{
"_id" : 2,
"host" : "172.17.0.4:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {
},
"slaveDelay" : 0,
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatTimeoutSecs" : 10,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
}
}
}
測試模拟主節點故障
[root@3f63e6ba4d83 ~]# /etc/init.d/mongod stop
Stopping mongod:
dnode2自動切換為主
vnode:SECONDARY>
vnode:PRIMARY>
檢視狀态:
vnode:PRIMARY> rs.status()
{
"set" : "vnode",
"date" : ISODate("2016-04-04T09:50:29.433Z"),
"myState" : 1,
"members" : [
{
"_id" : 0,
"name" : "172.17.0.2:27017",
"health" : 0,
"state" : 8,
"stateStr" : "(not reachable/healthy)",
"uptime" : 0,
"optime" : Timestamp(0, 0),
"optimeDate" : ISODate("1970-01-01T00:00:00Z"),
"lastHeartbeat" : ISODate("2016-04-04T09:50:27.462Z"),
"lastHeartbeatRecv" : ISODate("2016-04-04T09:46:14.237Z"),
"pingMs" : 0,
"lastHeartbeatMessage" : "Failed attempt to connect to 172.17.0.2:27017; couldn't connect to server 172.17.0.2:27017 (172.17.0.2), connection attempt failed",
"configVersion" : -1
},
{
"_id" : 1,
"name" : "172.17.0.3:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 2247,
"optime" : Timestamp(1459763046, 1),
"optimeDate" : ISODate("2016-04-04T09:44:06Z"),
"electionTime" : Timestamp(1459763179, 1),
"electionDate" : ISODate("2016-04-04T09:46:19Z"),
"configVersion" : 2,
"self" : true
},
{
"_id" : 2,
"name" : "172.17.0.4:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 2096,
"optime" : Timestamp(1459763046, 1),
"optimeDate" : ISODate("2016-04-04T09:44:06Z"),
"lastHeartbeat" : ISODate("2016-04-04T09:50:29.331Z"),
"lastHeartbeatRecv" : ISODate("2016-04-04T09:50:29.267Z"),
"pingMs" : 0,
"configVersion" : 2
}
],
"ok" : 1
}
vnode:PRIMARY>
MongoDB備份與恢複
mongodb的指令
root@99caf161a55c ~]# mongo
mongo mongodump mongofiles mongooplog mongorestore mongostat
mongod mongoexport mongoimport mongoperf mongos mongotop
備份
1、備份指定庫
- mongodump -h ip -d dbname -o dir
#-h後面跟伺服器ip,-d後面跟database名字,不加則備份所有庫,-o後指定備份到哪個目錄
2、備份所有庫
- mongodump -h ip -o dir
3、備份指定集合
- mongodump -d mydb -c testc -o /tmp/testc #-c指定集合名字
4、導出集合為json檔案
- mongoexport -d mydb -c testc -o /tmp/testc.json #-o後面跟的是一個檔案名
建立一個庫表,并插入資料
vnode:PRIMARY> use testdb
switched to db testdb
vnode:PRIMARY> show tables
system.indexes
test
vnode:PRIMARY> db.testc.find()
vnode:PRIMARY> db.testc.insert({id:1,name:"dime",age:20})
WriteResult({ "nInserted" : 1 })
vnode:PRIMARY> db.testc.find()
{ "_id" : ObjectId("57023d2df247977956fa195b"), "id" : 1, "name" : "dime", "age" : 20 }
vnode:PRIMARY>
vnode:PRIMARY> db.testc.insert({id:2,name:"hosx",age:21})
WriteResult({ "nInserted" : 1 })
vnode:PRIMARY> db.testc.find()
{ "_id" : ObjectId("57023d2df247977956fa195b"), "id" : 1, "name" : "dime", "age" : 20 }
{ "_id" : ObjectId("57023d75f247977956fa195c"), "id" : 2, "name" : "hosx", "age" : 21 }
vnode:PRIMARY>
備份testdb庫
[root@3f63e6ba4d83 ~]# mongodump -d testdb -o /root/mongodbbak
2016-04-04T06:10:53.652-0400 writing testdb.system.indexes to /root/mongodbbak/testdb/system.indexes.bson
2016-04-04T06:10:53.653-0400 writing testdb.testc to /root/mongodbbak/testdb/testc.bson
2016-04-04T06:10:53.654-0400 writing testdb.test to /root/mongodbbak/testdb/test.bson
2016-04-04T06:10:53.679-0400 writing testdb.test metadata to /root/mongodbbak/testdb/test.metadata.json
2016-04-04T06:10:53.680-0400 writing testdb.testc metadata to /root/mongodbbak/testdb/testc.metadata.json
2016-04-04T06:10:53.684-0400 done dumping testdb.test (0 documents)
2016-04-04T06:10:53.685-0400 done dumping testdb.testc (2 documents)
[root@3f63e6ba4d83 ~]# ls
mongodbbak nginx-1.8.1.tar.gz
[root@3f63e6ba4d83 ~]# ls mongodbbak/testdb/
system.indexes.bson test.bson testc.bson testc.metadata.json test.metadata.json
備份所有的庫
[root@3f63e6ba4d83 ~]# mongodump -o /root/mongodbbak2
備份一個表
[root@3f63e6ba4d83 ~]# mongoexport -d testdb -c test -o /root/testdb/test.json
[root@3f63e6ba4d83 ~]# ls testdb/
test.json
删除
vnode:PRIMARY> use testdb
switched to db testdb
vnode:PRIMARY> db.dropDatabase()
{ "dropped" : "testdb", "ok" : 1 }
恢複
[root@3f63e6ba4d83 ~]# mongorestore -d testdb /root/mongodbbak/testdb
vnode:PRIMARY> show dbs
admin 0.078GB
local 0.078GB
mydb 0.078GB
testdb 0.078GB
恢複所有
[root@3f63e6ba4d83 ~]# mongorestore /root/mongodbbak2/
[root@3f63e6ba4d83 ~]# mongorestore --dorp /root/mongodbbak2/ #--dorp完全覆寫
PHP連接配接MongoDB
1、安裝PHP的mongo擴充
2、測試mongo擴充
下載下傳mongo擴充
http://pecl.php.net/get/mongo-1.6.13.tgz
安裝
[root@3f63e6ba4d83 ~]# tar zxf mongo-1.6.13.tgz
[root@3f63e6ba4d83 ~]# cd mongo-1.6.13
[root@3f63e6ba4d83 mongo-1.6.13]# /usr/local/php/bin/phpize
Configuring for:
PHP Api Version: 20131106
Zend Module Api No: 20131226
Zend Extension Api No: 220131226
[root@3f63e6ba4d83 mongo-1.6.13]# ./configure --with-php-config=/usr/local/php/bin/php-config
[root@3f63e6ba4d83 mongo-1.6.13]# make
[root@3f63e6ba4d83 mongo-1.6.13]# make install
Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
[root@3f63e6ba4d83 mongo-1.6.13]# ls /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/
mongo.so opcache.a opcache.so
[root@3f63e6ba4d83 mongo-1.6.13]# cp /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/mongo.so /usr/local/php/ext/
ls /usr/local/php/ext/
mongo.so
[root@3f63e6ba4d83 html]# vim /usr/local/php/etc/php.ini
extension_dir = "/usr/local/php/ext"
extension = mongo.so
extension = opcache.so
[root@3f63e6ba4d83 html]# mkdir /usr/local/php/ext
檢視
[root@3f63e6ba4d83 mongo-1.6.13]# /usr/local/php/bin/php -m |grep mongo
mongo
[root@3f63e6ba4d83 ~]# /etc/init.d/php-fpm restart
Gracefully shutting down php-fpm . done
Starting php-fpm done
建立測試檔案
[root@3f63e6ba4d83 ~]# vim /usr/local/nginx/html/mongo.php
<?php
$m = new MongoClient();
echo "Connection to database successfully";
$db = $m->testdb;
echo "Database testdb selected";
?>
通路
[root@dime ~]# curl http://192.168.1.15:32770/mongo.php
Connection to database successfullyDatabase testdb selected