首頁 > 資料庫 > MongoDB > 講講關於 MongoDB 複製集的幾個問題

講講關於 MongoDB 複製集的幾個問題

coldplay.xixi
發布: 2020-12-21 18:01:13
轉載
3466 人瀏覽過

MongoDB教學介紹為什麼要使用複製集

講講關於 MongoDB 複製集的幾個問題

推薦(免費):MongoDB教學

為什麼要使用複製集

1.備份資料
透過自帶的mongo_dump/mongo_restore 工具也可以實現備份,但畢竟沒有複製集的自動同步備份方便。

2.故障自動轉移
部署了複製集,當主節點掛了後,叢集會自動投票再從節點中選出一個新的主節點,繼續提供服務。而且這一切都是自動完成的,對維運人員和開發人員是透明的。當然,發生故障了還是得人工及時處理,不要過度依賴複製集,萬一都掛了,那就連喘息的時間都沒有了。

3.在某些特定的場景下提高讀取效能
預設情況下,讀取和寫入都只能在主節點上進行。
下面是MongoDB的客戶端支援5種複製集讀選項:

  • primary:預設模式,所有的讀取操作都在複製集的 主節點 進行的。
  • primaryPreferred:在大多數情況時,讀取操作在 主節點 上進行,但是如果主節點不可用了,讀取操作就會轉移到 從節點 上執行。
  • secondary:所有的讀取操作都在複製集的 從節點 上執行。
  • secondaryPreferred:在大多數情況下,讀取操作都是在 從節點 上進行的,但是當 從節點 不可用了,讀取操作會轉移到 主節點 上進行。
  • nearest:讀取操作會在 複製集 中網路延時最小的節點上進行,與節點類型無關。

來源:http://docs.mongoing.com/manual-zh/core/re...

不建議在從節點上進行讀取操作,因為從節點上的資料可能不是最新資料(主要原因)。
在從節點上進行讀取操作的場景很有限,官方手冊中寫明了適用的場景和不推薦從節點讀取操作的多個原因:http://docs.mongoing.com/manual-zh/ core/re...

說說我自己的看法:複製集並不是為了提高讀取效能而存在的,除了個別場景,不建議在從節點上進行讀取操作。如果想提升讀取效能,那麼請使用索引和分片。插一句,如果資料規模不大,就沒必要使用分片了。我們線上資料庫中單一集合記錄有將近 2 億條,效能還比較 OK(當然,機器配置也不差,而且上面就只跑了一個 Redis 和一個 MongoDB)。

如何部署複製集

##請看手冊:http://docs.mongoing.com/manual-zh/tutoria...

如何在程式中使用MongoDB 複製集故障自動轉移的特性

以PHP 的mongo 驅動為例。

$client = new MongoClient('mongodb://192.168.1.2:27018,192.168.1.3:27019,192.168.1.4:27020', array('replicaSet' => 'rs0'));
登入後複製
這樣設定後,如果只是其中一台 MongoDB 服務掛接後,剩餘的節點會自動選出新的主節點,程式還是可以繼續正常運作。在選舉的過程中,程序還是會拋出異常的,儘管選舉過程很快,但是為了程序的健壯性,必須考慮異常的處理。當然,如果選舉不出新的主節點,那麼整個 MongoDB 就不可用了。 (根據上面講的,如果複製集的讀取選項是配置的

primaryPreferred。如果沒有了主節點,但是從節點還可用的話,那麼讀取操作將轉移到從節點上去,這樣整個MongoDB 複製集還能提供讀取操作服務)

其實如果指定了複製集名

'replicaSet' => 'rs0',那麼就算不列出所有節點位址,只寫一個有效節點位址,mongo 驅動程式會自動取得到所有有效節點,$client->getHosts() 方法可以查看所有有效節點的位址。

但是如果你只寫了一個節點位址,剛好是那個節點掛掉了,那就連不上了。

所有我建議配置完整的節點位址清單

同步的原理是什麼

開啟複製集後,會在

local 函式庫下產生一個集合叫oplog.rs,這是一個有限集合,也就是大小是固定的。每次資料庫的寫入操作都會被記錄到這個集合裡面。複製集中的節點就是透過讀取其他節點上面的 oplog 來實現資料同步的。

举个例子:
用客户端向主节点添加了 100 条记录,那么 oplog 中也会有这 100 条的 insert 记录。从节点通过获取主节点的 oplog,也执行这 100 条 oplog 记录。这样,从节点也就复制了主节点的数据,实现了同步。

需要说明的是:并不是从节点只能获取主节点的 oplog。

为了提高复制的效率,复制集中所有节点之间会互相进行心跳检测(通过ping)。每个节点都可以从任何其他节点上获取oplog。

还有,用一条语句批量删除 50 条记录,并不是在 oplog 中只记录一条数据,而是记录 50 条单条删除的记录。

oplog中的每一条操作,无论是执行一次还是多次执行,对数据集的影响结果是一样的,i.e 每条oplog中的操作都是幂等的。

什么情况下需要重新同步

在上一个问题中得知:oplog 大小是固定的,而且 oplog 里面的记录数不一定和节点中的数据量成正比。那么,新记录肯定会将前面的老记录给覆盖。

如果,有天一个从节点挂了,其他节点还在正常运行,继续有写操作,oplog 继续增长。而这个挂掉的节点一直不能从其他节点那里同步最新的 oplog 记录,当其他节点的 oplog 已经发生的覆盖。即使这个从节点后来恢复了正常,也不会和其他节点保持数据一致了。因为,覆盖的就永远回不来了。

那么,这个时候就得重新同步了。恩,回不去的就永远回不去了,再找个新的重新开始吧。(逃

如何重新同步

参见:复制集成员的重新同步

什么时候应该使用投票节点

当复制集中有偶数个节点时,应该再加一个投票节点,用于打破投票僵局。

比如:我线上共有3台服务器,其中1台是作为 Web 服务器;其余2台作为 DB 服务器,各部署了1个MongoDB节点,构成了2个节点的复制集。这个时候,我并没有多余的机器了。在这个情况下,如果任意一台 DB 服务器上的 MongoDB 挂了,那么另外一台的 MongoDB 必然变为 SECONDARY 节点,那么就意味着 MongoDB 是不可用的了。为了避免这种情况,提高服务的可用性,可以在 Web 服务器上部署一个投票节点。投票节点并不存储数据,因此不能升职为 PRIMARY 节点,它对于硬件资源要求很低,并不会对 Web 服务器上的其他程序产生太大影响。这种情况下,如果任意一台 DB 服务器挂了,另外一台服务器上的 MongoDB 将成为 PRIMARY 节点,此时 MongoDB 还是依旧对外提供服务的。乘此时机,赶紧排查出故障的那台服务器的原因,尽快恢复服务。

为了让投票节点可以占用更少的资源,可以在配置文件中添加以下几个配置项:

journal = false
smallfiles = true
noprealloc = true
登入後複製

主从复制

master-slave 复制架构已经不推荐使用了,建议使用 replica sets 复制集架构。
参见:http://docs.mongoing.com/manual-zh/core/ma...

以上是講講關於 MongoDB 複製集的幾個問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:learnku.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板