MongoDB入門實戰教程(10)

前面我們學習了在MongoDB中如何使用索引來提高查詢效率,本篇我們開始進入事務管理部分,首先我們來看看寫操作事務。

1 writeConcern詳解

通過前面的介紹,我們瞭解瞭如何搭建一個MongoDB的複製集實現高可用。要實現高可用,就需要在複製集上有冗餘。

那麼,對數據的寫操作,是需要保證數據成功的在從節點上冗餘才能算是高可用的。因此,MongoDB提供了一個writeConcern的參數,它決定了一個數據的寫操作要落到多少個節點纔算成功。

writeConcern的取值:

(1)0:發起寫操作,並不關心是否成功;(實際中不建議使用此方式,無法保證數據的複製是否成功)

(2)1~集羣最大節點個數:寫操作需要被複制到指定節點個數纔算成功;(舉例:集羣共5個節點,那麼此方式需要5個節點都複製成功纔算成功。實際中也不建議此方式,延時較長,體驗較差)

(3)majority:寫操作需要被複制到大多數節點上纔算成功;(舉例:集羣中共5個節點,那麼此方式需要5/2=3個節點都複製成功就算成功。實際中建議採用此方式,屬於折中考慮的方案)

 對於(2)和(3)兩種方式,發起寫操作的程序將會被阻塞到寫操作達到指定的節點個數爲止。

綜述,從上面的介紹我們可以知道,在實際應用中,建議配置writeConcern爲majority,它兼顧了響應時間(性能)和數據冗餘(安全),這也是我在團隊項目中爲MongoDB Driver基礎組件設置的默認選項。

2 writeConcern應用

Mongo Shell實驗

首先,確保你已經搭建好了一個MongoDB的複製集(replica set),參考《MongoDB入門實戰教程(2)》。這裏我們有3個節點的複製集,一個primary節點 和 2個secondary節點。

其次,爲了模擬網絡延遲等待的效果,我們首先在primary節點上通過mongo shell爲一個secondary節點設置slaveDelay參數爲10s,代表這個secondary節點要等待10s纔會被同步數據。

// 拿到複製集的配置
rs0:PRIMARY> conf = rs.conf()
// 查看當前所有members
rs0:PRIMARY> conf.members
// 爲第2個secondary節點設置slaveDelay=10s
rs0:PRIMARY> conf.members[2].slaveDelay = 10
// 不讓第2個secondary節點參與選舉
rs0:PRIMARY> conf.members[2].priority = 0

設置好之後,我們再來試一試帶writeConcern參數的insert操作。這裏我們先來一個writeConcern=3,即所有3個節點都寫成功了纔算寫入成功,預期結果是等待10s才能成功。

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:3}})

實際結果:等待第2個secondary節點的延遲10s之後纔會響應寫入成功。

針對這種情況,我們也可以設置一個最大等待時間,超出了就立即響應。

例如,下面設置超過3s就立即響應,不管是否已同步到所有的3個節點:

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:3, wtimeout:3000}})

通過上面的介紹,我們知道將writeConcern設置爲majority是比較合適的。

rs0:PRIMARY> db.testDB.insert({count:100}, {writeConcern:{w:"majority"}})

MongoDB .NET Driver實驗

在連接字符串級別爲所有MongoDB操作設置默認writeConcern級別:

var client = new MongoClient(
    "mongodb+srv://<username>:<password>@<cluster-address>/test?w=majority"
);
var database = client.GetDatabase("test");

在Database級別爲某個Database設置默認writeConcern爲majority:

var mongoClient = new MongoClient("mongodb://mongo-master:27017");
var defaultDbSettings = new MongoDatabaseSettings()
{
   WriteConcern = WMajority
};
var mongoDatabase = mongoClient.GetDatabase("products", defaultDbSettings);

在Collection級別爲某個Collection設置默認writeConcer爲majority:

var defaultCollectionSettings = new MongoCollectionSettings()
{
  WriteConcern = WMajority
};         
var collection = mongoDatabase.GetCollection<SKU>("sku", defaultCollectionSettings);

在操作語句級別爲某個操作設置writeConcern爲majority:

var contact = new Contact();
_contacts.WithWriteConcern(WriteConcern.WMajority).InsertOne(contact);

3 總結

本文簡單介紹了MongoDB的寫操作事務,它有一個重要的參數writeConcern,瞭解它的選項並在實際項目中應用對於實現數據的高可用至關重要。

下一篇,我們會學習MongoDB的讀操作事務,掌握readPreference 和 readConcern 兩個重要參數。

參考資料

唐建法,《MongoDB高手課》(極客時間)

郭遠威,《MongoDB實戰指南》(圖書)

△推薦訂閱學習

 

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