MongoDB Certification Study Guide / MongoDB 證照考試指南 重點整理(下)

Caspar Chang
5 min readMar 26, 2021

--

本文是 MongoDB Certified Study Guide(下),主要分享認證考試重點,幫助大家快速應試考取證照。

由於內容較多,本篇僅介紹 Replication, Sharding, Application & Server Administration (DBA Only), Storage Engine, Glossary

其餘的包括 Philosophy and Features, CRUD, Indexes 與 Aggregation (Developer Only) ,請參考上篇

MongoDB Certified Intro 請參考於此

MongoDB Certified Overview 請參考於此

開始之前

Practice Exams 記得多做,可以幫助你大致了解考試題型以及比較不足的地方,也比較好做針對性的補強。

記得準備 Certification Study Guide

接下來會帶著大家複習考試要點,這是我在準備認證的時候整理的Study Guide,會從中挑出比較重要的部分跟大家做分享。

Glossary

概述

有空把 Glossary 看一遍,大概會出2題
有些少見的名詞如:idempotent, snappy, term, zlib, zstd 大概懂就好

Storage Engine

概述

大概會出2題,詳細有點忘了,主要幾個觀念懂就好。現行主要的storage engine是 WiredTiger 與 In-memory (MongoDB Enterprise才有),至於MMAPv1已經被遺棄無法再用了。

WiredTiger :

預設存儲引擎,屬於 Document Level Concurrency預設壓縮方式:
snappy compression library for all collections.
prefix compression for all indexes.
可選壓縮方式:
zlib/zstd
預設大小:
256MG or 50% (RAM - 1 GB)
可透過 --wiredTigerCacheSizeGB 設定大小

Journal :

MongoDB 交易日誌
Recover Data After Unexpected Shutdown On a restart after a crash。
由於WiredTiger每60秒才寫入一次硬碟,在這之間若出現異常則需要透過Journal Log來做資料復原。
預設開啟,在Replica Set中則為必需開啟
每100ms 寫入一次disk, journal log 大小為 100mb
若使用 write concern : majority 或是寫入設定 j : true
每次寫入 都寫入disk

Tools

概述

大概看一下 MongoDB Tools 的工具有哪些, 應該會考1題左右。mongoimport/mongoexport :
預設格式為JSON, 可以指定CSV (--type=csv)
mongodump/mongorestore :
使用格式為BSON
mongostat :
呈現整體crud資訊,包含insert/update/delete/getMore/command 等
mongotop :
呈現hot collection的read/write資訊

Replication

概述

大概會出6~10題,看考的是Developer還是DBAReplication這個部分考得比較細,會考使用目的(高可用異地備援),資料抄寫的方式(Statement Based),如何判斷主從節點(db.isMaster()),如何取得集群狀態(rs.status()),節點特性(arbiter, hidden),集群設定(rs.config()) 等等

rs常用語法 :

rs狀態檢查指令,資訊豐富程度
rs.status() >= db.isMaster() >= db.serverStatus()['repl']
rs如何在從節點操作
rs.slaveOk()
可以在從節點進行讀取或是建立index, 無法寫入資料
db.isMaster()
可以在任何節點查詢節點狀態
rs參數檢查
cfg = rs.config()
更改 cfg 後, 使用 rs.reconfig(cfg) 更新設定
更新後 config.version 的值會 +1
rs新增節點
rs.add("host:port")
rs新增仲裁
rs.addArb("host:port")
rs主從切換 failover
rs.stepDown()

rs 參數設定 :

需要知道rs有哪些從節點類型,其行為模式以及如何配置
所以大致上要知道每個參數在做什麼,能記就記
Arbiter - 仲裁者
vote 必為 1, priority 預設 0, 可為 1
Delayed - 延遲節點
priority 必為 0, 可以 vote
Hidden - 隱藏節點
priority 必為 0, 可以 vote
db.isMaster() 不會呈現出資訊
votes
0 or 1, 最多能有七個投票節點
大於零才能acknowledging write operations with majority
priority
0~1000, 0的話代表無法變成Primary, 1以上的話 votes必須大於0
tag
讀取偏好 tag
rs.config()
_id: <string>,
version: <int>,
term: <int>,
protocolVersion: <number>,
writeConcernMajorityJournalDefault: <boolean>,
configsvr: <boolean>,
members: [{
_id: <int>,
host: <string>,
arbiterOnly: <boolean>,
buildIndexes: <boolean>,
hidden: <boolean>,
priority: <number>,
tags: <document>,
slaveDelay: <int>,
votes: <number>
}]

Oplog :

俗稱交易日誌, 是statement based抄寫
Primary執行deleteMany指令, Secondary可能會收到0~N行異動的語法.
rs的節點之間主要透過oplog做資料同步
oplog的狀態
db.oplog.rs.stats()
rs.printReplicationInfo()
oplog的存放位置
local.oplog.rs
oplog的可用空間
5% disk space, 下限990MB ~ 上限 50GB
屬於 capped collection 有固定大小, 所以最舊的交易日誌會一直被清掉

rs 讀寫偏好 :

只要記得有這些偏好設定就好,詳細的行為能記再記Read Preference : 
primary, primaryPreferred, secondary, secondaryPreferred, nearest
Read Concern :
local, available, majority, linearizable, snapshot
Write Concern :
預設為 1 , 通常建議 majority (過半數)
wtimeout 預設為 0ms, 代表會持續等待寫入acknowledge

rs 投票機制 :

在下列情況下,會觸發rs選舉機制 (不一定會切換)
initiating a replica set
Adding a new node to the replica set
rs.stepDown() / rs.reconfig()
timeout
settings.electionTimeoutMillis //切換判斷時間,預設1000ms
補充 Heartbeats 機制是每兩秒一次

Sharding

概述

大概會出8~10題,看考的是Developer還是DBASharding這個部分算挺簡單的,會考為何需要sharding(分散讀寫,提升效能,提升備份還原效率),sharding的組成(mongoS, mongoD, config Server),sharding設計實作(如何選擇shard key),與sharding的維運(看懂chunk, 搬移chunk),以及primary shard的額外功能 等等

Sharding Basics :

Sharding 狀態檢查
sh.status()
db.collection.getShardDistribution()
Shard key 選擇
High Cardinality, Low Frequency, Non-Monotonically
必需先建立為index, 才能建立為shard key (shard collection by shard key)
Sharding 種類
Range sharding, Hash sharding
Primary shard 行為
stores unsharded collection
aggregation stages : $out, $facet, $lookup
Aggregation on shards
$sort : push sort to each shard and merge sorts (在mongoS裡面跑)
$limit : pass limit to each shard and limit after merge (從各shard抓取limit+skip數量的資料)
$skip : perform skip after merge (從各shard抓取unskip資料, skip不會在shard上做)
db.movies.find({"cast": "Meryl Streep"}).sort({"year":1}).skip(100).limit(20)
route, sort_by_shard, limit_by_shard, sort_by_mongos, skip_by_mongos, limit_by_mongos
在各shard應該要提供100+20個彙整到mongos 確保足夠
Unique
only _id or shard key prefix can be unique

Chunks :

Chunk 分佈
透過 sh.status() 指令做查詢,
需注意chunk range 右邊邊界是小於, 左邊邊界是大於等於
chunk Lower bound is inclusive, Upper bound is exclusive.

需看懂chunk分佈
以下的範例, productId 9294 會在 shard0002
{ "productId" : { "$minKey" : 1 } } -->> { "productId" : 9294 } on : shard0000 { "t" : 2, "i" : 0 }
{ "productId" : 9294 } -->> { "productId" : 18684 } on : shard0002 { "t" : 3, "i" : 0 }
Chunk Migration
透過balancer做搬移,balancer可以被stop與start
最多同時 n/2 (rounded down) chunk migrations
搬移的過程是先複製一份過去再切換,期間所有讀寫依然在原shard。
Jumbo Chunk
chunk size 預設最大為64(MB), 滿了會自動split, 若無法split的就是jumbo chunk
自動被標注,不能被移動,不會被Balance,可以被手動拆分

Application & Server Administration (DBA Only)

概述

加起來大概會出20題基本上這部分就是背多分,內容繁雜瑣碎,把相關參數都背起來就對了。CFG File 能熟讀就熟讀Command Line Mapping 也要讀懂,某些參數對應需要搞清楚
例如開啟auth在CFG裡面需要設定security.authorization : enabled
而透過mongod則是使用 mongod --auth

Configuration :

CFG 基本參數 
systemLog:
destination: file
path: "/var/log/mongodb/mongod.log"
storage:
dbPath: /data/db
processManagement:
fork: true
// 需要有logpath才能設定fork
net:
bindIp: localhost
port: 27017

啟用 Authorization (Authentication)
security:
authorization: enabled
// 使用authorization等同開啟authentication, 使用內建的SCRAM-SHA-1
// localhost expection : 能使用local連線, 建立"一個"使用者帳號
密鑰 Key Generation
主要使用openSSL, key的長度位於6~1024字元
openssl rand -base64 (6~1024) > mongodb-keyfile
openssl x509 -in client.pem -inform PEM -nameopt RFC2253 -text
// in 輸入檔案, inform 檔案格式, text 內容, nameopt 列印方式
啟用 TLS (SSL)
// 4.0版以前是SSL, 4.2版以後為TLS
net:
tls:
mode: requireTLS
// 模式差別要搞清楚, requireTLS, preferTLS, allowTLS, disabled
certificateKeyFile:
// 同時包含TLS / SSL證書和mongo外殼密鑰的文件。
CAFile:
// 包含來自證書頒發機構的根證書鏈的文件。
clusterFile:
// -- tlsAllowInvalidCertificates 讓不合法的tls連線
啟用 X.509 Authentication (需同時啟用TLS)
net:
authenticationDatabase: '$external'
authenticationMechanism: MONGODB-X509
// 啟用X.509等同開啟authorization
啟用 Replicaset 之間的 Authentication (需同時啟用TLS)
security:
keyFile: /
clusterAuthMode: keyFile / x509
啟用 Encryption at Rest
//
僅支援 WiredTiger, 共用Master Key, 每個資料庫有獨立的data key
security:
enableEncryption: true
encryptionKeyFile:
kmip:
serverName:
RotateMasterKey:
啟用 Audit
auditLog:
destination: file / syslog / console
format: JSON / BSON
path: /
filter: '{ atype: { $in: [ "createCollection", "dropCollection" ] }, "param.ns": /^test\\./ } }'
// 預設不紀錄DML (CRUD),設定atype為authCheck才能紀錄
// auditAuthorizationSuccess為true,才紀錄所有DML
// 如果是false只記錄auth失敗
// atype: authenticate, authCheck, createCollection, createIndex, createUser, createRole, replSetReconfig, shardCollection
啟用 Log Rotate
systemLog:
logAppend: 預設 false
//mongod重啟後是否繼續寫入同樣log
logRotate: 預設 rename
//開啟新的log檔案
security:
redactClientLogData:
// Log Redaction:

Authentication :

驗證方式  1. Authenticate after Connecting to the Shell
use admin
db.auth('name','password')
2. Authenticate when Connecting to the Shell
mongo --username 'name' --password 'password' --authenticationDatabase admin
// 這邊會考很多變形用法,多一個參數行不行,少一個參數會怎樣。
// 少一行 use admin 會怎樣, 少一個 authenticationDatabase 會怎樣
// 最好自己多作嘗試搞懂

Authentication 類型
SCRAM-SHA-1/256, X.509 => 社區版
clusterAuthMode : x509, 需要TLS
MongoDB-CR, 舊的方法已停用,只有在低版本相容時使用
LDAP, Kerberos => 企業版
LDAP 不使用admin db, 改使用$external
Kerberos => 使用kinit
建立user使用 $external

Authorization :

這邊大概是最難記的,在MongoDB裡面多建立幾次帳號/權限會懂的比較快。
權限組成

User, Role, Roles(Built-in Roles), Resource
User
create user=>userName, pwd, roles (role, db)
//如果role不指定db則是當前db
//roles 由 role + db(resource)
//如果是$external database, 不需要密碼
Role
由privileges與roles(inherited)組合而成
Privilege
由action與resource組合而成
//resource : {db:"", collection:""}, ""代表不指定,等同所有
Roles
由role與db組合而成
Resource
由db與privileg組合而成

Built-In Roles:
Database User Roles

read, readWrite (通常指定特定的資料庫,只能連到該資料庫)
Database Administration Roles
dbOwner = dbAdmin + userAdmin + readWrite
userAdmin : 只能管理資料庫下的使用者, 常見給DBA
dbAdmin : 管理資料庫物件, (通常使用dbAdminAnyDatabase)
//以下只有admin資料庫才有
Cluster Administration Roles

clusterAdmin, clusterManager (管理集群用), clusterMonitor, hostManager
Backup and Restoration Roles
backup, restore
All-Database Roles
readAnyDatabase, readWriteAnyDatabase, userAdminAnyDatabase, dbAdminAnyDatabase
Superuser Roles
root : all roles
Internal Role
__system : 內部使用,全部權力,但不該開出來
User-defined roles
指定名稱,權限,或是繼承某些權限
取得權限
db.getUser("caspar",{ showPrivileges:1})
//showPrivileges //showCredentials
db.getRole( "userAdminAnyDatabase", {showPrivileges:true} );
//showPrivileges //showBuiltinRoles
db.getRoles( { "showPrivileges": true, showBuiltinRoles: true } )
//showPrivileges //showBuiltinRoles
修改權限
db.updateRole()
db.grantPrivilegesToRole()
// role, privileges (resource, action)
db.grantRolesToRole()
// 把role繼承某個role, 會出現roles[], ingeritedRoles[]兩個欄位
移除權限
db.revokePrivilegesFromRole
// role, privileges (resource, action)

Database Profiler

觀念簡單,常考會收集正在執行的指令,包含CRUD, 管理, 維護等語法,並且結果存在 system.profile預設是關閉收集不紀錄
// setProfilingLevel (0) : 不紀錄
收集紀錄超過slowms的指令
// setProfilingLevel (1) : slowms預設100
// setProfilingLevel(1, { slowms: 20 }) : 指定slowms 20
收集紀錄全部指令
// setProfilingLevel (2)

Log Management:

日誌管理相關資訊,有空加減看一下日誌讀取
方法一:db.adminCommand({ "getLog": "global" })
方法二:tail -f /data/db/mongod.log
設定日誌等級
db.setLogLevel(0, "index")
//從-1~5, 0是預設, 1~5是debug
db.setLogLevel(-1, "query")
//可以看到query log, 但是必需屬於slow operation
//進階設定 logComponentVerbosity 調整不同參數
日誌格式
"t": <Datetime>, // timestamp
"s": <String>, // severity
"c": <String>, // component
"ctx": <String>, // context
"id": <String>, // unique identifier
"msg": <String>, // message body
"attr": <Object> // additional attributes (optional)
"tags": <Array of strings> // tags (optional)
"truncated": <Object> // truncation info (if truncated)
"size": <Integer> // original size of entry (if truncated)
Context:
String representing the name of the thread issuing the log statement.
Severity:
F Fetal, E Error, W warning, I info, D1~D5 debug
Components:
ACCESS, COMMAND, CONTROL, FTDC, INDEX, QUERY, UPDATE, WRITE, NETWORK …

Diagnostics and Debugging

//查詢資料庫現狀 - Long-running operations
db.currentOp()
//刪除特定op_id
db.killOp()
//提供給mongodb support 處理 issue
diagnostic.data

--

--

Caspar Chang

具有十年以上的資料庫開發與維運管理經驗,現任職於 MongoDB Taiwan 解決方案架構師