第三十六課預習任務
1.mongodb介紹
MongoDB是基於文件的儲存的(而非表),是一個介於關係資料庫和非關係資料庫之間的產品,是非關係資料庫當中功能最豐富,最像關係資料庫的。他支援的資料結構非常鬆散,是類似json的bjson格式,因此可以儲存比較複雜的資料型別。模式自由(schema-free),意味著對於儲存在MongoDB資料庫中的檔案,我們不需要知道它的任何結構定義。如果需要的話,你完全可以把不同結構的檔案儲存在同一個資料庫裡。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於面向物件的查詢語言,幾乎可以實現類似關係資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引。
Mongo主要解決的是海量資料的訪問效率問題。因為Mongo主要是支援海量資料儲存的,所以Mongo還自帶了一個出色的分散式檔案系統GridFS,可以支援海量的資料儲存。由於Mongo可以支援複雜的資料結構,而且帶有強大的資料查詢功能,因此非常受到歡迎。
1.2、適用場景
1、網站資料:適合實時的插入,更新與查詢,並具備網站實時資料儲存所需的複製及高度伸縮性。
2、快取:由於效能很高,也適合作為資訊基礎設施的快取層。在系統重啟之後,搭建的持久化快取可以避免下層的資料來源過載。
3、大尺寸、低價值的資料:使用傳統的關係資料庫儲存一些資料時可能會比較貴,在此之前,很多程式設計師往往會選擇傳統的檔案進行儲存。
4、高伸縮性的場景:非常適合由數十或者數百臺伺服器組成的資料庫。
5、用於物件及JSON資料的儲存:MongoDB的BSON資料格式非常適合文件格式化的儲存及查詢。
1.3 MongoDB和關係型資料庫對比
2.mongodb安裝
epel自帶的mongodb版本為2.6,我們需要安裝3.4版本
[[email protected] ~]# cd /etc/yum.repos.d/
[ [email protected] yum.repos.d]# vim mongodb-org-3.4.repo//加入如下內容
[mongodb-org-3.4]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/3.4/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-3.4.asc
[[email protected] yum.repos.d]# yum install -y mongodb-org
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
epel/x86_64/metalink | 8.9 kB 00:00:00
* base: centos.01link.hk
* epel: mirrors.ustc.edu.cn
* extras: centos.01link.hk
* updates: centos.01link.hk
........................................................................................
2.2 啟動mongod
[[email protected] yum.repos.d]# systemctl start mongod
[[email protected] yum.repos.d]# ps aux |grep mongod
mongod 33450 0.6 3.9 972844 39592 ? Sl 09:16 0:00 /usr/bin/mongod -f /etc/mongo.conf
root 33471 0.0 0.0 112704 960 pts/1 S+ 09:17 0:00 grep --color=auto mongod
[[email protected] yum.repos.d]# netstat -lnp |grep mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 33450/mongod
unix 2 [ ACC ] STREAM LISTENING 494210 33450/mongod /tmp/mongodb-27017.sock
3.連線mongodb
- 如果mongodb監聽埠並不是預設的27017,則在連線的時候需要加--port 選項,
- 例如 mongo --port 27018
- 連線遠端mongodb,需要加--host,例如 mongo --host 127.0.0.1
- 如果設定了驗證,則在連線的時候需要帶使用者名稱和密碼 mongo -uusername -ppasswd --authenticationDatabase db //這個和MySQL挺像
[[email protected] ~]# mongo
MongoDB shell version v3.4.18
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.18
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings:
2018-10-28T09:16:08.502-0400 I CONTROL [initandlisten]
2018-10-28T09:16:08.502-0400 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database.
2018-10-28T09:16:08.502-0400 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted.
2018-10-28T09:16:08.502-0400 I CONTROL [initandlisten]
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten]
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten]
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten] ** We suggest setting it to 'never'
2018-10-28T09:16:08.503-0400 I CONTROL [initandlisten]
>
4.mongodb使用者管理
//切換到admin庫
> use admin
switched to db admin
//建立一個使用者:user指定使用者,customData為說明欄位,可以省略,pwd為密碼,roles指定使用者的角色,db指定庫名
> db.createUser( { user: "admin", customData: {description: "superuser"}, pwd: "admin122", roles: [ { role: "root", db: "admin" } ] } )
Successfully added user: {
"user" : "admin",
"customData" : {
"description" : "superuser"
},
"roles" : [
{
"role" : "root",
"db" : "admin"
}
]
}
use admin //切換到admin庫
db.system.users.find() //列出所有使用者,需要切換到admin庫
show users //檢視當前庫下所有的使用者
db.dropUser('admin') //刪除使用者
若要使用者生效,還需要編輯啟動指令碼vim /usr/lib/systemd/system/mongod.service,在OPTIONS=後面增--auth
重啟服務systemctl restart mongod
mongo -u "admin" -p "admin122" --authenticationDatabase "admin"
4.2 MongoDB使用者角色
- Read:允許使用者讀取指定資料庫
- readWrite:允許使用者讀寫指定資料庫
- dbAdmin:允許使用者在指定資料庫中執行管理函式,如索引建立、刪除,檢視統計或訪問
- system.profile userAdmin:允許使用者向
- system.users集合寫入,可以找指定資料庫裡建立、刪除和管理使用者
- clusterAdmin:只在admin資料庫中可用,賦予使用者所有分片和複製集相關函式的管理許可權。
- readAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀許可權
- readWriteAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的讀寫許可權
- userAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的userAdmin許可權
- dbAdminAnyDatabase:只在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin許可權。
- root:只在admin資料庫中可用。超級賬號,超級許可權
4.3 MongoDB庫管理
- db.version() //檢視版本
- use userdb //如果庫存在就切換,不存在就建立
- show dbs //檢視庫,此時userdb並沒有出現,這是因為該庫是空的,還沒有任何集合,只需要建立一個集合就能看到了 db.createCollection('clo1') //建立集合clo1,在當前庫下面建立
- db.dropDatabase() //刪除當前庫,要想刪除某個庫,必須切換到那個庫下
- db.stats() //檢視當前庫的資訊
- db.serverStatus() //檢視mongodb伺服器的狀態
5.mongodb建立集合、資料管理
> db.createCollection("TT", { size : 6142800, max : 10000 } )
{ "ok" : 1 }
//語法:db.createCollection(name,options)
name就是集合的名字,options可選,用來配置集合的引數,引數如下
- capped true/false (可選)如果為true,則啟用封頂集合。封頂集合是固定大小的集合,當它達到其最大大小,會自動覆蓋最早 的條目。如果指定true,則也需要指定尺寸引數。
- autoindexID true/false (可選)如果為true,自動建立索引_id欄位的預設值是false。
- size (可選)指定最大大小位元組封頂集合。如果封頂如果是 true,那麼你還需要指定這個欄位。單位B
- max (可選)指定封頂集合允許在檔案的最大數量。
//檢視集合,或者使用show tables
> show collections
TT
system.users
system.version
//插入兩條資料
db.Account.insert({AccountID:1,UserName:"123",password:"123456"}) //如果集合不存在,直接插入資料,則mongodb會自動建立集合
> db.Account.insert({AccountID:2,UserName:"456",password:"123456"})
WriteResult({ "nInserted" : 1 })
//查詢集合中的資料
> db.Account.find()
{ "_id" : ObjectId("5bd5bbc4f0d6f1b379870358"), "AccountID" : 1, "UserName" : "123", "password" : "123456" }
- db.Account.find({AccountID:1}) //根據條件查詢
- db.Account.remove({AccountID:1}) //根據條件刪除
- db.Account.drop() //刪除所有文件,即刪除集合
- use dbname //先進入對應的庫
- db.printCollectionStats() // 然後檢視集合狀態
6.php的mongodb擴充套件
- cd /usr/local/src/
- wget https://pecl.php.net/get/mongodb-1.3.0.tgz
- tar zxvf mongodb-1.3.0.tgz
- cd mongodb-1.3.0 /usr/local/php/bin/phpize
- ./configure --with-php-config=/usr/local/php/bin/php-config
- make && make install
- vi /usr/local/php/etc/php.ini //增加 extension = mongodb.so
- //檢查php載入模組是否有mongodb.so
- /usr/local/php/bin/php -m
7.php的mongo擴充套件
- cd /usr/local/src/
- wget https://pecl.php.net/get/mongo-1.6.16.tgz
- tar zxvf mongodb-1.6.16.tgz cd mongodb-1.6.16
- /usr/local/php/bin/phpize
- ./configure --with-php-config=/usr/local/php/bin/php-config
- make && make install
- vi /usr/local/php/etc/php.ini //增加 extension = mongo.so
- /usr/local/php/bin/php -m
8.mongodb副本集介紹
副本集中資料同步過程:Primary節點寫入資料,Secondary通過讀取Primary的oplog得到複製資訊,開始複製資料並且將複製資訊寫入到自己的oplog。如果某個操作失敗,則備份節點停止從當前資料來源複製資料。如果某個備份節點由於某些原因掛掉了,當重新啟動後,就會自動從oplog的最後一個操作開始同步,同步完成後,將資訊寫入自己的oplog,由於複製操作是先複製資料,複製完成後再寫入oplog,有可能相同的操作會同步兩份,不過MongoDB在設計之初就考慮到這個問題,將oplog的同一個操作執行多次,與執行一次的效果是一樣的。簡單的說就是:
當Primary節點完成資料操作後,Secondary會做出一系列的動作保證資料的同步:
1:檢查自己local庫的oplog.rs集合找出最近的時間戳。
2:檢查Primary節點local庫oplog.rs集合,找出大於此時間戳的記錄。
3:將找到的記錄插入到自己的oplog.rs集合中,並執行這些操作。
副本集的同步和主從同步一樣,都是非同步同步的過程,不同的是副本集有個自動故障轉移的功能。其原理是:slave端從primary端獲取日誌,然後在自己身上完全順序的執行日誌所記錄的各種操作(該日誌是不記錄查詢操作的),這個日誌就是local資料 庫中的oplog.rs表,預設在64位機器上這個表是比較大的,佔磁碟大小的5%,oplog.rs的大小可以在啟動引數中設 定:--oplogSize 1000,單位是M。
注意:在副本集的環境中,要是所有的Secondary都宕機了,只剩下Primary。最後Primary會變成Secondary,不能提供服務。
9.mongodb副本集搭建
9.1 MongoDB副本集搭建
//編輯配置檔案
[[email protected] ~]# vim /etc/mongod.conf
net:
port: 27017
bindIp: 127.0.0.1,192.168.139.132
replication:
oplogSizeMB: 20
replSetName: knightlai
//在主上面操作
> config={_id:"knightlai",members:[{_id:0,host:"192.168.139.132:27017"},{_id:1,host:"192.168.139.133:27017"}]}
{
"_id" : "knightlai",
"members" : [
{
"_id" : 0,
"host" : "192.168.139.132:27017"
},
{
"_id" : 1,
"host" : "192.168.139.133:27017"
}
]
}
> rs.initiate(config)
{ "ok" : 1 }
//檢視副本集狀態
knightlai:OTHER> rs.status()
{
"set" : "knightlai",
"date" : ISODate("2018-10-28T14:32:07.554Z"),
"myState" : 2,
"term" : NumberLong(1),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"heartbeatIntervalMillis" : NumberLong(2000),
"optimes" : {
"lastCommittedOpTime" : {
"ts" : Timestamp(0, 0),
"t" : NumberLong(-1)
},
"appliedOpTime" : {
"ts" : Timestamp(1540737115, 1),
"t" : NumberLong(-1)
},
"durableOpTime" : {
"ts" : Timestamp(1540737115, 1),
"t" : NumberLong(-1)
}
},
"members" : [
{
"_id" : 0,
"name" : "192.168.139.132:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 120,
"optime" : {
"ts" : Timestamp(1540737115, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-10-28T14:31:55Z"),
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "could not find member to sync from",
"configVersion" : 1,
"self" : true,
"lastHeartbeatMessage" : ""
},
{
"_id" : 1,
"name" : "192.168.139.133:27017",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 11,
"optime" : {
"ts" : Timestamp(1540737115, 1),
"t" : NumberLong(-1)
},
"optimeDurable" : {
"ts" : Timestamp(1540737115, 1),
"t" : NumberLong(-1)
},
"optimeDate" : ISODate("2018-10-28T14:31:55Z"),
"optimeDurableDate" : ISODate("2018-10-28T14:31:55Z"),
"lastHeartbeat" : ISODate("2018-10-28T14:32:05.799Z"),
"lastHeartbeatRecv" : ISODate("2018-10-28T14:32:06.708Z"),
"pingMs" : NumberLong(8),
"lastHeartbeatMessage" : "",
"syncingTo" : "",
"syncSourceHost" : "",
"syncSourceId" : -1,
"infoMessage" : "",
"configVersion" : 1
}
],
"ok" : 1
}
10. mongodb副本集測試
//在主上操作,
knightlai:PRIMARY> use mydb
switched to db mydb
knightlai:PRIMARY> db.acc.insert({AccountID:1,UserName:"123",password:"123456"})
WriteResult({ "nInserted" : 1 })
knightlai:PRIMARY> show dbs
admin 0.000GB
local 0.000GB
mydb 0.000GB
//在從上操作
knightlai:SECONDARY> rs.slaveOk();
knightlai:SECONDARY> show dbs
admin 0.000GB
local 0.000GB
mydb 0.000GB
注意:如果出現以下錯誤只要執行 :knightlai:SECONDARY> rs.slaveOk();
- knightlai:SECONDARY> show dbs
- 2018-10-28T10:44:34.725-0400 E QUERY [thread1] Error: listDatabases failed:{
- "ok" : 0,
- "errmsg" : "not master and slaveOk=false",
- "code" : 13435,
- "codeName" : "NotMasterNoSlaveOk"
- } :
- [email protected]/mongo/shell/utils.js:25:13
- [email protected]/mongo/shell/mongo.js:62:1
- [email protected]/mongo/shell/utils.js:814:19
- [email protected]/mongo/shell/utils.js:704:15
- @(shellhelp2):1:1
10.2 副本集更改權重模擬主宕機
- 在主上執行 cfg = rs.conf()
- cfg.members[0].priority = 3
- cfg.members[1].priority = 2
- rs.reconfig(cfg)
knightlai:PRIMARY> cfg = rs.conf()
{
"_id" : "knightlai",
"version" : 3,
"protocolVersion" : NumberLong(1),
"members" : [
{
"_id" : 0,
"host" : "192.168.139.132:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 2,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
},
{
"_id" : 1,
"host" : "192.168.139.133:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 3,
"tags" : {
},
"slaveDelay" : NumberLong(0),
"votes" : 1
}
],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : 60000,
"getLastErrorModes" : {
},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5bd5c85b9b98966a0ba3dafe")
}
}
11.mongodb分片介紹
- mongos: 資料庫叢集請求的入口,所有的請求都通過mongos進行協調,不需要在應用程式新增一個路由選擇器,mongos自己就是一個請求分發中心,它負責把對應的資料請求請求轉發到對應的shard伺服器上。在生產環境通常有多mongos作為請求的入口,防止其中一個掛掉所有的mongodb請求都沒有辦法操作。
- config server: 配置伺服器,儲存所有資料庫元資訊(路由、分片)的配置。mongos本身沒有物理儲存分片伺服器和資料路由資訊,只是快取在記憶體裡,配置伺服器則實際儲存這些資料。mongos第一次啟動或者關掉重啟就會從 config server 載入配置資訊,以後如果配置伺服器資訊變化會通知到所有的 mongos 更新自己的狀態,這樣 mongos 就能繼續準確路由。在生產環境通常有多個 config server 配置伺服器,因為它儲存了分片路由的元資料,防止資料丟失!
- shard: 儲存了一個集合部分資料的MongoDB例項,每個分片是單獨的mongodb服務或者副本集,在生產環境中,所有的分片都應該是副本集。
13.MongoDB備份
- 備份指定庫 mongodump --host 127.0.0.1 --port 20000 -d mydb -o /tmp/mongobak 它會在/tmp/目錄下面生成一個mydb的目錄 備份所有庫 mongodump --host 127.0.0.1 --port 20000 -o /tmp/mongobak/alldatabase
- 指定備份集合 mongodump --host 127.0.0.1 --port 20000 -d mydb -c c1 -o /tmp/mongobak/ 它依然會生成mydb目錄,再在這目錄下面生成兩個檔案 匯出集合為json檔案
- mongoexport --host 127.0.0.1 --port 20000 -d mydb -c c1 -o /tmp/mydb2/1.json
MongoDB恢復
恢復所有庫 mongorestore -h 127.0.0.1 --port 20000 --drop
dir/ //其中dir是備份所有庫的目錄名字,其中--drop可選,意思是當恢復之前先把之前的資料刪除,不建議使用 恢復指定庫 mongorestore -d mydb dir/ //-d跟要恢復的庫名字,dir就是該庫備份時所在的目錄
恢復集合 mongorestore -d mydb -c testc dir/mydb/testc.bson // -c後面跟要恢復的集合名字,dir是備份mydb庫時生成檔案所在路徑,這裡是一個bson檔案的路徑 匯入集合 mongoimport -d mydb -c testc --file /tmp/testc.json
擴充套件連結
https://note.youdao.com/share/?token=0EED380D933E4F7ABA0C6BB4A3FCA4CD&gid=31981530#/