MongoDB從庫延遲讀取資料問題的解決思路
最近,在網上看到一個朋友的MongoDB遇到效能問題,問題是這樣的:
主庫更新了資料,其中一個從庫時讀取,配置了後發現有延遲,比如更新50條,從庫只能讀取50%的資料,如何解決?
解決思路:
1) 監測一下網路看是否有瓶頸
2) 確認主從配置是否一致 (CPU、記憶體和IO)
3) 使用WriteConcern把資料同步寫到從機
那麼WriteConcern是怎麼把資料同步寫到從機的,下面介紹一下MongoDB的WriteConcern引數
首先列一下WriteConcern的幾種丟擲異常的級別引數:
WriteConcern.NONE:沒有異常丟擲
WriteConcern.NORMAL:僅丟擲網路錯誤異常,沒有伺服器錯誤異常
WriteConcern.SAFE:丟擲網路錯誤異常、伺服器錯誤異常;並等待伺服器完成寫操作。
WriteConcern.MAJORITY: 丟擲網路錯誤異常、伺服器錯誤異常;並等待一個主伺服器完成寫操作。
WriteConcern.FSYNC_SAFE: 丟擲網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器將資料重新整理到磁碟。
WriteConcern.JOURNAL_SAFE:丟擲網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器提交到磁碟的日誌檔案。
WriteConcern.REPLICAS_SAFE:丟擲網路錯誤異常、伺服器錯誤異常;等待至少2臺伺服器完成寫操作。
當我們執行如下操作時(將"name"為"lily"的"age"設定為20):
db.update({"name":"lily"},{"$set":{"age":20}})
預設情況下,該操作會使用WriteConcern.NORMAL(僅在網路錯誤時丟擲異常),等同於:
db.update({"name":"lily"},{"$set":{"age":20}},WriteConcern.NORMAL)
使用NORMAL模式引數,可以使得寫操作效率非常高。但是如果此時伺服器出錯,也不會返回錯誤給客戶端,而客戶端會誤認為操作成功。
因此在很多重要寫操作中需要使用WriteConcern.SAFE模式,保證可以感知到這個錯誤,保證客戶端和伺服器對一次操作的正確性認知保持一致。
(根據筆者測試,如果伺服器發生掉電情況,客戶端依然得不到當時操作的錯誤返回,需要特別注意)
另外在很多時候,我們需要確切知道這次寫操作是否成功(或者本次更新操作影響了多少個物件),這時候就需要:
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getN()>0) //操作影響的物件個數
return true;
else
return false;
或者:
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getLastError() == null)
return true;
else
return false;
此時,getLastError()會查詢上次操作結果是否出現錯誤。
更進一步
然後由於mongodb中使用連線池的原因,getLastError()需要再次從連線池中獲取連線,這樣效率會慢一些。可以這樣做:
db.requestStart();
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getLastError() == null)
return true;
else
return false;
db.requestDone();
就可以保證update操作和getLastError()使用同一個連線,並且減少了一次存/取連線的過程。
主庫更新了資料,其中一個從庫時讀取,配置了後發現有延遲,比如更新50條,從庫只能讀取50%的資料,如何解決?
解決思路:
1) 監測一下網路看是否有瓶頸
2) 確認主從配置是否一致 (CPU、記憶體和IO)
3) 使用WriteConcern把資料同步寫到從機
那麼WriteConcern是怎麼把資料同步寫到從機的,下面介紹一下MongoDB的WriteConcern引數
首先列一下WriteConcern的幾種丟擲異常的級別引數:
WriteConcern.NONE:沒有異常丟擲
WriteConcern.NORMAL:僅丟擲網路錯誤異常,沒有伺服器錯誤異常
WriteConcern.SAFE:丟擲網路錯誤異常、伺服器錯誤異常;並等待伺服器完成寫操作。
WriteConcern.MAJORITY: 丟擲網路錯誤異常、伺服器錯誤異常;並等待一個主伺服器完成寫操作。
WriteConcern.FSYNC_SAFE: 丟擲網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器將資料重新整理到磁碟。
WriteConcern.JOURNAL_SAFE:丟擲網路錯誤異常、伺服器錯誤異常;寫操作等待伺服器提交到磁碟的日誌檔案。
WriteConcern.REPLICAS_SAFE:丟擲網路錯誤異常、伺服器錯誤異常;等待至少2臺伺服器完成寫操作。
當我們執行如下操作時(將"name"為"lily"的"age"設定為20):
db.update({"name":"lily"},{"$set":{"age":20}})
預設情況下,該操作會使用WriteConcern.NORMAL(僅在網路錯誤時丟擲異常),等同於:
db.update({"name":"lily"},{"$set":{"age":20}},WriteConcern.NORMAL)
使用NORMAL模式引數,可以使得寫操作效率非常高。但是如果此時伺服器出錯,也不會返回錯誤給客戶端,而客戶端會誤認為操作成功。
因此在很多重要寫操作中需要使用WriteConcern.SAFE模式,保證可以感知到這個錯誤,保證客戶端和伺服器對一次操作的正確性認知保持一致。
(根據筆者測試,如果伺服器發生掉電情況,客戶端依然得不到當時操作的錯誤返回,需要特別注意)
另外在很多時候,我們需要確切知道這次寫操作是否成功(或者本次更新操作影響了多少個物件),這時候就需要:
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getN()>0) //操作影響的物件個數
return true;
else
return false;
或者:
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getLastError() == null)
return true;
else
return false;
此時,getLastError()會查詢上次操作結果是否出現錯誤。
更進一步
然後由於mongodb中使用連線池的原因,getLastError()需要再次從連線池中獲取連線,這樣效率會慢一些。可以這樣做:
db.requestStart();
WriteResult ret = db.update({"name":"lily"},{"$set":{"age":20}});
if(ret.getLastError() == null)
return true;
else
return false;
db.requestDone();
就可以保證update操作和getLastError()使用同一個連線,並且減少了一次存/取連線的過程。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15498/viewspace-1976412/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL主從資料庫同步延遲問題怎麼解決MySql資料庫
- mysql的主從複製資料延遲問題MySql
- 資料庫層面問題解決思路資料庫
- oracle 資料庫解決問題思路總結Oracle資料庫
- 主從延遲調優思路
- 教你如何解決MySQL資料延遲跳動的問題MySql
- 如何避免MYSQL主從延遲帶來的讀寫問題?MySql
- Google 怎麼解決長尾延遲問題Go
- 怎麼解決伺服器延遲問題伺服器
- Jtti:redis主從延遲資料不一致問題如何解決JttiRedis
- 《RabbitMQ》| 解決訊息延遲和堆積問題MQ
- Go GC:Go 1.5 將會解決延遲問題GoGC
- 從庫延遲案例分析
- 讀取多個(海康\大華)網路攝像頭的視訊流 (使用opencv-python),解決實時讀取延遲問題OpenCVPython
- MySQL之 從複製延遲問題排查MySql
- MySQL主從複製延遲解決方案MySql
- 疫情延遲 題解
- 美國伺服器延遲高怎麼辦,如何解決延遲問題伺服器
- 伺服器延遲問題如何解決伺服器
- MySQL 延遲從庫介紹MySql
- 主從複製延遲推薦解決方案
- MySQL資料庫慢的思路解決MySql資料庫
- MySQL讀寫分離及主從同步延時問題解決思路深入剖析-綜合元件環境實戰MySql主從同步元件
- 從“股票問題”談動態規劃問題的解決思路動態規劃
- MySQL 中讀寫分離資料延遲MySql
- Mysql配置從庫延遲應用MySql
- MySQL主從複製延遲原因及處理思路MySql
- 微服務改造中解決跨庫問題的思路微服務
- 安裝資料庫和資料庫解決問題資料庫
- MySQL主從延遲解決方法的歸納和總結MySql
- 分析伺服器延遲的問題伺服器
- 解決hive資料庫 插入資料很慢的問題Hive資料庫
- 關於讀取資料庫配置資原始檔問題資料庫
- AIX問題解決思路AI
- Oracle資料庫密碼延遲驗證Oracle資料庫密碼
- TDengine3.0:解決高基數問題的時序資料庫設計思路資料庫
- win7系統網路延遲問題多種解決方法Win7
- yii2 從資料庫獲取內容值型別與資料庫欄位型別問題解決資料庫型別