第一章、副本集 - Replica Sets
1.1 簡介
MongoDB 中的副本集(Replica Set)是一組維護相同數據集的 mongod 服務。 副本集可提供冗餘和高可用性,是所有生產部署的基礎。
也可以說,副本集類似於有自動故障恢復功能的主從集羣。通俗的講就是用多臺機器進行同一數據的異步同步,從而使多臺機器擁有同一數據的多個副本,並且當主庫當掉時在不需要用戶干預的情況下自動切換其他備份服務器做主庫。而且還可以利用副本服務器做只讀服務器,實現讀寫分離,提高負載。
冗餘和數據可用性
複製提供冗餘並提高數據可用性。 通過在不同數據庫服務器上提供多個數據副本,複製可提供一定級別的容錯功能,以防止丟失單個數據庫服務器。
在某些情況下,複製可以提供增加的讀取性能,因爲客戶端可以將讀取操作發送到不同的服務上, 在不同數據中心維護數據副本可以增加分佈式應用程序的數據位置和可用性。 還可以爲專用目的維護其他副本,例如災難恢復,報告或備份。
MongoDB 中的複製
副本集是一組維護相同數據集的 mongod 實例。 副本集包含多個數據承載節點和可選的一個仲裁節點。 在承載數據的節點中,一個且僅一個成員被視爲主節點,而其他節點被視爲次要(從)節點。
主節點接收所有寫操作。 副本集只能有一個主要能夠確認具有 {w:"most"}
寫入關注的寫入; 雖然在某些情況下,另一個 mongod 實例可能暫時認爲自己也是主要的。主要記錄其操作日誌中的數據集的所有 更改,即 oplog。
輔助(副本)節點複製主節點的oplog並將操作應用於其數據集,以使輔助節點的數據集反映主節點的數據 集。 如果主要人員不在,則符合條件的中學將舉行選舉以選出新的主要人員。
主從複製和副本集區別
主從集羣和副本集最大的區別就是副本集沒有固定的”主節點”;整個集羣會選出一個”主節點”,當其掛掉後,又在剩下的從節點中選中其他節點爲主節點,副本集總有一個活躍點 (主、primary) 和一個或多個備份節點 (從、secondary)
1.2 副本集的三個角色
副本集有兩種類型三種角色
兩種類型:
- 主節點(Primary)類型:數據操作的主要連接點,可讀寫
- 次要(輔助、從)節點(Secondary)類型:數據冗餘備份節點,可以讀或選舉
三種角色:
-
主要成員(Primary):主要接收所有寫操作。就是主節點
-
副本成員(Replicate):從主節點通過複製操作以維護相同的數據集,即備份數據,不可寫操作,但可以讀操作(但需要配置)。是默認的一種從節點類型
-
仲裁者(Arbiter):不保留任何數據的副本,只具有投票選舉作用。當然也可以將仲裁服務器維護爲副本集的一部分,即副本成員同時也可以是仲裁者。也是一種從節點類型。
關於仲裁者的額外說明:
您可以將額外的 mongod 實例添加到副本集作爲仲裁者。 仲裁者不維護數據集。 仲裁者的目的是通過響應其他副本集成員的心跳和選舉請求來維護副本集中的仲裁。 因爲它們不存儲數據集,所以仲裁器可以是提供副本集仲裁功能的好方法,其資源成本比具有數據集的全功能副本集成員更便宜。
如果您的副本集具有偶數個成員,請添加仲裁者以獲得主要選舉中的大多數投票。 仲裁者不需要專用 硬件。
仲裁者將永遠是仲裁者,而主要人員可能會退出併成爲次要人員,而次要人員可能成爲選舉期間的主要人員。
如果你的副本+主節點的個數是偶數,建議加一個仲裁者,形成奇數,容易滿足大多數的投票。
如果你的副本+主節點的個數是奇數,可以不加仲裁者。
- 說人話就是 [Paxos 協議算法]
1.3 動手實現一個副本集
使用一個主節點, 一個副節點, 一個仲裁節點
- 用端口號區分不同的節點
- 副本集名稱都是
myrs
1.3.1 創建主節點
建立存放數據和日誌的目錄
#-----------myrs
#主節點
mkdir -p /mongodb/replica_sets/myrs_27017/log \ &
mkdir -p /mongodb/replica_sets/myrs_27017/data/db
新建或修改配置文件:
vim /mongodb/replica_sets/myrs_27017/mongod.conf
myrs_27017:
systemLog:
#MongoDB發送所有日誌輸出的目標指定爲文件
destination: file
#mongod或mongos應向其發送所有診斷日誌記錄信息的日誌文件的路徑
path: "/mongodb/replica_sets/myrs_27017/log/mongod.log"
#當mongos或mongod實例重新啓動時,mongos或mongod會將新條目附加到現有日誌文件的末尾。
logAppend: true
storage:
#mongod實例存儲其數據的目錄。storage.dbPath設置僅適用於mongod。
dbPath: "/mongodb/replica_sets/myrs_27017/data/db"
journal:
#啓用或禁用持久性日誌以確保數據文件保持有效和可恢復。
enabled: true
processManagement:
#啓用在後臺運行mongos或mongod進程的守護進程模式。
fork: true
#指定用於保存mongos或mongod進程的進程ID的文件位置,其中mongos或mongod將寫入其PID
pidFilePath: "/mongodb/replica_sets/myrs_27017/log/mongod.pid"
net:
#服務實例綁定所有IP,有副作用,副本集初始化的時候,節點名字會自動設置爲本地域名,而不是ip
#bindIpAll: true
#服務實例綁定的IP
bindIp: localhost,192.168.0.2
#bindIp
#綁定的端口
port: 27017
replication:
#副本集的名稱
replSetName: myrs
啓動節點服務:
[root@bobohost replica_sets]# /usr/local/mongodb/bin/mongod -f
/mongodb/replica_sets/myrs_27017/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 54257
child process started successfully, parent exiting
1.3.2 創建副本節點
建立存放數據和日誌的目錄
#-----------myrs
#副本節點
mkdir -p /mongodb/replica_sets/myrs_27018/log \ &
mkdir -p /mongodb/replica_sets/myrs_27018/data/db
新建或修改配置文件:
vim /mongodb/replica_sets/myrs_27018/mongod.conf
myrs_27018:
systemLog:
#MongoDB發送所有日誌輸出的目標指定爲文件
destination: file
#mongod或mongos應向其發送所有診斷日誌記錄信息的日誌文件的路徑
path: "/mongodb/replica_sets/myrs_27018/log/mongod.log"
#當mongos或mongod實例重新啓動時,mongos或mongod會將新條目附加到現有日誌文件的末尾。
logAppend: true
storage:
#mongod實例存儲其數據的目錄。storage.dbPath設置僅適用於mongod。
dbPath: "/mongodb/replica_sets/myrs_27018/data/db"
journal:
#啓用或禁用持久性日誌以確保數據文件保持有效和可恢復。
enabled: true
processManagement:
#啓用在後臺運行mongos或mongod進程的守護進程模式。
fork: true
#指定用於保存mongos或mongod進程的進程ID的文件位置,其中mongos或mongod將寫入其PID
pidFilePath: "/mongodb/replica_sets/myrs_27018/log/mongod.pid"
net:
#服務實例綁定所有IP,有副作用,副本集初始化的時候,節點名字會自動設置爲本地域名,而不是ip
#bindIpAll: true
#服務實例綁定的IP
bindIp: localhost,192.168.0.2
#bindIp
#綁定的端口
port: 27018
replication:
#副本集的名稱
replSetName: myrs
啓動節點服務:
[root@bobohost replica_sets]# /usr/local/mongodb/bin/mongod -f
/mongodb/replica_sets/myrs_27018/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 54361
child process started successfully, parent exiting
1.3.3 創建仲裁節點
建立存放數據和日誌的目錄
#-----------myrs
#仲裁節點
mkdir -p /mongodb/replica_sets/myrs_27019/log \ &
mkdir -p /mongodb/replica_sets/myrs_27019/data/db
仲裁節點:
新建或修改配置文件:
vim /mongodb/replica_sets/myrs_27019/mongod.conf
myrs_27019:
systemLog:
#MongoDB發送所有日誌輸出的目標指定爲文件
destination: file
#mongod或mongos應向其發送所有診斷日誌記錄信息的日誌文件的路徑
path: "/mongodb/replica_sets/myrs_27019/log/mongod.log"
#當mongos或mongod實例重新啓動時,mongos或mongod會將新條目附加到現有日誌文件的末尾。
logAppend: true
storage:
#mongod實例存儲其數據的目錄。storage.dbPath設置僅適用於mongod。
dbPath: "/mongodb/replica_sets/myrs_27019/data/db"
journal:
#啓用或禁用持久性日誌以確保數據文件保持有效和可恢復。
enabled: true
processManagement:
#啓用在後臺運行mongos或mongod進程的守護進程模式。
fork: true
#指定用於保存mongos或mongod進程的進程ID的文件位置,其中mongos或mongod將寫入其PID
pidFilePath: "/mongodb/replica_sets/myrs_27019/log/mongod.pid"
net:
#服務實例綁定所有IP,有副作用,副本集初始化的時候,節點名字會自動設置爲本地域名,而不是ip
#bindIpAll: true
#服務實例綁定的IP
bindIp: localhost,192.168.0.2
#bindIp
#綁定的端口
port: 27019
replication:
#副本集的名稱
replSetName: myrs
啓動節點服務:
[root@bobohost replica_sets]# /usr/local/mongodb/bin/mongod -f
/mongodb/replica_sets/myrs_27019/mongod.conf
about to fork child process, waiting until server is ready for connections.
forked process: 54410
child process started successfully, parent exiting
1.3.4 初始化配置副本集和主節點
使用客戶端命令連接任意一個節點,但這裏儘量要連接主節點 (27017節點)
$ /usr/local/mongodb/bin/mongo --host=180.76.159.126 --port=27017
連接上之後,很多命令無法使用, 比如 show dbs
等,必須初始化副本集纔行
初始化新的副本集
# example, `configuration` is optional
# rs.initiate(configuration)
$ rs.initiate()
{
"info2" : "no configuration specified. Using a default configuration for the set",
"me" : "<ip_address>:27017",
"ok" : 1,
"operationTime" : Timestamp(1565760476, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1565760476, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
myrs:SECONDARY> <hit enter>
myrs:PRIMARY>
ok
的值爲1
, 說明創建成功- 命令行提示符發生變化,變成了一個從節點角色,此時默認不能讀寫。稍等片刻,回車,變成主節 點。
1.3.5 查看配置
# configuration - optional
$ rs.conf(configuration)
myrs:PRIMARY> rs.conf()
{
"_id" : "myrs",
"version" : 1,
"protocolVersion" : NumberLong(1),
"writeConcernMajorityJournalDefault" : true,
"members" : [{
"_id" : 0,
"host" : "180.76.159.126:27017",
"arbiterOnly" : false,
"buildIndexes" : true,
"hidden" : false,
"priority" : 1,
"tags" : {},
"slaveDelay" : NumberLong(0),
"votes" : 1
}],
"settings" : {
"chainingAllowed" : true,
"heartbeatIntervalMillis" : 2000,
"heartbeatTimeoutSecs" : 10,
"electionTimeoutMillis" : 10000,
"catchUpTimeoutMillis" : -1,
"catchUpTakeoverDelayMillis" : 30000,
"getLastErrorModes" : {},
"getLastErrorDefaults" : {
"w" : 1,
"wtimeout" : 0
},
"replicaSetId" : ObjectId("5d539bdcd6a308e600d126bb")
}
}
"_id" : "myrs"
:副本集的配置數據存儲的主鍵值,默認就是副本集的名字"members"
:副本集成員數組,此時只有一個:"host" : "180.76.159.126:27017"
,該成員不是仲裁節點:"arbiterOnly" : false
,優先級(權重值):"priority" : 1
"settings"
:副本集的參數配置。
1.3.6 查看副本集狀態
返回包含狀態信息的文檔。此輸出使用從副本集的其他成員發送的心跳包中獲得的數據反映副本集的當 前狀態
$ rs.status()
1.3.7 添加副本節點以及仲裁節點
在主節點添加從節點,將其他成員加入到副本集
語法:
$ rs.add(host, arbiterOnly)
選項:
【示例】
將27018的副本節點添加到副本集中:
myrs:PRIMARY> rs.add("180.76.159.126:27018")
{
"ok" : 1,
"operationTime" : Timestamp(1565761757, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1565761757, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
說明:
- "ok" : 1 :說明添加成功
添加一個仲裁節點到副本集
語法:
rs.addArb(host)
將27019的仲裁節點添加到副本集中:
myrs:PRIMARY> rs.addArb("180.76.159.126:27019")
{
"ok" : 1,
"operationTime" : Timestamp(1565761959, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1565761959, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
說明:
- "ok" : 1 :說明添加成功
1.4 副本集的數據讀寫操作
副本節點 (SECONDARY) 默認不能 read , 更不可能 write 數據, 需要
$ rs.slaveOk()
myrs:SECONDARY> show dbs;
"errmsg" : "not master and slaveOk=false",
# 非主節點同時 slaveOk=false 無法讀寫
數據會自動同步, 但是會有延遲
仲裁者節點, 不存放任何數據 -> rs.slaveOk()
也看不到數據
1.5 主節點的選舉原則
MongoDB在副本集中,會自動進行主節點的選舉,主節點選舉的觸發條件
- 主節點故障
- 主節點網絡不可達 (默認心跳信息爲 10 秒)
- 人工干預
rs.stepDown(600)
一旦觸發選舉,就要根據一定規則來選主節點
選舉規則是根據票數來決定誰獲勝
- 票數最高,且獲得了“大多數”成員的投票支持的節點獲勝。
- “大多數”的定義爲:假設複製集內投票成員數量爲N,則大多數爲 N/2 + 1。例如:3個投票成員, 則大多數的值是2。當複製集內存活成員數量不足大多數時,整個複製集將無法選舉出Primary, 複製集將無法提供寫服務,處於只讀狀態。
- 若票數相同,且都獲得了“大多數”成員的投票支持的,數據新的節點獲勝。
- 數據的新舊是通過操作日誌 oplog 來對比的。
在獲得票數的時候,優先級(priority)參數影響重大。
可以通過設置優先級(priority)來設置額外票數。優先級即權重,取值爲0-1000,相當於可額外增加 0-1000的票數,優先級的值越大,就越可能獲得多數成員的投票(votes)數。指定較高的值可使成員 更有資格成爲主要成員,更低的值可使成員更不符合條件。
主節點和副本節點的默認優先級各爲1,即,默認可以認爲都已經有了一票。但仲裁節點,優先級是0,(要注意是,官方說了,仲裁節點的優先級必須是0,不能是別的值。即不具備選舉權,但具有投票權)
1.6 故障測試
1.6.1 副本節點故障測試
關閉 27018
副本節點
- 主節點和仲裁節點對
27018
的心跳失敗。因爲主節點還在,因此,沒有觸發投票選舉。 - 如果此時,在主節點寫入數據。再啓動從節點,會發現,主節點寫入的數據,會自動同步給從節點。
1.6.2 主節點故障測試
關閉27017節點
- 從節點和仲裁節點對27017的心跳失敗,當失敗超過10秒,此時因爲沒有主節點了,會自動發起投票。
- 而副本節點只有27018,因此,候選人只有一個就是27018,開始投票。
- 27019向27018投了一票,27018本身自帶一票,因此共兩票,超過了“大多數”
- 27019是仲裁節點,沒有選舉權,27018不向其投票,其票數是0.
最終結果,27018成爲主節點。具備讀寫功能。 在27018寫入數據查看。
1.6.3 仲裁節點和主節點故障
先關掉仲裁節點27019,關掉現在的主節點27018,登錄27017後
- 27017仍然是從節點,副本集中沒有主節點了,導致此時,副本集是隻讀狀態, 無法寫入。
- 爲啥不選舉了?
- 因爲27017的票數,沒有獲得大多數,即沒有大於等於2,它只有默認的一票(優先級 是1)
- 如果要觸發選舉,隨便加入一個成員即可。
- 如果只加入27019仲裁節點成員,則主節點一定是27017,因爲沒得選了,仲裁節點不參與選舉, 但參與投票
- 如果只加入27018節點,會發起選舉。因爲27017和27018都是兩票,則按照誰數據新,誰當主節點。
1.6.4 仲裁節點和從節點故障
先關掉仲裁節點 27019
,關掉現在的副本節點 27018
10秒後,27017
主節點自動降級爲副本節點。(服務降級)
副本集不可寫數據了,已經故障了。
第二章、分片集羣 - Sharded Cluster
2.1 分片概念
分片 (sharding) 是一種跨多臺機器分佈數據的方法, MongoDB 使用分片來支持具有非常大的數據集和高吞吐量操作的部署。
換句話說:分片 (sharding) 是指將數據拆分,將其分散存在不同的機器上的過程。有時也用分區 (partitioning) 來表示這個概念。將數據分散到不同的機器上,不需要功能強大的大型計算機就可以儲存更多的數據,處理更多的負載。
具有大型數據集或高吞吐量應用程序的數據庫系統可以會挑戰單個服務器的容量。例如,高查詢率會耗盡服務器的 CPU 容量。工作集大小大於系統的 RAM 會強調磁盤驅動器的 I/O
容量。
有兩種解決系統增長的方法:垂直擴展和水平擴展。
- 垂直擴展意味着增加單個服務器的容量,例如使用更強大的CPU,添加更多RAM或增加存儲空間量。可 用技術的侷限性可能會限制單個機器對於給定工作負載而言足夠強大。此外基於雲的提供商基於可用的硬件配置具有硬性上限。結果,垂直縮放有實際的最大值。
- 水平擴展意味着劃分系統數據集並加載多個服務器,添加其他服務器以根據需要增加容量。雖然單個機器的總體速度或容量可能不高,但每臺機器處理整個工作負載的子集,可能提供比單個高速大容量服務器更高的效率。擴展部署容量只需要根據需要添加額外的服務器,這可能比單個機器的高端硬件的總體 成本更低。權衡是基礎架構和部署維護的複雜性增加。
MongoDB 支持通過分片進行水平擴展。
2.2 分片集羣包含的組件
MongoDB 分片羣集包含以下組件:
- 分片(存儲):每個分片包含分片數據的子集。 每個分片都可以部署爲副本集。
- mongos (路由):mongos充當查詢路由器,在客戶端應用程序和分片集羣之間提供接口。
- config servers (”調度” 的配置):配置服務器存儲羣集的元數據和配置設置。 從MongoDB 3.4 開始,必須將配置服務器部署爲副本集(CSRS)。
下圖描述了分片集羣中組件的交互:
MongoDB在集合級別對數據進行分片,將集合數據分佈在集羣中的分片上。
27018 if mongod is a shard member;
27019 if mongod is a confifig server member
2.3 分片集羣架構目標
兩個分片節點副本集(3+3)+ 一個配置節點副本集(3)+ 兩個路由節點(2),共
11
個服務節點
副本集的創建詳見文檔以及視頻
添加分片
$ sh.addShard("IP:Port", "IP:Port", "IP:Port")
查看分片狀態情況
$ sh.status()
如果添加分片失敗,需要先手動移除分片,檢查添加分片的信息的正確性後,再次添加分片。 移除分片:
$ use admin
$ db.runCommand( { removeShard: "myshardrs02" } )
- 如果只剩下最後一個 shard,是無法刪除的
- 移除時會自動轉移分片數據,需要一個時間過程
- 完成後,再次執行刪除分片命令才能真正刪除
開啓分片功能
$ sh.enableSharding("articledb")
$ sh.enableSharding("庫名")
$ sh.shardCollection("庫名.集合名",{"key":1})
集合分片,使用 sh.shardCollection()
方法指定集合和分片鍵
$ sh.shardCollection(namespace, key, unique)
對集合進行分片時, 你需要選擇一個 片鍵 (Shard Key) shard key 是每條記錄都必須包含的, 且建立了索引的單個字段或複合字段, MongoDB按照片鍵將數據劃分到不同的數據塊中,並將數據塊均衡地分佈到所有分片中. 爲了按照片鍵劃分數據塊, MongoDB使用基於哈希的分片方式(隨機平均分配)或者基於範圍的分片方式(數值大小分配) 。
用什麼字段當片鍵都可以,如:nickname作爲片鍵,但一定是必填字段。
分片策略(規則)
哈希策略
對於 基於哈希 的分片 , MongoDB計算一個字段的哈希值, 並用這個哈希值來創建數據塊.
在使用基於哈希分片的系統中, 擁有”相近”片鍵的文檔很可能不會存儲在同一個數據塊中, 因此數據的分離性更好一些.
範圍策略
對於 基於範圍 的分片 , MongoDB 按照片鍵的範圍把數據分成不同部分. 假設有一個數字的片鍵 : 想象一個從負無窮到正無窮的直線,每一個片鍵的值都在直線上畫了一個點. MongoDB把這條直線劃分爲更短的不重疊的片段, 並稱之爲數據塊 ,每個數據塊包含了片鍵在一定範圍內的數據.
在使用片鍵做範圍劃分的系統中, 擁有”相近”片鍵的文檔很可能存儲在同一個數據塊中, 因此也會存儲在同一個分片中.
基於範圍的分片方式與基於哈希的分片方式性能對比
基於範圍的分片方式提供了更高效的範圍查詢, 給定一個片鍵的範圍,分發路由可以很簡單地確定哪個數 據塊存儲了請求需要的數據,並將請求轉發到相應的分片中. 不過, 基於範圍的分片會導致數據在不同分片上的不均衡,有時候,帶來的消極作用會大於查詢性能的積極作用. 比如, 如果片鍵所在的字段是線性增長的, 一定時間內的所有請求都會落到某個固定的數據塊中, 最終導致分佈在同一個分片中. 在這種情況下, 一小部分分片承載了集羣大部分的數據,系統並不能很好地進行 擴展. 與此相比, 基於哈希的分片方式以範圍查詢性能的損失爲代價, 保證了集羣中數據的均衡.哈希值的隨機性 使數據隨機分佈在每個數據塊中, 因此也隨機分佈在不同分片中.但是也正由於隨機性, 一個範圍查詢很難 確定應該請求哪些分片, 通常爲了返回需要的結果,需要請求所有分片.
如無特殊情況,一般推薦使用 Hash Sharding
. 而使用 _id
作爲片鍵是一個不錯的選擇,因爲它是必有的,你可以使用數據文檔 _id
的哈希作爲片鍵。 這個方案能夠是的讀和寫都能夠平均分佈,並且它能夠保證每個文檔都有不同的片鍵所以數據塊能夠很 精細。 似乎還是不夠完美,因爲這樣的話對多個文檔的查詢必將命中所有的分片。雖說如此,這也是一種比較 好的方案了。 理想化的 shard key
可以讓 documents 均勻地在集羣中分佈
第三章、安全認證
3.1 MongoDB的用戶和角色權限簡介
默認情況下,MongoDB實例啓動運行時是沒有啓用用戶訪問權限控制的,也就是說,在實例本機服務器上都可以隨意連接到實例進行各種操作,MongoDB不會對連接客戶端進行用戶驗證,這是非常危險的。
mongodb官網上說,爲了能保障mongodb的安全可以做以下幾個步驟
- 使用新的端口,默認的 27017 端口如果一旦知道了 ip 就能連接上,不太安全
- 設置 mongodb 的網絡環境,最好將 mongodb 部署到公司服務器內網,這樣外網是訪問不到的。公 司內部訪問使用 vpn 等
- 開啓安全認證。認證要同時設置服務器之間的內部認證方式,同時要設置客戶端連接到集羣的賬號 密碼認證方式。
爲了強制開啓用戶訪問控制(用戶驗證),則需要在MongoDB實例啓動時使用選項 –auth 或在指定啓動 配置文件中添加選項 auth=true
在開始之前需要了解一下概念
啓用訪問控制
- MongoDB使用的是基於角色的訪問控制(Role-Based Access Control,RBAC)來管理用戶對實例的訪問。 通過對用戶授予一個或多個角色來控制用戶訪問數據庫資源的權限和數據庫操作的權限,在對用戶分配 角色之前,用戶無法訪問實例
- 在實例啓動時添加選項 –auth 或指定啓動配置文件中添加選項
auth=true
角色
在MongoDB中通過角色對用戶授予相應數據庫資源的操作權限,每個角色當中的權限可以顯式指定, 也可以通過繼承其他角色的權限,或者兩都都存在的權限。
權限
權限由指定的數據庫資源(resource)以及允許在指定資源上進行的操作(action)組成
- 資源(resource)包括:數據庫、集合、部分集合和集羣
- 操作(action)包括:對資源進行的增、刪、改、查(CRUD)操作
在角色定義時可以包含一個或多個已存在的角色,新創建的角色會繼承包含的角色所有的權限。在同一 個數據庫中,新創建角色可以繼承其他角色的權限,在 admin 數據庫中創建的角色可以繼承在其它任意 數據庫中角色的權限。
# 查詢所有角色權限(僅用戶自定義角色)
$ db.runCommand({ rolesInfo: 1 })
# 查詢所有角色權限(包含內置角色)
$ db.runCommand({ rolesInfo: 1, showBuiltinRoles: true })
# 查詢當前數據庫中的某角色的權限
$ db.runCommand({ rolesInfo: "<rolename>" })
# 查詢其它數據庫中指定的角色權限
$ db.runCommand({ rolesInfo: { role: "<rolename>", db: "<database>" } }
# 查詢多個角色權限
$ db.runCommand({
rolesInfo: [
"<rolename>",
{
role: "<rolename>",
db: "<database>"
},
...
]
})
常用的內置角色:
- 數據庫用戶角色:read、readWrite
- 所有數據庫用戶角色:readAnyDatabase、readWriteAnyDatabase、 userAdminAnyDatabase、dbAdminAnyDatabase
- 數據庫管理角色: dbAdmin、dbOwner、userAdmin
- 集羣管理角色: clusterAdmin、clusterManager、clusterMonitor、hostManager
- 備份恢復角色: backup、restore
- 超級用戶角色: root
- 內部角色: system