上一篇文章介紹了MongoDB的yum安裝方式、配置文件、建立用戶等基礎知識,本篇介紹MongoDB的源碼安裝以及複製集相關!
html
1、使用源碼安裝MongoDBlinux
官網下載地址:http://www.mongodb.org/downloads git
本次實驗使用的mongodb版本是mongodb-linux-x86_64-rhel62-3.4.2.tgz 安裝步驟以下: 一、解壓並設置可執行文件 #tar xf mongodb-linux-x86_64-rhel62-3.4.2.tgz #mv mongodb-linux-x86_64-rhel62-3.4.2 /usr/local/mongodb #將解壓的包拷貝到指定目錄 MongoDB 的可執行文件位於bin目錄下,因此能夠將其添加到 PATH 路徑中: #vi /etc/profile export PATH=$PATH:/usr/local/mongodb/bin 加載/etc/profile使定義生效 #. /etc/profile 查看mongodb的bin文件 #which mongo /usr/local/mongodb/bin/mongo 查看mongodb的版本號 #mongo --version MongoDB shell version v3.4.2 git version: 3f76e40c105fc223b3e5aac3e20dcd026b83b38b OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013 allocator: tcmalloc modules: none build environment: distmod: rhel62 distarch: x86_64 target_arch: x86_64 二、建立數據庫目錄 MongoDB的數據存儲在data目錄的db目錄下,可是這個目錄在源碼安裝過程不會自動建立,因此須要 手動建立data目錄,並在data目錄中建立db目錄。如下實例中咱們將data目錄建立於根目錄下(/)。 注意:/data/db 是MongoDB默認的啓動的數據庫路徑(--dbpath)。也能夠單獨使用一塊盤掛載到/data/db 目錄,這樣數據就單獨存放了,必定程度提升了安全性! #mkdir /data/db -p 三、啓動mongodb 注意:若是你的數據庫目錄不是/data/db,能夠經過 --dbpath 來指定 #mongod 2017-02-14T11:28:58.380+0800 I CONTROL [initandlisten] MongoDB starting : pid=9803 port=27017 dbpath=/data/db 64-bit host=template 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] db version v3.4.2 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] git version: 3f76e40c105fc223b3e5aac3e20dcd026b83b38b 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] allocator: tcmalloc 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] modules: none 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] build environment: 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] distmod: rhel62 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] distarch: x86_64 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] target_arch: x86_64 2017-02-14T11:28:58.381+0800 I CONTROL [initandlisten] options: {} 2017-02-14T11:28:58.432+0800 I STORAGE [initandlisten] 2017-02-14T11:28:58.432+0800 I STORAGE [initandlisten] ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine 2017-02-14T11:28:58.432+0800 I STORAGE [initandlisten] ** See http://dochub.mongodb.org/core/prodnotes-filesystem 2017-02-14T11:28:58.432+0800 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=426M,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0), 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended. 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. 2017-02-14T11:28:58.494+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'. 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] ** We suggest setting it to 'never' 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] ** WARNING: soft rlimits too low. rlimits set to 14867 processes, 65536 files. Number of processes should be at least 32768 : 0.5 times number of files. 2017-02-14T11:28:58.495+0800 I CONTROL [initandlisten] 2017-02-14T11:28:58.501+0800 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory '/data/db/diagnostic.data' 2017-02-14T11:28:58.511+0800 I INDEX [initandlisten] build index on: admin.system.version properties: { v: 2, key: { version: 1 }, name: "incompatible_with_version_32", ns: "admin.system.version" } 2017-02-14T11:28:58.511+0800 I INDEX [initandlisten] building index using bulk method; build may temporarily use up to 500 megabytes of RAM 2017-02-14T11:28:58.512+0800 I INDEX [initandlisten] build index done. scanned 0 total records. 0 secs 2017-02-14T11:28:58.513+0800 I COMMAND [initandlisten] setting featureCompatibilityVersion to 3.4 2017-02-14T11:28:58.513+0800 I NETWORK [thread1] waiting for connections on port 27017 根據提示設置ulimit和/sys/kernel參數: #echo never > /sys/kernel/mm/transparent_hugepage/enabled #echo never> /sys/kernel/mm/transparent_hugepage/defrag #vi /etc/security/limits.conf * soft nofile 65535 * hard nofile 65535 * soft nproc 32768 * hard nproc 32768 注:設置好以後,不會當即生效,須要exit退出shell,而後從新鏈接生效。從新啓動mongod進程,警告 沒有那麼多了,可是還會提示以下幾個: ** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine ** WARNING: Access control is not enabled for the database. ** WARNING: You are running this process as the root user, which is not recommended 其中第一個和第二個比較容易解決,在配置文件添加參數就ok,第三個是提示不容許使用root用戶啓動 mongod進程,上一篇yum安裝的沒有遇到相似問題,是由於yum安裝以後,利用啓動腳本啓動的mongod進 是普通用戶。 四、以普通用戶身份啓動mongod 建立一個普通用戶mongod #useradd -r -m -s /bin/bash mongod #建立一個普通系統用戶 修改權限 #chown mongod.mongod /data/ -R 建立mongodb日誌目錄並修改權限 #mkdir /var/log/mongodb/ #chown mongod.mongod /var/log/mongodb 建立配置文件mongod.conf #vi /etc/mongod.conf # mongod.conf # for documentation of all options, see: # http://docs.mongodb.org/manual/reference/configuration-options/ # where to write logging data. systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log logRotate: rename # Where and how to store data. storage: dbPath: /data/db journal: enabled: true engine: wiredTiger # mmapv1: # wiredTiger: # how the process runs processManagement: fork: true # fork and run in background pidFilePath: /usr/local/mongodb/mongod.pid # location of pidfile # network interfaces net: port: 27017 bindIp: 10.0.18.149 # Listen to local interface only, comment to listen on all interfaces. http: enabled: false RESTInterfaceEnabled: false #setParameter: # enableLocalhostAuthBypass: true security: authorization: enabled #operationProfiling: #replication: #sharding: ## Enterprise-Only Options #auditLog: #snmp: 保存退出,以上配置文件開啓了authorization功能! 啓動命令: #su mongod -c "/usr/local/mongodb/bin/mongod -f /etc/mongod.conf" about to fork child process, waiting until server is ready for connections. forked process: 11274 child process started successfully, parent exiting 查看端口 #netstat -tunlp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1026/sshd tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 1103/master tcp 0 0 10.0.18.149:27017 0.0.0.0:* LISTEN 11274/mongod tcp 0 0 :::22 :::* LISTEN 1026/sshd tcp 0 0 ::1:25 :::* LISTEN 1103/master 查看進程是不是mongod啓動的 #ps aux | grep mongod mongod 11274 0.8 1.8 341288 35872 ? Sl 16:03 0:01 /usr/local/mongodb/bin/mongod -f /etc/mongod.conf root 11302 0.0 0.0 103244 836 pts/1 S+ 16:06 0:00 grep mongod 注:若是想在啓動的時候開啓認證,使用命令:mongod --dbpath /data/db --port 20000 --auth 若是配置以普通用戶啓動mongod進程,也須要修改/etc/security/limit.d/90-nproc.conf #vi /etc/security/limits.d/90-nproc.conf ##添加以下2行 * soft nproc 32768 * hard nproc 32768 注意:能夠用killall mongod 來中止mongodb服務;可是不能用kill -9 來中止,會損壞服務器;還可 以用ps aux| grep mongod命令來查看PID,再用kill -2 PID中止服務!
2、配置MongoDB的複製(主從複製)web
一、什麼是複製mongodb
MongoDB複製是將數據同步在多個服務器的過程。複製提供了數據的冗餘備份,並在多個服務器上存儲數據副本,提升了數據的可用性, 並能夠保證數據的安全性。複製還容許您從硬件故障和服務中斷中恢復數據。shell
Mongodb複製集由一組Mongod實例(進程)組成,包含一個Primary節點和多個Secondary節點,Mongodb Driver(客戶端)的全部數據都寫入Primary,Secondary從Primary同步寫入的數據,以保持複製集內全部成員存儲相同的數據集,提供數據的高可用。數據庫
二、配置複製的優勢centos
保障數據的安全性緩存
數據高可用性 (24*7)安全
災難恢復
無需停機維護(如備份,重建索引,壓縮)
分佈式讀取數據
三、MongoDB複製原理
官方說明: The minimum recommended configuration for a replica set is a three member replica set with three data-bearing members: one primary and two secondary members
mongodb的複製至少須要兩個節點。其中一個是主節點,負責處理客戶端請求,其他的都是從節點,負責複製主節點上的數據。mongodb各個節點常見的搭配方式爲:一主一從、一主多從。
主節點記錄在其上的全部操做oplog,從節點按期輪詢主節點獲取這些操做,而後對本身的數據副本執行這些操做,從而保證從節點的數據與主節點一致,以下圖:
大體流程是:客戶端從主節點讀取數據,在客戶端寫入數據到主節點時,主節點與從節點進行數據交互保障數據的一致性。
四、配置MongoDB的主從複製(不經常使用)
主IP:10.0.18.144 從IP:10.0.18.145
注:複製集已經在大多數場合下替代了master-slave複製。若是可能的話,儘量使用複製集而不是主-從複製架構。本文旨在於爲以前遺留的主從架構提供支持,或是僅用於學習。
補充:配置主從,暫時將配置文件中的認證功能關閉-->註釋掉security.authorization: enabled 在主服務器關閉mongod進程,從新啓動以下: #killall mongod #關閉mongod進程 而後從新啓動: #su mongod -c "/usr/local/mongodb/bin/mongod --master -f /etc/mongod.conf" about to fork child process, waiting until server is ready for connections. forked process: 10430 child process started successfully, parent exiting 在從服務器關閉mongod進程,從新啓動以下: #su mongod -c "/usr/local/mongodb/bin/mongod --slave --source 10.0.18.144:27017 -f /etc/mongod.conf" about to fork child process, waiting until server is ready for connections. forked process: 14206 child process started successfully, parent exiting 這樣mongodb的主從就配置ok了。 a、在master服務器上操做 首先看下日誌 #tail /var/log/mongodb/mongod.log ……………… 2017-02-15T17:02:16.309+0800 I STORAGE [initandlisten] Scanning the oplog to determine where to place markers for truncation 2017-02-15T17:02:16.322+0800 I REPL [initandlisten] ****** 2017-02-15T17:02:16.325+0800 I NETWORK [thread1] waiting for connections on port 27017 2017-02-15T17:04:09.031+0800 I NETWORK [thread1] connection accepted from 10.0.18.145:46767 #1 (1 connection now open) 2017-02-15T17:04:09.032+0800 I NETWORK [conn1] received client metadata from 10.0.18.145:46767 conn1: { driver: { name: "MongoDB Internal Client", version: "3.4.2" }, os: { type: "Linux", name: "CentOS release 6.6 (Final)", architecture: "x86_64", version: "Kernel 2.6.32-504.el6.x86_64" } } 2017-02-15T17:04:09.045+0800 I - [conn1] end connection 10.0.18.145:46767 (1 connection now open) 2017-02-15T17:04:12.033+0800 I NETWORK [thread1] connection accepted from 10.0.18.145:46828 #2 (1 connection now open) 2017-02-15T17:04:12.034+0800 I NETWORK [conn2] received client metadata from 10.0.18.145:46828 conn2: { driver: { name: "MongoDB Internal Client", version: "3.4.2" }, os: { type: "Linux", name: "CentOS release 6.6 (Final)", architecture: "x86_64", version: "Kernel 2.6.32-504.el6.x86_64" } } 2017-02-15T17:04:12.035+0800 I - [conn2] end connection 10.0.18.145:46828 (1 connection now open) 2017-02-15T17:04:15.036+0800 I NETWORK [thread1] connection accepted from 10.0.18.145:46887 #3 (1 connection now open) 2017-02-15T17:04:15.036+0800 I NETWORK [conn3] received client metadata from 10.0.18.145:46887 conn3: { driver: { name: "MongoDB Internal Client", version: "3.4.2" }, os: { type: "Linux", name: "CentOS release 6.6 (Final)", architecture: "x86_64", version: "Kernel 2.6.32-504.el6.x86_64" } } 能夠看到已經接受了從服務器10.0.18.145的鏈接請求。 進入mongodb進行查看 #mongo --host 10.0.18.144 > db.isMaster() { "ismaster" : true, #表示是主節點 "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-02-15T09:08:01.081Z"), "maxWireVersion" : 5, "minWireVersion" : 0, "readOnly" : false, "ok" : 1 } 在主服務器建立一個庫,並插入數據,驗證從服務器是否存在 > show dbs; admin 0.000GB local 0.000GB > db.test test.test > db test > db.test.insert({"name":"ceshizhucong"}) WriteResult({ "nInserted" : 1 }) > show dbs; admin 0.000GB local 0.000GB test 0.000GB > use test switched to db test > db.test.findOne();db.test.findOne(); { "_id" : ObjectId("58a41cbda6bb67ceb5dd53c6"), "name" : "ceshizhucong" } b、在從服務器操做 #mongo --host 10.0.18.145 > db.isMaster(); { "ismaster" : false, #表示是從節點 "maxBsonObjectSize" : 16777216, "maxMessageSizeBytes" : 48000000, "maxWriteBatchSize" : 1000, "localTime" : ISODate("2017-02-15T09:19:30.163Z"), "maxWireVersion" : 5, "minWireVersion" : 0, "readOnly" : false, "ok" : 1 } > show dbs; 2017-02-15T17:23:35.795+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:755:19 shellHelper@src/mongo/shell/utils.js:645:15 @(shellhelp2):1:1 能夠看到執行show dbs命令不成功,由於不是master服務器 > db #查看當前數據庫,能夠看到test庫已經複製過來了 test > use web switched to db web > db web > db.web.insert({"name":"ceshizhucong3"})db.web.insert({"name":"ceshizhucong3"}) WriteResult({ "writeError" : { "code" : 10107, "errmsg" : "not master" } }) 也沒法插入數據,由於從服務器沒法進行寫操做! 查看從服務器日誌 #tail -f mongod.log ……………… 2017-02-15T17:29:13.730+0800 I REPL [replslave] syncing from host:10.0.18.144:27017 2017-02-15T17:29:14.732+0800 I REPL [replslave] syncing from host:10.0.18.144:27017 到這裏MongoDB的主從複製就結束了!
3、MongoDB副本集的一些特徵介紹
一、副本集特徵:
N個節點的集羣
任何節點可做爲主節點
全部寫入操做都在主節點上
自動故障轉移
自動恢復
二、Primary選舉
複製集經過replSetInitiate命令(或mongo shell的rs.initiate())進行初始化,初始化後各個成員間開始發送心跳消息,
併發起Priamry選舉操做,得到『大多數』成員投票支持的節點,會成爲Primary,其他節點成爲Secondary
三、大多數的定義
假設複製集內投票成員(後續介紹)數量爲N,則大多數爲N/2 + 1,當複製集內存活成員數量不足大多數時,整個複製集將沒法選舉出Primary,複製集將沒法提供寫服務,處於只讀狀態。以下圖:
一般建議將複製集成員數量設置爲奇數,從上表能夠看出3個節點和4個節點的複製集都只能容忍1個節點失效,從『服務可用性』的角度看,其效果是同樣的(但無疑4個節點能提供更可靠的數據存儲)
四、特殊的Secondary
正常狀況下,複製集的Seconary會參與Primary選舉(自身也可能會被選爲Primary),並從Primary同步最新寫入的數據,以保證與Primary存儲相同的數據。Secondary能夠提供讀服務,增長Secondary節點能夠提供複製集的讀服務能力,同時提高複製集的可用性。另外,Mongodb支持對複製集的Secondary節點進行靈活的配置,以適應多種場景的需求
五、Arbiter 仲裁節點
Arbiter節點只參與投票,不能被選爲Primary,而且不從Primary同步數據。好比你部署了一個2個節點的複製集,1個Primary,1個Secondary,任意節點宕機,複製集將不能提供服務了(沒法選出Primary),這時能夠給複製集添加一個Arbiter節點,即便有節點宕機,仍能選出Primary。
Arbiter自己不存儲數據,是很是輕量級的服務,當複製集成員爲偶數時,最好加入一個Arbiter節點,以提高複製集可用性。
六、Priority0
Priority0節點的選舉優先級爲0,不會被選舉爲Primary。好比你跨機房A、B部署了一個複製集,而且想指定Primary必須在A機房,這時能夠將B機房的複製集成員Priority設置爲0,這樣Primary就必定會是A機房的成員。
(注意:若是這樣部署,最好將『大多數』節點部署在A機房,不然網絡分區時可能沒法選出Primary)
七、Vote0
Mongodb 3.0裏,複製集成員最多50個,參與Primary選舉投票的成員最多7個,其餘成員(Vote0)的vote屬性必須設置爲0,即不參與投票。
八、Hidden
Hidden節點不能被選爲主(Priority爲0),而且對Driver不可見。
因Hidden節點不會接受Driver的請求,可以使用Hidden節點作一些數據備份、離線計算的任務,不會影響複製集的服務。
九、Delayed
Delayed節點必須是Hidden節點,而且其數據落後與Primary一段時間(可配置,好比1個小時)。
因Delayed節點的數據比Primary落後一段時間,當錯誤或者無效的數據寫入Primary時,可經過Delayed節點的數據來恢復到以前的時間點。
十、數據同步
Primary與Secondary之間經過oplog來同步數據,Primary上的寫操做完成後,會向特殊的local.oplog.rs特殊集合寫入一條oplog,Secondary不斷的從Primary取新的oplog並應用。因oplog的數據會不斷增長,local.oplog.rs被設置成爲一個capped集合,當容量達到配置上限時,會將最舊的數據刪除掉。另外考慮到oplog在Secondary上可能重複應用,oplog必須具備冪等性,即重複應用也會獲得相同的結果。
Secondary初次同步數據時,會先進行init sync 從Primary(或其餘數據更新的Secondary)同步全量數據,而後不斷經過tailable cursor從Primary的local.oplog.rs集合裏查詢最新的oplog並應用到自身。
init sync過程包含以下步驟:
T1時間,從Primary同步全部數據庫的數據(local除外),經過listDatabases + listCollections + cloneCollection敏命令組合完成,假設T2時間完成全部操做。
從Primary應用[T1-T2]時間段內的全部oplog,可能部分操做已經包含在步驟1,但因爲oplog的冪等性,可重複應用。
根據Primary各集合的index設置,在Secondary上爲相應集合建立index。(每一個集合_id的index已在步驟1中完成)。
oplog集合的大小應根據DB規模及應用寫入需求合理配置,配置得太大,會形成存儲空間的浪費;配置得過小,可能形成Secondary的init sync一直沒法成功。好比在步驟1裏因爲DB數據太多、而且oplog配置過小,致使oplog不足以存儲[T1, T2]時間內的全部oplog,這就讓Secondary沒法從Primary上同步完整的數據集。
十一、修改複製集配置
當須要修改複製集時,好比增長成員、刪除成員、或者修改爲員配置(如priorty、vote、hidden、delayed等屬性),可經過replSetReconfig命令(rs.reconfig())對複製集進行從新配置。
好比將複製集的第2個成員Priority設置爲2,可執行以下命令
cfg = rs.conf();
cfg.members[1].priority = 2;
rs.reconfig(cfg);
細說Primary選舉
Primary選舉除了在複製集初始化時發生,還有以下場景
複製集被reconfig
Secondary節點檢測到Primary宕機時,會觸發新Primary的選舉
當有Primary節點主動stepDown(主動降級爲Secondary)時,也會觸發新的Primary選舉
Primary的選舉受節點間心跳、優先級、最新的oplog時間等多種因素影響。
十二、節點間心跳
複製集成員間默認每2s會發送一次心跳信息,若是10s未收到某個節點的心跳,則認爲該節點已宕機;若是宕機的節點爲Primary,Secondary(前提是可被選爲Primary)會發起新的Primary選舉。
節點優先級
每一個節點都傾向於投票給優先級最高的節點
優先級爲0的節點不會主動發起Primary選舉
當Primary發現有優先級更高Secondary,而且該Secondary的數據落後在10s內,則Primary會主動降級,讓優先級更高的Secondary有成爲Primary的機會。
1三、Optime
擁有最新optime(最近一條oplog的時間戳)的節點才能被選爲主。
1四、網絡分區
只有更大多數投票節點間保持網絡連通,纔有機會被選Primary;若是Primary與大多數的節點斷開鏈接,Primary會主動降級爲Secondary。
當發生網絡分區時,可能在短期內出現多個Primary,故Driver在寫入時,最好設置『大多數成功』的策略,這樣即便出現多個Primary,也只有一個Primary能成功寫入大多數。
1五、複製集的讀寫設置(Read Preference)
默認狀況下,複製集的全部讀請求都發到Primary,Driver可經過設置Read Preference來將讀請求路由到其餘的節點。
primary: 默認規則,全部讀請求發到Primary
primaryPreferred: Primary優先,若是Primary不可達,請求Secondary
secondary: 全部的讀請求都發到secondary
secondaryPreferred:Secondary優先,當全部Secondary不可達時,請求Primary
nearest:讀請求發送到最近的可達節點上(經過ping探測得出最近的節點)
1六、Write Concern
默認狀況下,Primary完成寫操做即返回,Driver可經過設置[Write Concern(https://docs.mongodb.org/manual/core/write-concern/)來設置寫成功的規則。
以下的write concern規則設置必須在大多數節點上成功,超時時間爲5s。
db.products.insert(
{ item: "envelopes", qty : 100, type: "Clasp" },
{ writeConcern: { w: majority, wtimeout: 5000 } }
)
1七、異常處理(rollback)
當Primary宕機時,若是有數據未同步到Secondary,當Primary從新加入時,若是新的Primary上已經發生了寫操做,則舊Primary須要回滾部分操做,以保證數據集與新的Primary一致。
舊Primary將回滾的數據寫到單獨的rollback目錄下,數據庫管理員可根據須要使用mongorestore進行恢復。
4、開始配置MongoDB副本集:
注:這裏使用3臺服務器作MongoDB的副本集,都是源碼安裝的3.4.2版本,架構信息以下:
主:10.0.18.144 centos6.6 x86_64
從:10.0.18.149 centos6.6 x86_64
從:10.0.18.150 centos6.6 x86_64
具體安裝步驟請參見本篇博客第一部分!
一、修改配置文件 基本配置以下: systemLog: destination: file logAppend: true path: /var/log/mongodb/mongod.log logRotate: rename storage: dbPath: /data/db journal: enabled: true engine: wiredTiger processManagement: fork: true # fork and run in background pidFilePath: /usr/local/mongodb/mongod.pid # location of pidfile net: port: 27017 bindIp: x.x.x.x # Listen to local interface only, comment to listen on all interfaces. http: enabled: false RESTInterfaceEnabled: false #security: # authorization: enabled 在基本配置的基礎上對三臺mongodb的配置文件統一添加以下: replication: oplogSizeMB: 20 replSetName: Myrepl 注:oplogSizeMB指oplog大小,即複製操做日誌的最大大小(以兆字節爲單位 replSetName 指副本集名稱,注意格式是前面空兩格,冒號後空一格。 而後重啓三臺MongoDB的mongod進程! #killall mongod #su mongod -c "/usr/local/mongodb/bin/mongod -f /etc/mongod.conf" #以普通用戶啓動 二、在主服務器操做 #mongo --host 10.0.18.144 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.144:27017/ MongoDB server version: 3.4.2 > use admin switched to db admin > config={_id:"Myrepl",members:[{_id:0,host:"10.0.18.144:27017"},{_id:1,host:"10.0.18.149:27017"},{_id:2,host:"10.0.18.150:27017"}]}config={_id:"Myrepl",members:[{_id:0,host:"10.0.18.144:27017"},{_id:1,host:"10.0.18.149:27017"},{_id:2,host:"10.0.18.150:27017"}]} { "_id" : "Myrepl", "members" : [ { "_id" : 0, "host" : "10.0.18.144:27017" }, { "_id" : 1, "host" : "10.0.18.149:27017" }, { "_id" : 2, "host" : "10.0.18.150:27017" } ] } > rs.initiate(config) #初始化 { "ok" : 1 } #顯示ok表示成功 Myrepl:OTHER> 補充:要想使用副本集,從的mongodb的數據必須都是空的,要否則執行rs.initiate()命令時會提示因 存在數據而致使初始化不成功,以下: > rs.initiate(config) { "ok" : 0, "errmsg" : "'10.0.18.150:27017' has data already, cannot initiate set.", "code" : 110, "codeName" : "CannotInitializeNodeWithData" } 繼續進行: Myrepl:OTHER> rs.status() #查看副本集狀態 { "set" : "Myrepl", "date" : ISODate("2017-02-16T08:57:54.003Z"), "myState" : 1, "term" : NumberLong(1), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "10.0.18.144:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #主 "uptime" : 941, "optime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-02-16T08:57:44Z"), "electionTime" : Timestamp(1487235294, 1), "electionDate" : ISODate("2017-02-16T08:54:54Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "10.0.18.149:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #從 "uptime" : 191, "optime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-02-16T08:57:44Z"), "optimeDurableDate" : ISODate("2017-02-16T08:57:44Z"), "lastHeartbeat" : ISODate("2017-02-16T08:57:52.541Z"), "lastHeartbeatRecv" : ISODate("2017-02-16T08:57:52.182Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.18.150:27017", "configVersion" : 1 }, { "_id" : 2, "name" : "10.0.18.150:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #從 "uptime" : 191, "optime" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1487235464, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-02-16T08:57:44Z"), "optimeDurableDate" : ISODate("2017-02-16T08:57:44Z"), "lastHeartbeat" : ISODate("2017-02-16T08:57:52.542Z"), "lastHeartbeatRecv" : ISODate("2017-02-16T08:57:52.092Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.18.144:27017", "configVersion" : 1 } ], "ok" : 1 } 注意:兩個從上的狀態爲 "stateStr" : "SECONDARY",若爲 "STARTUP",則須要進行以下操做: > var config={_id:"tpp",members:[{_id:0,host:"192.168.0.103:27017"},{_id:1,host:"192.168.0.109:27017"},{_id:2,host:"192.168.0.120:27017"}]} > rs.initiate(config) 查看到以上信息就說明配置成功了,咱們也會發現主上前綴變爲Myrepl:PRIMARY> 而從服務器的前綴 變成了Myrepl:SECONDARY> 三、副本集測試 在主服務器上建庫、建集合、插入數據 Myrepl:PRIMARY> use testdb switched to db testdb Myrepl:PRIMARY> db.createCollection('test1') { "ok" : 1 } Myrepl:PRIMARY> show dbs admin 0.000GB local 0.000GB testdb 0.000GB Myrepl:PRIMARY> db.testdb.insert({"name":"repl","time":"170216"}) #插入一條數據 WriteResult({ "nInserted" : 1 }) Myrepl:PRIMARY> db.testdb.findOne() #查看數據 { "_id" : ObjectId("58a56b7404b33bc093a90321"), "name" : "repl", "time" : "170216" } 而後再從服務器上查看 #mongo --host 10.0.18.149 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.149:27017/ MongoDB server version: 3.4.2 Myrepl:SECONDARY> show dbs 2017-02-16T17:08:09.524+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:755:19 shellHelper@src/mongo/shell/utils.js:645:15 @(shellhelp2):1:1 Myrepl:SECONDARY> rs.slaveOk() #執行此命令,以後查詢就不報錯了! Myrepl:SECONDARY> show dbs admin 0.000GB local 0.000GB testdb 0.000GB Myrepl:SECONDARY> use testd switched to db testdb Myrepl:SECONDARY> db.testdb.findOne() #查詢數據,能夠看到在從服務器上已經有數據了 { "_id" : ObjectId("58a56b7404b33bc093a90321"), "name" : "repl", "time" : "170216" } 注意:經過上面的命令只能臨時查詢,下次再經過mongo命令進入後查詢仍會報錯,因此能夠修改文件 #vi ~/.mongorc.js //寫入下面這行 rs.slaveOk(); 而後重啓mongod進程! 我這裏是root用戶,因此在/root/.mongorc.js中添加便可! 四、模擬主服務器宕機,查看從服務器轉變爲主 首先在主服務器查看三臺服務器的權重,以下: Myrepl:PRIMARY> rs.config() { "_id" : "Myrepl", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "10.0.18.144:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #優先級爲1 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "10.0.18.149:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #優先級爲1 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "10.0.18.150:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #優先級爲1 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("58a568d2b205e55e0e0682d1") } } 注意:默認全部的機器權重(優先級)都爲1,若是任何一個權重設置爲比其餘的高,則該臺機器立馬會切換爲primary角色,因此要咱們預設三臺機器的權重 設置權重 預設主(18.144)權重爲三、從(18.149)權重爲二、從(18.150)權重爲1(默認值可不用從新賦值)。 在主18.144上執行下面命令: Myrepl:PRIMARY> cfg=rs.config() #從新賦值 { "_id" : "Myrepl", "version" : 1, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "10.0.18.144:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "10.0.18.149:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "10.0.18.150: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" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("58a568d2b205e55e0e0682d1") } } Myrepl:PRIMARY> cfg.members[0].priority = 3 3 Myrepl:PRIMARY> cfg.members[1].priority = 2 2 Myrepl:PRIMARY> rs.reconfig(cfg) #從新加載配置 { "ok" : 1 } Myrepl:PRIMARY> rs.config() #從新查看權重是否已經更改 { "_id" : "Myrepl", "version" : 2, "protocolVersion" : NumberLong(1), "members" : [ { "_id" : 0, "host" : "10.0.18.144:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 3, #變爲了3 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 1, "host" : "10.0.18.149:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 2, #變爲了2 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 }, { "_id" : 2, "host" : "10.0.18.150:27017", "arbiterOnly" : false, "buildIndexes" : true, "hidden" : false, "priority" : 1, #保持原來的1 "tags" : { }, "slaveDelay" : NumberLong(0), "votes" : 1 } ], "settings" : { "chainingAllowed" : true, "heartbeatIntervalMillis" : 2000, "heartbeatTimeoutSecs" : 10, "electionTimeoutMillis" : 10000, "catchUpTimeoutMillis" : 2000, "getLastErrorModes" : { }, "getLastErrorDefaults" : { "w" : 1, "wtimeout" : 0 }, "replicaSetId" : ObjectId("58a568d2b205e55e0e0682d1") } } 五、停掉主(10.0.18.144)服務器的mongod進程 #killall mongod 而後在從服務器10.0.18.149上敲幾下回車,從的角色立馬由SECONDARY變爲PRIMARY,以下: Myrepl:SECONDARY> Myrepl:SECONDARY> Myrepl:SECONDARY> Myrepl:PRIMARY> Myrepl:PRIMARY> Myrepl:PRIMARY> rs.status() #查看狀態 { "set" : "Myrepl", "date" : ISODate("2017-02-16T10:12:40.419Z"), "myState" : 1, "term" : NumberLong(2), "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) }, "appliedOpTime" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) }, "durableOpTime" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) } }, "members" : [ { "_id" : 0, "name" : "10.0.18.144:27017", "health" : 0, #原來的主服務器health爲0 "state" : 8, "stateStr" : "(not reachable/healthy)", #並且是不可達的狀態 "uptime" : 0, "optime" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDurable" : { "ts" : Timestamp(0, 0), "t" : NumberLong(-1) }, "optimeDate" : ISODate("1970-01-01T00:00:00Z"), "optimeDurableDate" : ISODate("1970-01-01T00:00:00Z"), "lastHeartbeat" : ISODate("2017-02-16T10:12:39.422Z"), "lastHeartbeatRecv" : ISODate("2017-02-16T10:10:43.056Z"), "pingMs" : NumberLong(0), "lastHeartbeatMessage" : "Connection refused", "configVersion" : -1 }, { "_id" : 1, "name" : "10.0.18.149:27017", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #原來的從服務器由於優先級高,變成了主 "uptime" : 3446, "optime" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-02-16T10:12:33Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1487239853, 1), "electionDate" : ISODate("2017-02-16T10:10:53Z"), "configVersion" : 2, "self" : true }, { "_id" : 2, "name" : "10.0.18.150:27017", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 3445, "optime" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) }, "optimeDurable" : { "ts" : Timestamp(1487239953, 1), "t" : NumberLong(2) }, "optimeDate" : ISODate("2017-02-16T10:12:33Z"), "optimeDurableDate" : ISODate("2017-02-16T10:12:33Z"), "lastHeartbeat" : ISODate("2017-02-16T10:12:39.357Z"), "lastHeartbeatRecv" : ISODate("2017-02-16T10:12:39.583Z"), "pingMs" : NumberLong(0), "syncingTo" : "10.0.18.149:27017", "configVersion" : 2 } ], "ok" : 1 } 注意:由上面可發現原來的主(18.144)已處於不健康狀態(失連),而原來權重高的從(18.149)的角色變爲PRIMARY, 權重低的從角色不變。不過要想讓用戶識別新主,還需手動指定讀庫的目標server! 六、原主恢復,新主寫入的數據是否同步 在10.0.18.149這臺新主服務器操做: #mongo --host 10.0.18.149 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.149:27017/ MongoDB server version: 3.4.2 在此服務器建庫、建集合、插入數據 Myrepl:PRIMARY> show dbs; admin 0.000GB local 0.000GB testdb 0.000GB Myrepl:PRIMARY> use testdb2 switched to db testdb2 Myrepl:PRIMARY> db testdb2 Myrepl:PRIMARY> db.createCollection('test2') { "ok" : 1 } Myrepl:PRIMARY> show dbs admin 0.000GB local 0.000GB testdb 0.000GB testdb2 0.000GB Myrepl:PRIMARY> db.testdb2.insert({"name":"repl2","time":"17021618"})db.testdb2.insert({"name":"repl2","time":"17021618"}) WriteResult({ "nInserted" : 1 }) Myrepl:PRIMARY> db.testdb2.findOne() { "_id" : ObjectId("58a57cd471c4e5a43bfa11fa"), "name" : "repl2", "time" : "17021618" } 在第二臺從服務器10.0.18.150查看數據 #mongo --host 10.0.18.150 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.150:27017/ MongoDB server version: 3.4.2 Myrepl:SECONDARY> show dbs; 2017-02-16T18:21:23.860+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435, "codeName" : "NotMasterNoSlaveOk" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:755:19 shellHelper@src/mongo/shell/utils.js:645:15 @(shellhelp2):1:1 Myrepl:SECONDARY> rs.slaveOk() Myrepl:SECONDARY> show dbs admin 0.000GB local 0.000GB testdb 0.000GB testdb2 0.000GB 也能夠看到第二臺從服務器已經重新主服務器複製了數據! 而後將原來的主服務器10.0.18.144的mongod進程啓動,在新主服務器10.0.18.149回車查看以下: Myrepl:PRIMARY> 2017-02-16T18:24:06.037+0800 I NETWORK [thread1] trying reconnect to 10.0.18.149:27017 (10.0.18.149) failed 2017-02-16T18:24:06.039+0800 I NETWORK [thread1] reconnect 10.0.18.149:27017 (10.0.18.149) ok Myrepl:SECONDARY> Myrepl:SECONDARY> 能夠看到狀態由原來的Myrepl:PRIMARY變爲了Myrepl:SECONDARY 最後登陸原主服務器查看數據是否存在 #mongo --host 10.0.18.144 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.144:27017/ MongoDB server version: 3.4.2 Myrepl:PRIMARY> show dbs #能夠看到testdb2庫已經存在了 admin 0.000GB local 0.000GB testdb 0.000GB testdb2 0.000GB Myrepl:PRIMARY> use testdb2 switched to db testdb2 Myrepl:PRIMARY> db.testdb2.findOne() #數據也能夠查看到 { "_id" : ObjectId("58a57cd471c4e5a43bfa11fa"), "name" : "repl2", "time" : "17021618" }
說明:由上面可知,當權重更高的原主恢復運行了,在新主期間寫入的新數據一樣同步到了原主上,即副本集成功實現了負載均衡的目的。
七、爲副本集開啓認證功能
說明:在配置副本集的時候,沒有開啓認證功能,爲了安全起見,配置好副本集以後,須要開啓。
注:單服務器,啓動時添加--auth參或者在配置文件中配置authorization: enabled開啓開啓驗證。
副本集服務器,開啓--auth參數或者在配置文件中配置authorization: enabled的同時,必須指定keyfile參數,節點之間的通信基於該keyfile,key長度必須在6到1024個字符之間,最好爲3的倍數,不能含有非法字符!
a、首先在主服務器建立數據庫管理員用戶 Myrepl:PRIMARY> use admin switched to db admin Myrepl:PRIMARY> db.createUser({user:"root",pwd:"test123",roles:["userAdminAnyDatabase"]}) Successfully added user: { "user" : "root", "roles" : [ "userAdminAnyDatabase" ] } Myrepl:PRIMARY> show collections; #查看集合 system.users system.version Myrepl:PRIMARY> show users; #查看用戶 { "_id" : "admin.root", "user" : "root", "db" : "admin", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } Myrepl:PRIMARY> db.system.users.find() #查看用戶的詳細信息 { "_id" : "admin.root", "user" : "root", "db" : "admin", "credentials" : { "SCRAM-SHA-1" : { "iterationCount" : 10000, "salt" : "YUtAugkOXigZNs0Y8sO+aA==", "storedKey" : "SGcT/CXln2oV0yCg0AP6GUgNhLQ=", "serverKey" : "ntBaZ36ulyNa7QuiLiXpclXb1TU=" } }, "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } 而後爲testdb庫建立一個具備讀寫權限的普通用戶 Myrepl:PRIMARY> use testdb switched to db testdb Myrepl:PRIMARY> db.createUser({user:"testuser1",pwd:"123456,",roles:["readWrite"]}) Successfully added user: { "user" : "testuser1", "roles" : [ "readWrite" ] } Myrepl:PRIMARY> show users; { "_id" : "testdb.testuser1", "user" : "testuser1", "db" : "testdb", "roles" : [ { "role" : "readWrite", "db" : "testdb" } ] } 而後建立系統管理員用戶 Myrepl:PRIMARY> use admin switched to db admin Myrepl:PRIMARY> db.createUser({user:"system",pwd:"123456",roles:[{role:"root",db:"admin"}]}) Successfully added user: { "user" : "system", "roles" : [ { "role" : "root", "db" : "admin" } ] } Myrepl:PRIMARY> show users; { "_id" : "admin.root", "user" : "root", "db" : "admin", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } { "_id" : "admin.system", "user" : "system", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] } b、在主服務器生成keyfile文件 #cd /usr/local/mongodb #進入mongodb安裝目錄 #openssl rand -base64 21 > keyfile #建立一個keyfile(使用openssl生成21位base64加密的字符串) #chown mongod.mongod keyfile #修改屬主屬組 #chmod 600 keyfile #修改權限爲600 注意:上面的數字21,最好是3的倍數,不然生成的字符串可能含有非法字符,認證失敗! c、將keyfile的內容寫入到其餘2臺從服務器對應目錄,並修改屬性和權限 d、在三臺服務器的mongod.conf配置文件中添加認證參數 security: keyFile: "/usr/local/mongodb/keyfile" #keyfile路徑 clusterAuthMode: "keyFile" #認證模式 authorization: enabled #開啓認證 而後重啓mongod進程,而後查看 #mongo --host 10.0.18.144 MongoDB shell version v3.4.2 connecting to: mongodb://10.0.18.144:27017/ MongoDB server version: 3.4.2 Myrepl:PRIMARY> show dbs 2017-02-17T17:35:42.675+0800 E QUERY [thread1] Error: listDatabases failed:{ "ok" : 0, "errmsg" : "not authorized on admin to execute command { listDatabases: 1.0 }", "code" : 13, "codeName" : "Unauthorized" } : _getErrorWithCode@src/mongo/shell/utils.js:25:13 Mongo.prototype.getDBs@src/mongo/shell/mongo.js:62:1 shellHelper.show@src/mongo/shell/utils.js:755:19 shellHelper@src/mongo/shell/utils.js:645:15 @(shellhelp2):1:1 能夠看到沒法執行show dbs,提示沒有認證 Myrepl:PRIMARY> use admin switched to db admin Myrepl:PRIMARY> db.auth("root","test123") #認證經過 1 Myrepl:PRIMARY> show dbs; #認證以後,查看就ok了 admin 0.000GB local 0.001GB testdb 0.000GB testdb2 0.000GB Myrepl:PRIMARY> show users; { "_id" : "admin.root", "user" : "root", "db" : "admin", "roles" : [ { "role" : "userAdminAnyDatabase", "db" : "admin" } ] } { "_id" : "admin.system", "user" : "system", "db" : "admin", "roles" : [ { "role" : "root", "db" : "admin" } ] } 一樣,在從服務器上想要查看數據,也須要認證經過後才能夠! 八、其餘 從新設置副本集命令: rs.stepDown() cfg = rs.conf() cfg.members[n].host= 'new_host_name:prot' rs.reconfig(cfg) 副本集全部節點服務器總數必須爲奇數,服務器數量爲偶數的時候,須要添加一個仲裁節點,仲裁節點不參與數副本集,只有選舉權。 #添加仲裁節點 rs.addArb("10.0.18.111:27017") 複製(副本集)相關請查閱中文網站 #################################### MongoDB查看複製集狀態 /opt/app/mongodb3/bin/mongostat --host x.x.x.114:27017 -umongodbuser -pxxx --authenticationDatabase=admin --discover -n 3 1 insert query update delete getmore command % dirty % used flushes vsize res qr|qw ar|aw netIn netOut conn set repl time x.x.x.113:27017 *16 95 *27 *0 0 74|0 0.1 80.0 0 15.5G 14.2G 0|3 1|0 17k 964k 556 km_tv SEC 11:27:50 x.x.x.114:27017 *16 81 *27 *0 0 75|0 0.1 80.0 0 15.4G 14.1G 0|0 1|0 16k 745k 558 km_tv SEC 11:27:50 x.x.x.115:27017 17 *0 57 *0 79 212|0 0.4 49.8 0 9.7G 8.4G 0|0 1|0 360k 694k 518 km_tv PRI 11:27:50 x.x.x.113:27017 *12 85 *29 *0 0 81|0 0.2 80.0 0 15.5G 14.2G 0|0 2|0 17k 618k 556 km_tv SEC 11:27:52 x.x.x.114:27017 *12 80 *29 *0 0 80|0 0.1 80.0 0 15.4G 14.1G 0|0 1|0 16k 697k 558 km_tv SEC 11:27:51 x.x.x.115:27017 11 *0 52 *0 68 181|0 0.5 49.8 0 9.7G 8.4G 0|0 1|0 292k 980k 515 km_tv PRI 11:27:52 x.x.x.113:27017 *12 81 *35 *0 0 86|0 0.2 80.0 0 15.5G 14.2G 0|0 1|0 16k 906k 556 km_tv SEC 11:27:53 x.x.x.114:27017 *12 90 *35 *0 0 83|0 0.1 80.0 0 15.4G 14.1G 0|0 1|0 17k 16m 558 km_tv SEC 11:27:52 x.x.x.115:27017 12 *0 64 *0 76 199|0 0.5 49.8 0 9.7G 8.4G 0|0 1|0 271k 548k 515 km_tv PRI 11:27:53 各字段解釋說明: insert/s : 官方解釋是每秒插入數據庫的對象數量,若是是slave,則數值前有*,則表示複製集操做 query/s : 每秒的查詢操做次數 update/s : 每秒的更新操做次數 delete/s : 每秒的刪除操做次數 getmore/s: 每秒查詢cursor(遊標)時的getmore操做數 command: 每秒執行的命令數,在主從系統中會顯示兩個值(例如 3|0),分表表明 本地|複製 命令 注: 一秒內執行的命令數好比批量插入,只認爲是一條命令(因此意義應該不大) dirty: 僅僅針對WiredTiger引擎,官網解釋是髒數據字節的緩存百分比 used: 僅僅針對WiredTiger引擎,官網解釋是正在使用中的緩存百分比 flushes: For WiredTiger引擎:指checkpoint的觸發次數在一個輪詢間隔期間 For MMAPv1 引擎:每秒執行fsync將數據寫入硬盤的次數 注:通常都是0,間斷性會是1, 經過計算兩個1之間的間隔時間,能夠大體瞭解多長時間flush一次。 flush開銷是很大的,若是頻繁的flush,可能就要找找緣由了 vsize: 虛擬內存使用量,單位MB (這是 在mongostat 最後一次調用的總數據) res: 物理內存使用量,單位MB (這是 在mongostat 最後一次調用的總數據) 注:這個和你用top看到的同樣, vsize通常不會有大的變更, res會慢慢的上升,若是res常常忽然降低,去查查是否有別的程序狂吃內存。 qr: 客戶端等待從MongoDB實例讀數據的隊列長度 qw:客戶端等待從MongoDB實例寫入數據的隊列長度 ar: 執行讀操做的活躍客戶端數量 aw: 執行寫操做的活客戶端數量 注:若是這兩個數值很大,那麼就是DB被堵住了,DB的處理速度不及請求速度。看看是否有開銷很大的慢查詢。若是查詢一切正常,確實是負載很大,就須要加機器了 netIn:MongoDB實例的網絡進流量 netOut:MongoDB實例的網絡出流量 注:此兩項字段表名網絡帶寬壓力,通常狀況下,不會成爲瓶頸 conn: 打開鏈接的總數,是qr,qw,ar,aw的總和 注:MongoDB爲每個鏈接建立一個線程,線程的建立與釋放也會有開銷,因此儘可能要適當配置鏈接數的啓動參數,maxIncomingConnections,阿里工程師建議在5000如下,基本知足多數場景 set: 副本集的名稱 repl: 節點的複製狀態 M ---master SEC ---secondary REC ---recovering UNK ---unknown SLV ---slave RTR ---mongs process("router') ARB ---arbiter time: 當前時間 九、不停機狀態下複製集主節點切換 注意:這裏是在三臺複製集的mongdob priority 全是1 的狀況下!!! a、凍結其中的一個從節點,使其不參與到與primary的內部選舉工做 進入到mongodb執行如下命令: (單位:秒) rs.freeze(120) b、重啓主節點的mongodb進程 (在2分鐘以內完成) c、第三個slave 節點 就被選舉成爲了主節點 rs.status() 查看狀態
5、複製集其餘一些用法
一、查看副本集成員數據同步(延遲)狀況 mongo>db.printReplicationInfo() mongo>db.printSlaveReplicationInfo() #最好在secondary上執行 mongo>rs.printReplicationInfo() mongo>rs.printSlaveReplicationInfo() #最好在secondary上執行 mongo>use local>db.slaves.find() 在主節點上跟蹤延遲: local.slaves該集合保存着全部正從當前成員進行數據同步的成員,以及每一個成員的數據新舊程度。 登陸主節點 >use local >db.slaves.find()、 查看其中每一個成員對應的"syncedTo":{"t":9999999,"i":32} 部分便可知道數據的同步程度。 二、主節點降爲secondary mongo>use admin mongo>rs.stepDown(60) #單位爲 秒 三、鎖定指定節點在指定時間內不能成爲主節點(阻止選舉) mongo>rs.freeze(120)#單位爲 秒 釋放阻止 mongo>rs.freeze(0)
本文參考連接:
http://msiyuetian.blog.51cto.com/8637744/1722406
http://www.osyunwei.com/archives/9313.html
http://blog.csdn.net/zhaowenzhong/article/details/51899093
不足之處,請多多指出!