1. 程式人生 > >第三十六課預習任務

第三十六課預習任務

1.mongodb介紹

2.mongodb安裝

3.連線mongodb

4.mongodb使用者管理

4.2 MongoDB使用者角色

4.3 MongoDB庫管理

5.mongodb建立集合、資料管理

6.php的mongodb擴充套件

7.php的mongo擴充套件

8.mongodb副本集介紹

9.mongodb副本集搭建

10. mongodb副本集測試

10.2 副本集更改權重模擬主宕機

11.mongodb分片介紹

13.MongoDB備份

MongoDB恢復



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#/