MongoDB複製集知識點及PHP7連接mongodb

概述

誠然,網上很多大佬列出了詳細的MongoDB複製集配置教程,但是新人總是還是遇到一些困惑的地方,我把我遇到的困惑點列出來,相互學習之、加深記憶之。

MongoDB搭建集羣主要有三種方式:1):主從;2):複製集;3):分片;

  • 主從
    主從就是一主(master)多從(slave)架構,可以是做到安全備份,讀寫分離等;但官方考慮到技術的更新換代,主從方式已不推薦使用,並從MongoDB4.0移除了對主從方式的支持,主要是因爲主從方式有明顯缺點:
    1):不具有高可用性,只要主節點掛掉,整個集羣都不可用了,需要人爲啓動主節點纔可以。
    2):如果不進行讀寫分離,讀寫都在主節點上,主節點的壓力無疑會很大
    3):從節點都從主節點複製數據,主節點壓力會不會過大
    4):如果採用讀寫分離(寫主讀從),會不會因爲主從同步時因爲數據複製延遲的問題,導致客戶端讀到的是舊數據或無法拿到數據,假設一個極端的場景:在讀寫分離模式下,客戶端寫入一個文檔,就立馬讀出來,這時可能會出現讀到的是舊數據或無法拿到數據的情況,在實際業務中要避免的,主要是因爲從節點從主節點複製數據是要一定時間的。

Removed
MongoDB 4.0 removes support for master-slave replication. Before you can upgrade to MongoDB 4.0, if your deployment uses master-slave replication, you must upgrade to a replica set.
To convert your master-slave replication, see Convert a Master-Slave Deployment to a Replica Set

  • 複製集
    原理:主節點是副本集中接收寫操作的唯一成員。MongoDB在主數據庫上應用寫操作,然後在主數據庫的oplog上記錄操作。次要成員複製此日誌,並將操作應用於其數據集。
    在這裏插入圖片描述
    複製集採用一主(Primary,即主要)多從(Secondary,即次要)的架構,這裏的主是所有節點推選出來的,很民主吧,並不像主從架構的主節點是上帝(你)指定的。官方規定,副本集最多50個節點,但擁有選舉權最多可以有七個,要知道擁有選舉權的節點纔可能成爲主節點。如下圖:
    在這裏插入圖片描述
    官方推薦具有選舉權的(可以投票的)節點數爲奇數,從節點有幾種角色:
    普通節點:備份主節點數據
    仲裁節點:僅有選舉權,不備份主節點數據
    隱藏節點:對客戶端應用程序不可見,但備份主節點數據
    延遲節點:所含數據集是主節點的過去某時刻的內容
    詳細說明見官網副本集次要成員
    優點:高可用(主的死了再推一個主的,不會因此不能工作),災備恢復,讀寫分離等
    缺點:除了提高了可用性(對於集羣來說很重要的一個特性),其他與主從模式差不多
    1):如果不進行讀寫分離,讀寫都在主節點上,主節點的壓力無疑會很大
    2):從節點都從主節點複製數據,主節點壓力會不會過大?
    3):如果採用讀寫分離(寫主讀從),會不會因爲主從同步時因爲數據複製延遲的問題,導致客戶端讀到的是舊數據或無法拿到數據,假設一個極端的場景:在讀寫分離模式下,客戶端寫入一個文檔,就立馬讀出來,這時可能會出現讀到的是舊數據或無法拿到數據的情況,在實際業務中要避免的,主要是因爲從節點從主節點複製數據是要一定時間的。

複製集配置

(由於我只有一臺個人電腦(mac),所以通過區分端口(27017,27018,27019)來進行三個節點的配置),具體下載安裝mongodb就不說了,玩到到副本集段位的這些也不用說,哈哈。
mongodb配置:

#mongodb config file
dbpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/data/db/
logpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/log/mongod.log
logappend = true #日誌追加方式
port = 27017 #端口
fork = true #守護進程運行
#auth = true
noauth = true
#bind_ip = 192.168.40.253
bind_ip = 127.0.0.1 #綁定IP

replSet = rs0 #副本集名字,具有唯一性,換別的也可以
oplogSize=2048 #oplog集合大小,單位M,用於主從同步的一個固定集合(即大小受限的集合),在local庫裏
directoryperdb=true # 設置每個數據庫將被保存在一個單獨的目錄
#私鑰
#security:
	#keyFile = /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

並命名爲mongodb.conf,位於/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/conf/mongodb.conf。

啓動服務

按配置文件建好目錄,文件等,啓動 。切換到/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10目錄,執行
mongod -f ./rs0/conf/mongodb.conf
同理,進行節點2,3的初始化:
mongod -f ./rs1/conf/mongodb.conf
mongod -f ./rs2/conf/mongodb.conf

注意:初始化時不要開啓認證模式,先用免認證模式進行復制集設置。

進入端口27017服務,mongo --port 27017

1:rs.initiate()//初始化複製集配置
2:rs.add("127.0.0.1:27018")//增加節點
3:rs.add("127.0.0.1:27019")//增加節點
4:rs.status()//查看節點狀態
5:rs.conf()//查看節點配置
6:use admin
8:db.createUser({ user: "root", pwd: "123456", roles: [ { role: "root", db: "admin"} ]})//創建用戶,這裏如果通過Robo 3T看,可以看到新建的用戶已同步到27018,27019服務

三個服務全關閉,可以通過 ps -ef | grep mongo 查看mongo進程號,然後kill掉就好了,也可執行db.shutdownServer()。

主從間的同步需要安全機制,所以要生成祕鑰(注意,如果多臺機器,一個機器生成,複製到其他機器上即可,各節點必須保持一致):openssl rand -base64 90 -out ./keyfile,將生成的keyfile放到配置文件指定的目錄 /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

修改配置文件,開啓認證模式:

#mongodb config file
dbpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/data/db/
logpath=/Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/rs0/log/mongod.log
logappend = true #日誌追加方式
port = 27017 #端口
fork = true #守護進程運行
auth = true
#noauth = true
#bind_ip = 192.168.40.253
bind_ip = 127.0.0.1 #綁定IP

replSet = rs0 #副本集名字,具有唯一性,換別的也可以
oplogSize=2048 #
directoryperdb=true # 設置每個數據庫將被保存在一個單獨的目錄
#私鑰
security:
	keyFile = /Applications/MAMP/db/mongodb-osx-x86_64-4.0.10/key/keyfile

啓動三個mongo服務,使用之前創建的用戶登錄即可。現在已經具有災備,高可用的特性了。

我們這樣搭建下來,27017爲主要節點,27018,27019爲次要節點,如果關閉27017主節點,你會發現27018和27019中的某一個變成主節點,並且再啓動27017節點,它變成了一個次要節點,並開始從主節點複製數據,並不會恢復主節點的身份。當然,恢復也是不合理的,畢竟它掛了的那段時間實際數據已經改變了

PHP連接MongoDB實現讀寫分離

安裝:PHP7安裝MongoDB擴展(php7以前可以用mongo擴展,但PHP7已放棄),
mongodb的composer包(composer require mongodb/mongodb)

require_once 'vendor/autoload.php';
$uri='mongodb://'.$host1.':'.$port1.','.$host2.':'.$port2.','.$host3.':'.$port3;
$uriOptions = [
       'username' => $username,
       'password' => $password,
       'ssl' => false,//ssl連接,需要證書,默認false
       'replicaSet' => $replicaset,//複製集名稱,如我用的 rs0
       'authSource' => $authdb,//認證的數據庫,admin
       //'slaveOk'=>true,//已棄用
       'readPreference' => 'secondaryPreferred'//指定讀模式
 ];
 $diverOptions = [
            'typeMap' => [         
                'root' => 'array',
                'document' => 'array',
                'array' => 'array',
            ]
        ];
/**
   限定MongoDB擴展返回來的是方便php處理的數組,而不是bsonarray對象,默認配置
   [
    'array' => 'MongoDB\Model\BSONArray',
    'document' => 'MongoDB\Model\BSONDocument',
    'root' => 'MongoDB\Model\BSONDocument',
]
*/
$mongo = new MongoDB\Client($uri,$uriOptions,$diverOptions);

注意讀模式共有五種模式:

primary:默認參數,只從主節點上進行讀取操作;
primaryPreferred:大部分從主節點上讀取數據,只有主節點不可用時從secondary節點讀取數據。
secondary:只從secondary節點上進行讀取操作,存在的問題是secondary節點的數據會比primary節點數據“舊”。
secondaryPreferred:優先從secondary節點進行讀取操作,secondary節點不可用時從主節點讀取數據;
nearest:不管是主節點、secondary節點,從網絡延遲最低的節點上讀取數據。

主從複製原理淺析

首先,主節點會把本服務的與寫有關的操作記錄下來,讀操來不記錄,這些操作就記錄在local數據庫中的oplog.rs0(因爲我創建複製集的名稱叫rs0)這個集合中,這是一個固定集合,大小是可以配置的,主要是通過配置oplogSize這個參數來實現,單位是M,大小一般爲磁盤剩餘空間的5%左右.因爲是固定集合所以當固定集合放滿日誌的時候,新進來的日誌就會把最舊的日誌覆蓋掉,如果這個值設置的不合理,導致數據很快的被覆蓋,而從節點沒有來得及更新,這樣就會產生數據不同步的情況.設置爲主節點的local數據庫有會有oplog.$admin與slave這兩個集合.slave記錄的是從節點的信息.
從節點與主節點的數據同步主要是從節點定時的會去連接主節點,請求主節點的操作日誌,從而對自己的數據副表進行同樣的操作來達到數據的同步.從節點的local數據庫中會多了source與me這兩個集合,source是記錄主節點的信息,me是記錄從節點的標識

待續。。。。。。

參考資料

1】MongoDB官網
2】生產環境配置MongoDB複製集
3】使用新版MongoDB1.4–composer安裝、使用與填坑
4] MongoDB副本集實現及讀寫分離

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章