對於某些應用程式來說,寫關注是重要的。它能判斷哪些寫操作成功寫入了,哪些失敗了,對於失敗的操作,驅動程式能返回錯誤,由應用程式決定怎麼處理。如果沒有寫關注,應用程式傳送一個寫操作到socket後,就不會管後面傳送了什麼情況,不知道是否成功寫入資料庫,這種情形對於日誌型別的應用程式還是可以接受的,因為偶爾的寫失敗不會影響整個日誌的監控情況;帶有寫關注的操作會等到資料庫確認成功寫入後才能返回,因此寫關注會帶來一點效能的損失。下面先分析複製集上寫關注配置。
預設情況下複製集的寫關注只針對primary節點,當應用程式傳送一個寫操作請求時,驅動程式會呼叫getLastError命令返回寫操作的執行情況(這一動作對應用程式來說是透明的),getLastError命令會根據你配置的寫關注選項來執行。寫關注選項的配置是針對當前客戶端與資料庫的socket連線來說的,因此配置項需要通過應用程式傳遞給驅動程式。當然如果你沒有傳遞任何選項引數給驅動程式,getLastError命令會根據你配置在複製集中預設配置local.system.replset.settings.getLastErrorDefaults來執行。getLastError命令的常用選項如下:
(1) 選項w
當取值為-1時,驅動程式不會使用寫關注,忽略掉所有的網路或socket錯誤。
當取值為0時,驅動程式不會使用寫關注,只返回網路和socket的錯誤。
當取值為1時,驅動程式使用寫關注,但是隻針對primary節點,這個配置項是複製集或單mongod例項的預設寫關注配置。
當取值為整數且大於1時,寫關注將針對複製集中n個節點,當客戶端收到這些節點的反饋資訊後,命令才返回給客戶端繼續執行。
(2)選項wtimeout
指定寫關注應在多長時間內返回,如果你沒有指定這個值,複製集可能因為不確定因素導致應用程式的寫操作一直阻塞。
下面通過一段程式碼對上面的描述做個回顧,在C#驅動程式下連線複製集並插入一條記錄。
//例項化一個客戶端的連線屬性例項
MongoClientSettings clientSetting = new MongoClientSettings();
//設定屬性準備Servers為要連線的複製集中的所有成員例項
List<MongoServerAddress> Servers = new List<MongoServerAddress>();
Servers.Add(new MongoServerAddress("Guo",40000));
Servers.Add(new MongoServerAddress("Guo",40001));
Servers.Add(new MongoServerAddress("Guo",40002));
clientSetting.Servers = Servers;
clientSetting.ReplicaSetName = "rs0"; //設定屬性複製集的名稱
MongoClient client = new MongoClient(clientSetting);//根據設定的屬性,例項化客戶端
//得到一個與複製集連線的例項
MongoServer server = client.GetServer();
//獲得一個與具體資料庫連線物件,資料庫名為students
MongoDatabase mydb = server.GetDatabase("students");
//獲得資料庫中的表物件,即scores表
MongoCollection mydbTable = mydb.GetCollection("scores");
//準備一條資料,即宣告一個文件物件
BsonDocument doc = new BsonDocument
{
{"stuid",5},
{"subject","sports"},
{"score",99}
};
//將文件插入到資料庫中
mydbTable.Insert(doc);
上面程式碼向複製集中插入一條資料,但是客戶端的配置屬性都是預設的,寫關注w選項值為1,可以在C#的驅動程式中通過MongoClientSettings這個類來設定客戶端的連線屬性,包括寫關注等;上面的程式碼也沒有具體指定連線到哪個節點,但驅動程式會預設的選擇primary節點;當primary節點當機時,複製集重新選擇出新的primary節點,驅動程式嘗試重新連線新的primary節點並完成插入,這個動作對應用程式透明的。