MongoDB 寫安全(Write Concern)
MongoDB Write Concern,簡稱MongoDB寫入安全機制,是一種客戶端設定,用於控制寫入安全的級別。Write Concern 描述了MongoDB寫入到mongod單例項,副本集,以及分片叢集時何時應答給客戶端。預設情況下,mongoDB文件增刪改都會一直等待資料庫響應(確認寫入是否成功),然後才會繼續執行。本文講述了MongoDB 應答機制及相關引數。
一、MongoDB應答機制
MongoDB應答機制就是說對於當前資料庫的寫入成功與否告知客戶端(db.getLastError())。如下:
mongoDB client發出寫入(或更新)請求---->mongoDB Server端寫入---->通知客戶端已經寫入OK
主要分為2種應答機制
應答式寫入(預設情形,安全寫入,適用於資料強一致性場景)
非應答式寫入(非安全寫入,適用於資料弱一致性場景)
實現方式
通過Write Concern來實現,客戶端驅動呼叫db.getLastError()方法,錯誤返回給客戶端
如果捕獲到錯誤,則可以通過客戶端定義的邏輯嘗試再次寫入或記錄到特定日誌等
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
二、Write Concern用法
{ w: <value>, j: <boolean>, wtimeout: <number> }
w : 該選項要求確認操作已經傳播到指定數量的mongod例項或指定標籤的mongod例項
w可選的的值
<number>
w:1(應答式寫入)
要求確認操作已經傳播到指定的單個mongod例項或副本集主例項(預設為1)
w:0(非應答式寫入)
不返回任何響應,所以無法知道寫入是否成功
但是對於嘗試向已關閉的套接字寫入或者網路故障會返回異常資訊
w:>1(用於副本集環境)
該值用於設定寫入節點的數目,包括主節點
"majority"(大多數)
適用於叢集架構,要求寫入操作已經傳遞到絕大多數投票節點以及主節點後進行應答
<tag set>
要求寫入操作已經傳遞到指定tag標記副本集中的成員後進行應答
j : 該選項要求確認寫操作已經寫入journal日誌之後應答客戶端(需要開啟journal功能)
則在意外重啟,當機等情形下可以通過journal來進行資料恢復
寫入journal操作必須等待直到下次提交日誌時完成寫入
為降低延遲,MongoDB可以通過增加commit journal的頻率來加快journal寫入
wtimeout:
該選項指定一個時間限制,以防止寫操作無限制被阻塞導致無法應答給客戶端
wtimeout的單位為ms,當w值大於1時生效,該引數即僅適用於叢集環境
當某個節點寫入時超出指定wtimeout之後,mongod將返回一個錯誤
在捕獲到超時之前,mongod並不會撤銷其他節點已成功完成的寫入
wtimeout值為0時等同於沒有配置wtimeout選項,容易導致由於某個節點掛起而無法應答
對於單例項應答的情形,是將資料寫入到記憶體後開始應答,除非j:true,則保證掉電後不會丟失資料
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
三、幾種不用應答模式圖示說明
1、非應答式寫入圖示
MongoDB不對客戶端進行應答,驅動會檢查套接字,網路錯誤等。
mongos> db.version()
3.2.9
mongos> db.version()
3.2.9
mongos> db
test
mongos> db.blogs.insert({ename:"leshami",url:"http://blog.csdn.net/leshami"},{writeConcern:{w:0}})
WriteResult({ }) //此處應答為空
mongos> db.blogs.find({},{_id:0})
{ "ename" : "leshami", "url" : "http://blog.csdn.net/leshami" }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
2、應答式寫入圖示
應答式寫入是預設值
MongoDB會在收到寫入操作並且確認該操作在記憶體中應用後進行應答,但不會確認資料是否已寫入磁碟
同時允許客戶端捕捉網路、重複key等等錯誤
mongos> db.blogs.insert({ename:"john",url:"http://blog.csdn.net/john"},{writeConcern:{w:1}})
WriteResult({ "nInserted" : 1 }) //此處應答資訊顯示為1個文件已插入
mongos> db.blogs.find({},{_id:0})
{ "ename" : "leshami", "url" : "http://blog.csdn.net/leshami" }
{ "ename" : "john", "url" : "http://blog.csdn.net/john" }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
3、帶journal應答式寫入圖示
確認寫操作已經寫入journal日誌之後應答客戶端,必須允許了日誌功能,才能生效。
寫入journal操作必須等待直到下次提交日誌時完成寫入
提供通過journal來進行資料恢復
- 1
- 2
- 3
- 4
4、副本集應答寫入圖示
對於使用副本集的場景,預設情況下僅僅從主(首選)節點進行應答
建議修改預設的應答情形為特定數目或者majority來保證資料的可靠
如下示例,w值為2,超時為5s
db.products.insert(
{ item: "envelopes", qty : 100, type: "Clasp" },
{ writeConcern: { w: 2, wtimeout: 5000 } }
)
如果不希望每次在增刪改時新增writeConcern,可以通過設定settings.getLastErrorDefaults
如下示例,
cfg = rs.conf()
cfg.settings = {}
cfg.settings.getLastErrorDefaults = { w: "majority", wtimeout: 5000 }
rs.reconfig(cfg)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
四、小結
1、write concern用於控制寫入安全的級別,可以分為應答式寫入以及非應答式寫入
2、write concern是一個效能和資料強一致性的權衡,應根據業務場景進行設定
3、對於強一致性場景,建議w>1或者等於majority,以及journal為true,否則w=0
4、在副本集的情形下,建議通過配置檔案來修改w以及設定wtimeout,以避免由於某個節點掛起導致無法應答
具體使用邏輯:
mongotemplate 設定writeconcern 用來標識什麼情況下 返回寫結果。
設定writeResultChecking 用來標識對寫結果 怎麼處理。
如果 mongo 遇到了可以處理的異常,會自動丟擲異常。
如果MongoDB執行過程中,遇到了伺服器異常(內部異常),會寫到writeResult 中,
這個時候 根據writeResultChecking 的值對writeResult 做不同的解析,
在資料強一致性要求下,可以設定writeconcern w1 ,writeResultChecking exception 保證dao 層使用丟擲異常。
在資料若一致性要求下,可以設定writeconcern none ,writeResultChecking none .
相關文章
- MongoDB Write Concern整理MongoDB
- 用 MongoTemplate 操作 documentDB 與 用 Spring Data MongoDB 操作 documentDB 有什麼不同,write concern,transactionSpringMongoDB
- AWS DocumentDB 如何設定為預設 write concern
- Mongodb write寫(增、刪、改)模組原始碼實現MongoDB原始碼
- mongodb批量操作, bulk_write,MongoDB
- mongodb核心原始碼實現及效能優化系列:Mongodb write寫(增、刪、改)模組原始碼實現MongoDB原始碼優化
- write_through 寫效能下降
- MongoDB安全配置MongoDB
- MongoDB:Read and write access to data and configuration is unrestricted.MongoDBREST
- MongoDB 安全&安全檢查列表MongoDB
- 練習英文寫作 Learn to write the english word
- MySQL:MGR 學習(1):寫集合(Write set)MySql
- Java 中的寫時複製 (Copy on Write, COW)Java
- 【MYSQL】innodb兩次寫(double write)實現解析MySql
- 如何寫一篇論文(How to write a thesis)
- MySQL:MGR 學習(2):Write set(寫集合)的寫入過程MySql
- MongoDB最佳安全實踐MongoDB
- MongoDB寫入資料策略MongoDB
- mongodb的讀寫分離MongoDB
- mongodb如何不區分大小寫MongoDB
- mongoDB研究筆記:寫關注MongoDB筆記
- Detectron2-寫模型(Write Models)官方文件中文翻譯模型
- 【Mongodb】 Replica set 的讀寫分離MongoDB
- 如何保證MongoDB的安全性?MongoDB
- mongoDB 3.0 安全許可權訪問MongoDB
- MongoDB安全checklist及最優配置模板MongoDB
- 淺談RAID寫懲罰(Write Penalty)與IOPS計算AI
- [OOD-More C++ Idioms] 寫時拷貝 (Copy on Write)C++
- 關於Cache的write-through & write-back
- MySQL double writeMySql
- hio_write
- [Javascript] Write .call()JavaScript
- SAP ABAP 寫時拷貝(Copy on Write)策略的一個具體例子
- shared_ptr實現多執行緒讀寫copy-on-write執行緒
- Linux--寫時複製(Copy-On-Write,COW)技術簡述Linux
- 提升 MongoDB 安全性的10個方法MongoDB
- MongoDB安全管理的三種方式介紹MongoDB
- 提升 MongoDB 安全性的 10 個方法MongoDB