天天看點

mongodb服務安裝,搭建副本集及原理概述

##初始化系統環境,參考文檔:伺服器系統環境初始化,Centos7系統

#mongodb下載下傳安裝

mkdir -p /server/src /server/logs
groupadd mongod
useradd -s /sbin/nologin -g mongod mongod  
cat /etc/passwd |grep mongo
cd /root
   ##安裝mongodb 3.0.7版本,若需要其他版本,官網擷取下載下傳https://fastdl.mongodb.org/linux/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.0.7.tgz   
tar zxvf mongodb-linux-x86_64-rhel70-3.0.7.tgz 
mv mongodb-linux-x86_64-rhel70-3.0.7 /usr/local/mongodb
mkdir -p /data/mongodb2/db
mkdir /data/mongodb2/log
mkdir /data/mongodb2/keyfile
chmod 755 !$
touch /data/mongodb2/keyfile/security
chmod 600 !$
echo "xxxxy" > !$
cat !$
touch /data/mongodb2/log/mongo.log
chmod 644 !$
chown -R mongod.mongod /data/mongodb2
ll /data
ll /data/mongodb2/
ll /data/mongodb2/log/
ll /data/mongodb2/keyfile/
vim /lib/systemd/system/mongod.service      
[Unit]
    Description=mongodb
    After=network.target remote-fs.target nss-lookup.target
 
[Service]
    Type=forking
    PIDFile=/data/mongodb2/db/mongod.lock
    ExecStart=/usr/local/mongodb/bin/mongod --dbpath=/data/mongodb2/db --logpath=/data/mongodb2/log/mongo.log --fork --port 27017 --logappend --replSet rep1 --rest --httpinterface --maxConns=8000 --keyFile=/data/mongodb2/keyfile/security
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    LimitFSIZE=infinity
    LimitCPU=infinity
    LimitAS=infinity
    LimitNOFILE=64000
    LimitNPROC=64000
 
[Install]
    WantedBy=multi-user.target      
systemctl enable mongod.service
systemctl start mongod.service
ps aux |grep mongo |grep -v 'grep'
systemctl status mongod.service 
    #将mongo程式添加到環境變量
echo "export PATH=/usr/local/mongodb/bin:$PATH" >>/etc/profile
source !$
echo $PATH      

#建立帳号

##建立帳号方式一(建立admin管理者)
use admin
db.createUser({user:"mongo_admin",pwd:"xxx",roles:[{role:"root",db:"admin"}]})      
    #下次登入需要驗證才能對資料庫進行操作
mongo
use admin
db.auth('mongo_admin','xxx')      

##建立管理者方式二(建立dba使用者)

> use admin
switched to db admin
> db.createUser(
...   {
...     user: "dba",
...     pwd: "dba",
...     roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
...   }
... )
Successfully added user: {
    "user" : "dba",
    "roles" : [
        {
            "role" : "userAdminAnyDatabase",
            "db" : "admin"
        }
    ]
}
##現在需要建立一個帳号,該賬号需要有grant權限,即:賬号管理的授權權限。注意一點,帳号是跟着庫走的,是以在指定庫裡授權,使用指定庫也必須在指定庫裡驗證(auth)。      

##建立使用者解析

roles:指定使用者的角色,可以用一個空數組給新使用者設定空角色;在roles字段,可以指定内置角色和使用者定義的角色。role裡的角色可以選:

  Built-In Roles(内置角色):

    1. 資料庫使用者角色:read、readWrite;

    2. 資料庫管理角色:dbAdmin、dbOwner、userAdmin;

    3. 叢集管理角色:clusterAdmin、clusterManager、clusterMonitor、hostManager;

    4. 備份恢複角色:backup、restore;

    5. 所有資料庫角色:readAnyDatabase、readWriteAnyDatabase、userAdminAnyDatabase、dbAdminAnyDatabase

    6. 超級使用者角色:root  

    // 這裡還有幾個角色間接或直接提供了系統超級使用者的通路(dbOwner 、userAdmin、userAdminAnyDatabase)

    7. 内部角色:__system

具體角色: 

Read:允許使用者讀取指定資料庫

readWrite:允許使用者讀寫指定資料庫

dbAdmin:允許使用者在指定資料庫中執行管理函數,如索引建立、删除,檢視統計或通路system.profile

userAdmin:允許使用者向system.users集合寫入,可以找指定資料庫裡建立、删除和管理使用者

clusterAdmin:隻在admin資料庫中可用,賦予使用者所有分片和複制集相關函數的管理權限。

readAnyDatabase:隻在admin資料庫中可用,賦予使用者所有資料庫的讀權限

readWriteAnyDatabase:隻在admin資料庫中可用,賦予使用者所有資料庫的讀寫權限

userAdminAnyDatabase:隻在admin資料庫中可用,賦予使用者所有資料庫的userAdmin權限

dbAdminAnyDatabase:隻在admin資料庫中可用,賦予使用者所有資料庫的dbAdmin權限。

root:隻在admin資料庫中可用。超級賬号,超級權限

#副本集配置檔案

conf=({_id:"repl",members:[{_id:0,host:"103.56.195.2"},{_id:1,host:"103.56.195.3"},{_id:2,host:"103.56.195.4"}]})
rs.initiate(conf)
rs.status()
rs.conf()                        #檢視副本集配置檔案
{
	"_id" : "repl",
	"version" : 8,
	"members" : [
		{
			"_id" : 0,
			"host" : "103.56.195.2:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 1,
			"host" : "103.56.195.3:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 3,
			"host" : "103.56.195.5:27027",
			"arbiterOnly" : true,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		},
		{
			"_id" : 2,
			"host" : "103.56.195.4:27017",
			"arbiterOnly" : false,
			"buildIndexes" : true,
			"hidden" : false,
			"priority" : 1,
			"tags" : {
				
			},
			"slaveDelay" : 0,
			"votes" : 1
		}
	],
	"settings" : {
		"chainingAllowed" : true,
		"heartbeatTimeoutSecs" : 10,
		"getLastErrorModes" : {
			
		},
		"getLastErrorDefaults" : {
			"w" : 1,
			"wtimeout" : 0
		}
	}
}      

#設定副本集中每台伺服器的優先級

mongo 10.10.148.130:27017       #ip和port是某個節點的位址   
use admin 
cfg={_id:"testrs",members:[{_id:0,host:'10.10.148.130:27017',priority:2},{_id:1,host:'10.10.148.131:27017',priority:1},{_id:2,host:'10.10.148.132:27017',arbiterOnly:true}]};   
rs.initiate(cfg)      

#測試副本集資料同步,在primary主節點上寫資料

[primary]
for(var i=0;i<10002;i++){db.test.insert({"name":"test"+i,"age":123})}
db.test.count()

[slave]
rs.slaveOk()
db.test.count()      

#檢視mongo副本集伺服器之間之間建立的網絡連接配接

netstat -atnp |grep mongo
tcp        0      0 0.0.0.0:27017           0.0.0.0:*               LISTEN      60566/mongod        
tcp        0      0 0.0.0.0:27027           0.0.0.0:*               LISTEN      60518/mongod        
tcp        0      0 0.0.0.0:28027           0.0.0.0:*               LISTEN      60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.3:48225      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:32798      103.56.195.2:27017      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.4:56920      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:37736      103.56.195.4:27017      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:27027      103.56.195.2:56702      ESTABLISHED 60518/mongod        
tcp        0      0 103.56.195.5:59560      103.56.195.3:27017      ESTABLISHED 60518/mongod      

#增删節點

#插入副本節點
rs.add({"_id":2,"host":"103.56.195.4:27017"})      
#插入仲裁節點
rs.addArb("103.56.195.5:27027")      
#删除節點
rs.remove("103.56.195.4:27017")      

#仲裁節點

上面說明已經讓25伺服器成為仲裁節點。副本集要求參與選舉投票(vote)的節點數為奇數,當我們實際環境中因為機器等原因限制隻有兩個(或偶數)的節點,這時為了實作 Automatic Failover引入另一類節點:仲裁者(arbiter),仲裁者隻參與投票不擁有實際的資料,并且不提供任何服務,是以它對實體資源要求不嚴格。

通過實際測試發現,當整個副本集叢集中達到50%的節點(包括仲裁節點)不可用的時候,剩下的節點隻能成為secondary節點,整個叢集隻能讀不能寫。比如叢集中有1個primary節點,2個secondary節點,加1個arbit節點時:當兩個secondary節點挂掉了,那麼剩下的原來的 primary節點也隻能降級為secondary節點;當叢集中有1個primary節點,1個secondary節點和1個arbit節點,這時即使 primary節點挂了,剩下的secondary節點也會自動成為primary節點。因為仲裁節點不複制資料,是以利用仲裁節點可以實作最少的機器開 銷達到兩個節點熱備的效果。

#仲裁節點啟動參數

[[email protected] mongoarb]# cat /usr/local/mongodb/mongoarb.conf 
    dbpath=/data/mongoarb/arbiter
    logpath=/data/mongoarb/log/arbiter.log 
    fork=true
    port=27027 
    logappend=true
    replSet=repl 
    keyFile=/data/mongoarb/keyfile/security      

#mongo仲裁節點程序

[[email protected] mongoarb]# ps aux |grep mongo
root  60518  1.0  0.1 105572288 66668 ?  Sl  18:30  0:00 /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongoarb.conf --rest
root  60566  0.3  0.0 491396 47140 ? Sl 18:31  0:00 /usr/local/mongodb/bin/mongod --dbpath=/data/mongodb2/db --logpath=/data/mongodb2/log/mongo.log --fork --port 27017 --logappend      

#仲裁節點mongo服務添加到systemctl開機自啟動服務

[[email protected] mongoarb]# cat /lib/systemd/system/mongoarb.service 
[Unit]
    Description=mongoarb
    After=network.target remote-fs.target nss-lookup.target 
[Service]
    Type=forking
    PIDFile=/data/mongoarb/arbiter/mongod.lock
    ExecStart=/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongoarb.conf --rest 
    ExecReload=/bin/kill -s HUP $MAINPID
    ExecStop=/bin/kill -s QUIT $MAINPID
    PrivateTmp=true
    LimitFSIZE=infinity
    LimitCPU=infinity
    LimitAS=infinity
    LimitNOFILE=64000
    LimitNPROC=64000
[Install]
    WantedBy=multi-user.target      

#讀寫分離

MongoDB副本集對讀寫分離的支援是通過Read Preferences特性進行支援的,這個特性非常複雜和靈活。

應用程式驅動通過read reference來設定如何對副本集進行讀取操作,預設的,用戶端驅動所有的讀操作都是直接通路primary節點的,進而保證了資料的嚴格一緻性。

支援五種的read preference模式:官網說明

primary主節點,預設模式,讀操作隻在主節點,如果主節點不可用,報錯或者抛出異常。

primaryPreferred 首選主節點,大多情況下讀操作在主節點,如果主節點不可用,如故障轉移,讀操作在從節點。

secondary從節點,讀操作隻在從節點, 如果從節點不可用,報錯或者抛出異常。

secondaryPreferred首選從節點,大多情況下讀操作在從節點,特殊情況(如單主節點架構)讀操作在主節點。

nearest最鄰近節點,讀操作在最鄰近的成員,可能是主節點或者從節點,關于最鄰近的成員請參考

注意:2.2版本之前的MongoDB對Read Preference支援的還不完全,如果用戶端驅動采用primaryPreferred實際上讀取操作都會被路由到secondary節點。

副本集中資料同步過程: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,不能提供服務。

參考文檔:MongoDB 副本集的原理、搭建、應用

http://www.cnblogs.com/zhoujinyi/p/3554010.html

2-Mongodb叢集搭建的三種方式

http://wenku.baidu.com/link?url=Th6OyRUeoUE_-Kxq09vWrUEHT1_k9JgXV-0F6sWdmRO6MyJbNPKa8B6FfGd26fZBIT8DjCTkj25AOLDFOROg5L1tSn_kzzzu80ejf35PlL_

轉載于:https://blog.51cto.com/jschu/1706918