目錄html
本文的內容是基於 MongoDB 4.0
的。 參考於 MongoDB 4.0
官方文檔。mysql
MongoDB 是由C++
語言編寫的,是一個基於分佈式文件存儲的開源數據庫系統。屬於 nosql
數據庫。MongoDB 數據庫中最小的數據單元是文檔,它是由 key 和 value 組成的數據結構, MongoDB 文檔相似於 JSON 對象。value 的值能夠是數組、字符串、數值、文檔。linux
支持多語言、高性能、豐富的查詢語言、高可用性、可擴展、支持多個儲存引擎、高效存儲二進制大對象 (好比照片和視頻)。git
4.0版本的優點:github
MongoDB 與 mysql 對比sql
SQL Terms/Concepts | MongoDB Terms/Concepts |
---|---|
database | database |
table | collection |
row | document or BSON document |
column | field |
index | index |
table joins | embedded documents and linking |
primary keySpecify any unique column orcolumn combination asprimary key. | primary keyIn MongoDB, the primary key isautomatically set to the _id field. |
aggregation (e.g. group by) | aggregation pipelineSee the SQL to Aggregation MappingChart. |
位置查詢的移動類APP,儲存數據結構易變化的數據。mongodb
電商後臺(商品更新記錄,會員天天虛擬幣餘額(定時獲取),會員帳號信息,訂單信息等等) 。docker
儲存用戶發表的朋友圈。shell
儲存直播行業的用戶信息、禮物信息以及日誌等信息,同時可經過豐富的聚合查詢來進行業務分析。數據庫
MongoDB 有三大儲存引擎,分別是 WiredTiger 、In-Memory 、MMAPv1。
WiredTiger
是MongoDB 3.2 中的默認儲存引擎,是多線程的,它適合大多數的工程場景,支持文檔級別的併發,壓縮等功能,官方建議使用該儲存引擎。在3.6版本後 WiredTiger 每60s將數據寫入到磁盤,在下一次寫入成功前,本次節點的數據仍然有效。當發生故障時,MongoDB 能夠從最後的一次成功寫入進行恢復。
In-Memory
In-Memory 只能在 企業版本中使用,它不是將文檔儲存在磁盤上,而是保存在內存上,實現更快的檢索。
MMAPv1
是 MongoDB 3.0 以前的更早版本的默認儲存引擎。從 MongoDB 4.0 開始官方不推薦使用該引擎。
MongoDB 如何保證數據的完整性 ,經過檢查點(也就是每60s寫入一次)和事務性日誌來確保數據的完整性和持久性。
咱們接下來介紹下 咱們經常使用的引擎 WiredTiger 的相關信息:
WiredTiger 日誌
日誌功能默認啓用。 WiredTiger 日誌會在檢查點之間保留全部數據修改。若是 MongoDB 在檢查點之間退出,它將使用日誌重播自上一個檢查點以來修改的全部數據。
咱們能夠禁用日誌功能,來減小開啓日誌功能所須要的開銷。可是這樣也就意味着,當MongoDB 非正常退出時,最後一個檢查點以後的數據將會都丟失。
WiredTiger 日誌默認啓用數據壓縮。此日誌非 MongoDB 的日誌文件,而是 WiredTiger 日誌,經過該日誌咱們能夠獲取上一個檢查點以後發生的操做。
使用日誌功能,恢復流程:
- 先查看數據文件查找最後一個檢查點的位置的標識符。
- 在日誌文件中搜索與檢查點標識符相匹配的記錄。
- 獲取從上一個檢查點以後的操做。
日誌文件會在 dbpath
下以 journal
命名的子目錄下,以形如 WiredTigerLog.0000000001
格式的文件名儲存。
WiredTiger 的最小日誌記錄大小爲128個字節。若是日誌記錄是128字節或更小,WiredTiger 不會壓縮該記錄。
日誌文件包含每一個寫操做的記錄。每條記錄都有惟一的標識符。MongoDB 將 WiredTiger 配置爲對日記數據使用snappy壓縮。
MongoDB 的 WiredTiger 日誌文件的最大大小限制大約爲100 MB。一旦文件超過該限制,WiredTiger就會建立一個新的日誌文件。
WiredTiger 會自動刪除舊日誌文件,以僅維護從上一個檢查點恢復所需的文件。
數據壓縮
使用 WiredTiger,MongoDB支持對全部集合和索引進行壓縮。壓縮是以 CPU 爲代價來減小磁盤的使用。默認狀況下,WiredTiger 會對數據進行壓縮。在大多數狀況下,默認的壓縮設置以及平衡了 儲存空間和 CPU 使用率。
內存使用
從 MongoDB 3.4開始,默認WiredTiger內部緩存大小取值是取如下兩個值中的較大者:
例如 一個主機的內存是 4G ,那麼取值爲 1.5G, 若是是 1.25G,那麼取值爲256M。
調整 內存使用,須要使用 storage.wiredTiger.engineConfig.cacheSizeGB
內部緩存和 --wiredTigerCacheSizeGB
。 兩個參數。
Mongodb 建議使用 YAML 格式的配置文件,也支持 ini 格式的配置文件。
bind_ip=0.0.0.0 #綁定的 ip,若是是 0.0.0.0 就是綁定本地全部ip port=27037 # 監聽端口號,默認爲27017。 dbpath=/opt/mongodb/data/ # 數據儲存的位置 logpath=/opt/mongodb/logs/mongodb.log # 日誌儲存的位置 pidfilepath=/opt/mongodb/logs/mongod.pid # pid文件儲存的位置 logRotate= rename/reopen #3.0.0版中的新功能。能夠取值爲 rename 或 reopen: rename 重命名日誌文件。每次重啓都會重命名日誌文件。 reopen 按照典型的 Linux/Unix 日誌循環行爲關閉並從新打開日誌文件。使用 reopen 使用的 Linux/Unix logrotate的工具時,以免日誌的丟失。 若是指定 reopen,則還必須使用 logappend logappend= true # 當 MongoDB 實例從新啓動時,將新的日誌內容添加到現有日誌文件的末尾。若是沒有此選項,MongoDB 將備份現有日誌並建立新文件。 listenBacklog= 128 #偵聽隊列中能夠存在的最大鏈接數。取決於 /proc/sys/net/core/somaxconn 這個值 maxConns= 500 #最大鏈接數 directoryperdb=true # 將每一個數據庫的數據分目錄儲存 # replS=fymongodb # 在配置副本集的時候設置副本集名稱,單節點的不須要設置該參數 auth=true # 開啓登陸驗證 fork=true # 後臺運行 journal=true # 開啓預寫日誌
systemLog: # 日誌配置 日誌切割見文章:https://dwz.cn/VPxxTf38 destination: file path: "/opt/mongodb/logs/mongodb.log" logAppend: true timeStampFormat: "iso8601-local" # 日誌使用的時間格式,默認爲iso8601-local,可選值 ctime、iso8601-utc、iso8601-local。 # 還有更詳細的組件、控制、索引、回滾等日誌的輸出等級配置見官網 processManagement: # 進程控制配置 fork: true #後臺以守護進程運行 pidFilePath: "/opt/mongodb/logs/mongod.pid" # pid 文件路徑 timeZoneInfo: "/usr/share/zoneinfo/Asia/Shanghai" #數據庫使用的時區,未設置使用系統默認 net: bindIp: "0.0.0.0" # 綁定的ip,127.0.0.1/0.0.0.0/::,0.0.0.0(綁定到全部IP地址),與bindIpAll 參數是互斥的 bindIpAll: <boolean> # 是否綁定本地全部ip,與bindIp 參數是互斥的 port: 27017 # 綁定的端口,默認值27017 maxIncomingConnections: 500 # 最大同時鏈接數,默認值爲65536 wireObjectCheck: <boolean> # 對客戶端的寫入進行驗證,會有較小的性能影響,默認爲 True. ssl: # ssl 的詳細配置 sslOnNormalPorts: <boolean> # deprecated since 2.6 certificateSelector: <string> clusterCertificateSelector: <string> mode: <string> PEMKeyFile: <string> PEMKeyPassword: <string> clusterFile: <string> clusterPassword: <string> CAFile: <string> clusterCAFile: <string> CRLFile: <string> allowConnectionsWithoutCertificates: <boolean> allowInvalidCertificates: <boolean> allowInvalidHostnames: <boolean> disabledProtocols: <string> FIPSMode: <boolean> compression: compressors: <string> # 通訊壓縮器,可取值 snappy、zlib(版本3.6+可用)、disabled,默認值snappy, serviceExecutor: <string> #線程執行模型 3.6+版本使用,默認值: synchronous,可取值 adaptive、synchronous storage: # 數據儲存配置 dbPath: "/opt/mongodb/data/" # mongod 數據儲存的位置 indexBuildRetry: <boolean> # mongod 在下次啓動從新構建不完整索引,默認爲True,不能與replication.replSetName 一塊兒使用 repairPath: <string> journal: enabled: <boolean> # 是否開啓journal日誌在64位系統默認爲 true,在32位系統爲false,建議啓用 commitIntervalMs: <num> # 設置日誌儲存到磁盤的間隔時間,默認爲100毫秒,能夠設置爲1-500. directoryPerDB: <boolean> # 是否開啓分目錄儲存數據,默認值爲 False, syncPeriodSecs: <int> # MongoDB經過fsync操做將數據儲存到磁盤的時間,默認值 60,單位秒,不建議更改此值 engine: <string> # 儲存引擎,默認值wiredTiger,MongoDB不推薦使用MMAPv1存儲引擎 wiredTiger: # wiredTiger 儲存引擎配置 engineConfig: cacheSizeGB: <number> # 內部緩存內存大小,默認是取50% of (RAM - 1 GB)和256 MB的最大者,可設置值爲 0.25G-10000G,若是一臺服務器有多個MongoDB實例或者運行在docker中,須要設置該值,避免多臺實例佔用完系統的全部內存,和mongodb在容器中獲取不到實際內存大小。 journalCompressor: <string> # WiredTiger日誌數據的壓縮類型 默認值 snappy,可選值 none、snappy、zlib. directoryForIndexes: <boolean> # 將index儲存到一個目錄,並軟鏈接到數據目錄,默認值爲False, collectionConfig: blockCompressor: <string> # 集合數據的壓縮類型,默認值 snappy,可選值 none、snappy、zlib. indexConfig: prefixCompression: <boolean> # 啓用的索引的前綴壓縮 默認值爲 true inMemory: # inmemory 引擎配置 engineConfig: inMemorySizeGB: <number> # 設置 inmemory 引擎分配的最大內存默認爲50%(RAM - 1 GB) security: keyFile: <string> #儲存密鑰文件的路徑,用於存儲MongoDB實例用於在分片集羣或副本集中相互進行身份驗證的共享密鑰 clusterAuthMode: <string> #集羣驗證模式 authorization: <string> #啓用基於角色的訪問控制,可選值enabled、disabled默認值爲禁用,建議開啓 operationProfiling: # 開啓慢查詢 mode: <string> # 慢查詢模式 可選值,off、slowOp、all,默認值off。建議開啓 slowOpThresholdMs: <int> # 閾值,默認值100 毫秒 slowOpSampleRate: <double> # 隨機採集慢查詢的百分比值,sampleRate 值默認爲1,表示都採集,0.42 表示採集42%的內容 replication: # 複製配置,副本集,indexBuildRetry與副本集互斥 Oplog 具體見文章: https://dwz.cn/98tUpUfu oplogSizeMB: <int> # Oplog 的最大大小,單位Mb , replSetName: <string> # 副本集名稱 secondaryIndexPrefetch: <string> # 僅適用於mmapv1 存儲引擎 enableMajorityReadConcern: <boolean> # 開啓 Majority 讀取,默認爲 True. sharding: # 分片 clusterRole: <string> # 設置該實例角色,可選值configsvr、shardsvr archiveMovedChunks: <boolean> # 遷移過程塊不保存 從3.2版本開始,默認爲 False
MongoDB 示例 ini 配置文件
github地址 : https://github.com/tobewithyou1996/LinuxGuide/blob/master/MongoDB/mongodb.conf
MongoDB 示例 YAML 配置文件
github地址 : https://github.com/tobewithyou1996/LinuxGuide/blob/master/MongoDB/mongodb.yaml
cd /tmp && wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-4.0.8.tgz tar -zxf mongodb-linux-x86_64-4.0.8.tgz mv mongodb-linux-x86_64-4.0.8 /opt/mongodb mkdir /opt/mongodb/{data,logs} touch /opt/mongodb/mongodb.conf useradd mongodb # 添加配置文件 cat <<EOF >> /opt/mongodb/mongodb.conf bind_ip=0.0.0.0 port=27037 dbpath=/opt/mongodb/data/ logpath=/opt/mongodb/logs/mongodb.log pidfilepath=/opt/mongodb/logs/mongod.pid logRotate= reopen logappend= true listenBacklog= 128 maxConns= 500 directoryperdb=true noauth=true fork=true journal=true profile=2 slowms=200 EOF # 更改 mongodb 的目錄全部者 chown -R mongodb:mongodb /opt/mongodb # 啓動 MongoDB 服務 mongod -f /opt/mongodb/mongodb.conf # 若是當前登陸的用戶是 root 須要指定用戶 mongodb 啓動。 su - mongodb -c "/opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf" # 添加環境變量 echo "export PATH=$PATH:/opt/mongodb/bin" >>/etc/profile source /etc/profile # 暫停 MongoDB 服務 /opt/mongodb/bin/mongod --shutdown --dbpath /opt/mongodb/data #`mongod` 是服務端 #`mongo` 是客戶端鏈接工具。
建立管理員用戶:建立管理員用戶 admin ,密碼 9toc7ttpji8 ,擁有最高級權限。
> use admin switched to db admin > db.createUser({ user: "admin", pwd: "9toc7tpji8", roles: [{ role: "root", db: "admin" }] }) Successfully added user: { "user" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] }
建立普通用戶 : 在數據庫 djx, 建立用戶名爲 dd ,密碼爲 djx@123456,對數據庫 djx 具備讀寫權限的用戶。
> use djx switched to db djx > db.createUser({user: "dd",pwd: "djx@123456",roles:[{"role":"readWrite","db":"djx"}]}); Successfully added user: { "user" : "dd", "roles" : [ { "role" : "readWrite", "db" : "djx" } ] }
詳細配置見本文後半部分的 MongoDB用戶認證和 MongoDB 角色。
將 mongodb.conf
文件中的 noauth=true
替換爲 auth=true
。
sed -i s/noauth/auth/g /opt/mongodb/mongodb.conf
並重啓MongoDB
才能生效
cat <<EOF >>/usr/lib/systemd/system/mongodb.service [Unit] Description= mongodb service manager [Service] # Other directives omitted # (file size) LimitFSIZE=infinity # (cpu time) LimitCPU=infinity # (virtual memory size) LimitAS=infinity # (locked-in-memory size) LimitMEMLOCK=infinity # (open files) LimitNOFILE=64000 # (processes/threads) LimitNPROC=64000 Type=forking User=mongodb Group=mongodb PIDFile=/opt/mongodb/logs/mongod.pid ExecStart= /opt/mongodb/bin/mongod -f /opt/mongodb/mongodb.conf ExecStop= /opt/mongodb/bin/mongod --shutdown --dbpath /opt/mongodb/data Restart=always [Install] WantedBy=multi-user.target EOF systemctl status mongodb # 查看 mongodb 狀態 systemctl start mongodb # 啓動 mongodb systemctl enable mongodb # 將 mongodb 添加到開機自啓 systemctl stop mongodb # 暫停 mongodb
若是是在生產環境中使用,查看 MongoDB 生產環境筆記 。
MongoDB 默認鏈接端口 27017 。
指定端口:
mongo --port 27037
指定端口和主機
mongo --host mongodb0.example.com:28015
具備認證的 MongoDB 實例
mongo --host mongodb://alice@mongodb0.examples.com:28015/?authSource=admin 或者使用 --username <user> --password, --authenticationDatabase <db>
鏈接到 MongoDB 的副本集
mongo mongodb://mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017/?replicaSet=replA 或者是 mongo --host replA/mongodb0.example.com.local:27017,mongodb1.example.com.local:27017,mongodb2.example.com.local:27017
使用 TLS/SSL 鏈接
在鏈接後面加上&ssl = true 便可
MongoDB 設置鏈接池的鏈接數
最大鏈接數 &maxPoolSize=<integer>
mongo "mongodb://root:xxxxxx@dds-bpxxxxxxxx-pub.mongodb.rds.aliyuncs.com:3717,dds-bpxxxxxxxx-pub.mongodb.rds.aliyuncs.com:3717/admin?replicaSet=mgset-xxxxxx&maxPoolSize=10"
最小鏈接數 &minPoolSize=<integer>
db.version() # 查看數據庫版本 db #查看當前所在的數據庫 db.help() # 幫助 use databasename # 切換數據庫 show dbs # 列出當前用戶可用的全部數據庫 db.getSiblingDB() #不切換數據庫,在別的數據庫執行程序 db.stats() # 查看當前所在數據庫的狀態 db.getMongo() # 查看當前 MongoDB 鏈接路徑 use newdatabasename # 建立數據庫 db.dropDatabase()# 刪除當前所在數據庫 show profile # 打印最近執行花費1毫秒或更長時間的五個最近的操做。 db.serverStatus().connections # 查詢當前鏈接數,以及最大鏈接數。 use admin , db.runCommand({currentOp: 1, $all:[{"active" : true}]}) # 查詢每一個鏈接對應的來源IP地址。 db.currentOp() # 查看 MongoDB 當前正在執行的操做。 db.killOp(opid) # 終止請求執行 db.fsyncLock()# 刷新寫入磁盤並鎖定數據庫 db.fsyncUnlock()# 解鎖 db.serverStatus().storageEngine # 顯示當前 MongoDB 所使用的儲存引擎 db.runCommand( { "connPoolStats" : 1 } ) # 查詢數據庫當前的鏈接信息 db.runCommand({logRotate:1}) # mongodb 日誌切割
show collections # 查看當前數據庫已有的集合 db.createCollection('name')# 建立集合 db.collectionname.drop()# 刪除集合 db.collectionname.dataSize(); # 查詢集合的大小 db.collectionname.find({key:value}) # 查詢集合的數據包含 key 和 value。 db.collectionname.find() # 查詢整個集合,每次只會顯示部分數據,經過輸入 it 來查看其它數據。 db.collectionname.renameCollection("newname")# 集合重命名 db.collectionname.stats()# 查詢集合的狀態
db.collectionname.insert({key:value})# 添加數據,collectionname指的是集合名稱。 db.collectionname.count() #查詢集合有多少文檔數量 db.collectionname.remove({'key':value}) # 刪除集合collectionname 中 key='key',value=value 的 文檔。
show users # 當前數據庫的用戶列表 show roles # 當前數據庫的全部角色列表,包括用戶定義和內置角色。 db.auth(username,pwd) # 登陸驗證 db.changeUserPassword(username, password) # 更改用戶密碼 db.createUser() # 建立用戶 db.dropUser(username) # 刪除用戶 db.dropAllUsers() # 刪除全部的用戶 db.getUser(username) # 查詢用戶 db.getUsers() # 返回當前數據庫全部的用戶 db.removeUser(username) # 刪除用戶 db.grantRolesToUser(username, roles, writeConcern) # 給用戶受權新的權限 db.revokeRolesFromUser() # 刪除用戶受權的權限 db.updateUser() # 更新用戶信息,該方法會替代用戶原有的全部值。
MongoDB 默認的認證是 SCRAM
MongoDB 建立用戶命令詳解:
# 建立用戶 db.createUser( { user: "用戶名", pwd: "密碼", customData: { < any information > }, roles: [ { role: "<role>", db: "<database>" } | "<role>", ... ], authenticationRestrictions: [ { clientSource: ["<IP>" | "<CIDR range>", ...] serverAddress: ["<IP>" | "<CIDR range>", ...] }, ... ], mechanisms: [ "<SCRAM-SHA-1|SCRAM-SHA-256>", ... ], passwordDigestor: "<server|client>" } )
字段 | 數據類型 | 描述 |
---|---|---|
user | string | 用戶名 |
pwd | string | 密碼 |
customData | document | 可選的,任意信息,能夠是用戶的id |
roles | array | 受權用戶的角色。能夠指定一個空數組[] 來建立沒有角色的用戶。 |
authenticationRestrictions | array | 可選,3.6版本中的新功能,容許服務器能夠接受用戶的IP地址和服務器地址,和CIDR 範圍 |
mechanisms | array | 可選的,4.0版本的功能,指定用於建立SCRAM用戶憑據的特定SCRAM機制,可選值爲 SCRAM-SHA-1 、SCRAM-SHA-256 |
passwordDigestor | string | 可選的,服務端和客戶端是否記錄密碼,默認爲 server ,可選 server 、client。 |
示例:
建立管理員用戶
use admin db.createUser( { user: "myUserAdmin", pwd: "abc123", roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ] } )
建立普通用戶 myTester ,密碼爲 xyz123 ,對庫 test 有可讀可寫的權限 和 對庫 reporting 有可讀的權限。
use test db.createUser( { user: "myTester", pwd: "xyz123", roles: [ { role: "readWrite", db: "test" }, { role: "read", db: "reporting" } ] } )
MongoDB 包含如下客戶端的角色 :
基本權限: read(可讀)、readWrite(可讀可寫)。
管理員權限:dbAdmin(管理員)、userAdmin(當前數據庫上建立和修改角色和用戶的功能)、dbOwner (數據庫全部者,包含readWrite
, dbAdmin
,userAdmin
角色)
備份和還原權限:backup(提供備份數據所須要的最小權限)、restore(提供從不包含system.profile
集合數據的備份還原數據所需的權限)
針對全部數據庫的權限:readAnyDatabase、readWriteAnyDatabase、`userAdminAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase,
超級管理員: root (包含readWriteAnyDatabase, dbAdminAnyDatabase,userAdminAnyDatabase, clusterAdmin,restore,和 backup)
咱們也能夠定義本身須要的角色,來實現咱們特定的權限規則。咱們能夠建立角色,並賦予其權限,詳細設置見官網。
因爲文章篇幅太長,因此單獨放到一個文章裏了。
MongoDB 備份與還原 mongodump、mongorestore
因爲文章篇幅太長,因此單獨放到一個文章裏了。
MongoDB調優-查詢優化-MongoDB Profiler
db.repairDatabase
命令。注:緊急狀況下請使用
db.runCommand({compact: 'oplog.rs'})
命令清理日誌。