創建mongodb副本集操作實例


一:概念

相關概念及圖片引用自這里

mongodb副本集: 副本集是一組服務器,其中一個是主服務器,用於處理客戶請求;還有多個備份服務器,用於保存主服務器的數據副本。如果主服務器崩潰了,備份服務器自動將其中一個成員升級為新的主服務器。 由此可見副本集對於應對災難性事件是多么的合適。以前的mongo主從模式其實就是一個單副本的應用,沒有很好的擴展性和容錯性。而mongodb副本集具有多個副本保證了高性能,數據的一致性,容錯性,就算一個副本掛掉了還有很多副本存在,並且解決了上面第一個問題“主節點掛掉了,整個集群內會自動切換”。

由圖可以看到客戶端連接到整個副本集,不關心具體哪一台機器是否掛掉。主服務器負責整個副本集的讀寫,副本集定期同步數據備份,一但主節點掛掉,副本節點就會選舉一個新的主服務器,這一切對於應用服務器不需要關心。我們看一下主服務器掛掉后的架構:

副本集中的副本節點在主節點掛掉后通過心跳機制檢測到后,就會在集群內發起主節點的選舉機制,自動選舉一位新的主服務器。

其他關於選舉等詳細概念可以看這里


官方推薦的副本集機器數量為至少3個,那我們也按照這個數量配置測試。

因此先准備3台虛擬機用於測試:

系統均為:Linux Debian ,分別為:

已分配好的可登錄用戶分別是:root,user1

二:安裝mongodb

以下記錄在安裝mongodb過程中遇到的問題:

1.在ip為84的虛擬機上,root用戶沒有開放遠程登錄權限,用root賬號登錄時報錯:Access denied (網上查到是因為sshd的設置不允許root用戶用密碼遠程登錄的原因)

解決辦法:user1用戶登錄后

   su        // 切換到管理員賬號

  輸入 nano /etc/ssh/sshd_config 回車              //nano是用記事本打開,也可以使用 vi 打開
  找到 # Authentication: LoginGraceTime 120 PermitRootLogin without passwd StrictModes yes
  把“PermitRootLogin without passwd”改成“PermitRootLogin yes”
  按“ctrl+o”保存再退出,退出后記得要重啟一下才生效!

  reboot   //重啟

2. root用戶目錄下安裝mongodb

  root 登錄 

  cd /root    //在root目錄下安裝

  mkdir mongodb   

  拖動 mongodb-linux-x86_64-3.0.1.tgz 到mongodb目錄

  解壓縮到當前目錄:tar zxvf mongodb-linux-x86_64-3.0.1.tgz

3. 配置mongodb啟動的配置文件 mongodb.conf

    

 解釋一下參數名稱:

  • dbpath: db數據文件存放位置
  • logpath:db的日志文件存放位置
  • logappend: 日志是否以追加方式寫入
  • fork: 后台運行
  • port: 訪問端口      //默認27017
  • noauth: 無認證訪問(此處是為測試方便,請勿效仿)
  • replSet:副本集核心參數,副本集的名稱,這個參數是必須的,而且必須三台機器完全一樣
  • 更多參數可以根據需要添加

4. 設置環境變量

  vi ~/.bashrc     //    ~/ 表示打開當前用戶目錄下面的.bashrc文件
  拷貝以下設置到文件保存即可
    export MONGOHOME=/root/mongodb/mongodb-linux-x86_64-3.0.1
    export PATH=$MONGOHOME/bin:$PATH

5. 設置服務開機自啟動:

  cd /etc/init.d        //進入啟動項目文件夾下

  touch mongodb  創建mongodb文件,將以下內容拷貝到文件並保存

#!/bin/sh
### BEGIN INIT INFO
# Provides: mongod
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop
### END INIT INFO

# Source function library.
. /lib/lsb/init-functions

retval=0
pidfile=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`

CONFIG="/root/mongodb/mongodb.conf"
PROGRAM="/root/mongodb/mongodb-linux-x86_64-3.0.1/bin/mongod"
MONGOPID=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`

test -x $PROGRAM || exit 0

case "$1" in
start)
ulimit -n 3000
log_begin_msg "Starting MongoDB server"
$PROGRAM -f $CONFIG &
log_end_msg 0
;;
stop)
log_begin_msg "Stopping MongoDB server"
if [ ! -z "$MONGOPID" ]; then
kill -15 $MONGOPID
fi
log_end_msg 0
;;
status)
;;
*)
log_success_msg "Usage: /etc/init.d/mongodb {start|stop|status}"
exit 1
esac

exit 0

(在mongodb文件存在的情況下,可將mongodb的啟動文件拖動到 /etc/init.d文件夾下)

   核對:啟動項目位置及配置文件位置

    CONFIG="/root/mongodb/mongodb.conf"
    PROGRAM="/root/mongodb/mongodb-linux-x86_64-3.0.1/bin/mongod"
    MONGOPID=`ps -ef | grep 'mongod' | grep -v grep | awk '{print $2}'`


6. 配置好后reboot 重啟系統

檢測是否能進入mongo:

mongo -v  或者 mongo 命令。

 注意項:

  因為mongodb是安裝在root用戶下(Linux系統默認所安裝的軟件只能在當前用戶下有使用權限,換一個用戶就沒有權限訪問),當user用戶登錄后使用mongo命令時,會報錯沒有權限訪問,這是我們需要設置user用戶的訪問mongodb的權限。

1:user用戶登錄

在user用戶目錄下 加入環境變量,指向mongo安裝的文件夾:
vi ~/.bashrc 進入當前用戶下面的.bashrc文件
  拷貝以下設置保存即可
  export MONGOHOME=/root/mongodb/mongodb-linux-x86_64-3.0.1
  export PATH=$MONGOHOME/bin:$PATH

2:mongodb的安裝目錄(root目錄)訪問權限

給mongodb的安裝目錄 :root目錄設置訪問權限(需要在root管理員用戶下設置) 在root當存目錄

cd /root
chmod 777 root (讀寫執行權限都有了)

chmod -R 777 root(文件的讀寫,創建文件夾等)
chmod a+x root  執行權限

設置完這兩部,在user賬號下,就能啟動mongodb了。

如果在啟動mongodb時報以下連接不上的mask錯誤,試試以下命令:

systemctl unmask mongodb
systemctl enable mongodb
systemctl start mongodb

3:在user用戶下,判斷開機啟動項下面的mongodb文件是否有執行權限 

  cd /etc/init.d/ 進入這個啟動項目錄
  ls -al mongodb 查看mongodb啟動文件的權限 (./mongo) 按tab鍵不全 則是沒有執行權限
  chmod a+x mongodb 給mongodb文件賦予執行權限   (需要在管理員權限下設置)

systemctl enable mongodb 對mongodb文件設置可用

systemctl start mongodb.service 啟動服務

4: 其他可能涉及的命令:

如果系統開放了防火牆,還需要開放防火牆的端口,可以使得3台機器相互之間能訪問,不會被牆掉。

列出INPUT 鏈所有的規則
iptables -L INPUT --line-numbers

#當然,自己不能被擋在外面,給自己開個后門
iptables -I INPUT -s 127.0.0.1 -p tcp --dport 27017 -j ACCEPT(出於業務邏輯的需要,有時還需要對服務器的公網IP授權)

iptables -I INPUT -s 172.16.9.241 -p tcp --dport 27017 -j ACCEPT
iptables -I INPUT -s 172.16.9.240 -p tcp --dport 27017 -j ACCEPT
iptables -I INPUT -s 172.16.9.85 -p tcp --dport 27017 -j ACCEPT

列出所有的服務,查看所有服務
systemctl list-units --type=service

df -h 查看磁盤空間

 手動從配置文件啟動服務 :mongod -config ./mongodb-3.2.18/mongodb.conf(配置文件路徑)

 

三:設置副本集

在3個虛擬機上啟動mongo服務都沒有問題時,開始配置副本集。

隨便選擇某一台服務器做副本集初始化配置即可。

輸入mongo命令,啟動mongo   

config={  
     _id:"testrepl",
    members:[
        {_id:0,host:"172.16.9.241:27017"},        
        {_id:1,host:"172.16.9.240:27017"},
        {_id:2,host:"172.16.9.84:27017"}]
    }  

rs.initiate(config) 

##########################
"_id": 副本集的名稱
"members": 副本集的服務器列表
  "_id": 服務器的唯一ID
  "host": 服務器主機
  "priority": 是優先級,默認為1,優先級0為被動節點,不能成為活躍節點。優先級不位0則按照有大到小選出活躍節點。
  "arbiterOnly": 仲裁節點,只參與投票,不接收數據,也不能成為活躍節點。

第一次初始化時報以下錯誤:

replSetInitiate quorum check failed because not all proposed set members responded affirmatively: 172.16.9.85:27017 failed with Failed attempt to connect to 172.16.9.85:27017; couldn't connect to server 172.16.9.85:27017 (172.16.9.85), connection attempt failed    code:74

 經查證發現root磁盤空間小了,副本集至少要求好幾G空間,以用來交互數據使用。重新分配虛擬機空間后解決問題。

若初始化成功,會返回以下代碼:

{
    "ok" : 1
}

查看副本集狀態: rs.status()  命令

注意事項:

1.只需要選擇其中某一節點做初始化配置

2. 在副本集初始化的時候,一般都是copy不同的數據至各個結點,之后啟動結點,添加至集群,之后查詢狀態會發現是  STARTUP2,這是因為集群初始化在同步數據,同步完數據之后,狀態就變正常了

3. 在副本節點讀取數據報錯:
Error: error: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 }

因為241為主副本集,mongodb默認是從主節點讀寫數據的,而副本節點上不允許讀數據,因此在從服務器上需要做以下設置,需要設置副本節點可以讀。

repset:SECONDARY>db.getMongo().setSlaveOk();   執行這句讓副本集可以讀

其實:有兩種方法實現從機的查詢:
第一種方法:db.getMongo().setSlaveOk();
第二種方法:rs.slaveOk();

上面兩行命令即允許此連接從副本讀取.

但是這種方式有一個缺點就是,下次再通過mongo進入實例的時候,查詢仍然會報錯,為此可以通過下列方式
vi ~/.mongorc.js
增加一行rs.slaveOk();
以后每次通過mongo命令進入都可以查詢了。

 

 可以測試當主節點掛掉,副本節點就會選舉一個新的主服務器

 

 當再次啟動241服務器的mongo時,會恢復其primary身份。

 到這里,副本集就已經配置完成。

 

對於切換日志的操作,

>use admin

> db.runCommand({logRotate:1})

 

參考文檔1;文檔2


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM