現場填坑系列:mongodb 複製集跨機房同步網路問題探查

来源:https://www.cnblogs.com/yizhu2000/archive/2020/05/11/12866582.html
-Advertisement-
Play Games

在丟包率0.3%的情況下,mongodb的replicaSet發生了比較嚴重的問題。表現為同步速率大幅下降,然後產生延遲。有的已經超過2-3個小時,造成有些打到延遲mongodb上面的資料庫請求無法反應資料庫的最新更改 ...


接到現場報告,客戶MongoDB間數據延遲越來越大,有的已經超過2-3個小時,造成有些打到延遲mongodb上面的資料庫請求無法反應資料庫的最新更改。這個問題反覆出現在高峰期尤其明顯,持續近一月。

架構

客戶為異地雙機房架構,兩地機房相隔上千公裡,帶寬250M,光纖,具體鏈路情況不明

               F5                              |                    F5

             N中心                           |                   S中心

業務服務  ...  業務服務              |          業務服務 .... 業務服務

mongodb4 ...  mongodb6   <----|-----   mongodb1(主) ... mongdb2

 

所有資料庫在一個複製集共6台(其中一臺不參與選舉),使用的是mongodb replicaSet 進行同步。

現象

S中心資料庫反覆產生延遲,其中一次rs.printSlaveReplicationInfo()查詢集群情況顯示如下,資料庫4,5,6三台延遲(此處不是每次都是三台同時延遲,有時只是這三臺中的兩台或者一臺出現延遲,但是1,2從不延遲),延遲時間最多達到2-3個小時,非高峰期可以恢復。

  • 客戶在兩個機房間通過ping命令發現南北網路有延遲現象。
  • 在發生延遲時,有時可以通過切換同步源的方式,暫時解決問題。

插入圖

分析

首先查看有問題的機器,發現4,5,6三台均在N中心,1,2均在S中心,而用rs.status查看,可以發現當延遲時,這三台都以1為同步源,也就是發生跨網路同步。

由於三台出現同步的機器都在N中心,可猜測與鏈路有關。客戶ping命令未顯示延遲,說明ping的數據量可能不夠或者問題是由某種條件觸發的。

是否有可能同步帶寬超過了鏈路限制,我們和網路方面的人進行了溝通,得到的消息是我們的應用使用的帶寬沒有達到上限。最高也就極限帶寬的2/3左右。為確認帶寬情況,我們自己也對帶寬進行了分析。

帶寬使用分析

南北中心業務高峰期正常情況下帶寬占用70Mb/s,也沒有達到理論高度,而且正常情況下某些瞬時,帶寬可以超過150Mb/s,也證明服務遠遠沒有達到帶寬上線。我們進一步對產生延遲的情況下的帶寬進行分析,發現了一個奇怪的情況

:在產生延遲的情況下,資料庫用來同步的帶寬遠遠不足60Mb/s ,只有不到15Mb/s。也就是說,資料庫有大量堆積,產生延遲的時候,資料庫同步反而變慢了

同時我們監控了S中心內未延遲節點與通中心主節點同步時的帶寬約為17Mb/s ,由於mongodb每台slave都是複製同樣的數據,可以推知其他機器都應該按照這個速率進行同步。而延遲節點只有4.5Mb/s左右。

我們又查看了延遲節點的監控,查看了延時節點從正常狀態轉入延遲狀態的帶寬情況,發現其使用帶寬會在某種情況下發生驟降

 

到底是什麼導致這種狀況呢?是mongodb本身的問題嗎?

這種情況我們還是決定圍繞核心現象來進行分析:這幾台伺服器和正常的伺服器有什麼不同。我們一一排查了機器配置,軟體配置的問題,確保出問題的伺服器和正常伺服器沒有原則不同,同時也查了這幾台伺服器在延遲時的表現,發現延遲時,這幾台mongo的指標遠遠沒有到達瓶頸,所以唯一可疑的不同還是在網路上,即使ping沒有發現問題,我們還是決定要進一步抓包。

抓包

因為抓包對性能有顯著影響,為了抓出特征包,我們選在節點開始延遲,並且延遲時間還在增大時進行抓包,抓包時間在1分鐘以內。

抓包語句 tcpdump -i eth0 port xxx -w /home/tcpdump.cap

下麵是我們看到的情況(使用Wireshark)

網路中出現了大量的Dup ACK,這個說明瞭TCP出現了數據丟失導致了重傳。

Dup ACK

TCP的流程是面向連接,會儘力保證數據的完整性,所以有失敗重傳機制,Dup ACK 就是這個機制的一部分。

每個包都有一個Seq號和一個包長度,正常情況下,某一端所有發送的包的Seq號是連續的,比如

第一個包的Seq是1,長度是2,

則第二個包Seq=1+2=3,長度4,

第三個包的Seq=3+4,長度若幹,

以此類推,當接收端收到這個包時會將這個包放到緩衝區,緩衝區里可能有很多從另一端發來的包,他們必須能連續起來,接收端會向發送端發包時告知會帶上我接收到的最後一個連續的包的Seq是多少,這個數據會放在ACK里傳送。

上面註意:

  • 發送端和接收端是相對的,兩邊都遵循這個規則。
  • 不是每一個包都ACK,這樣開銷太大。
  • 也不一定有專門用於ACK的包,事實上ACK包往往也可能是對上一個或者幾個包的回覆,順便就進行了ACK。

插入圖

假如丟失了一個包會怎麼樣?接收端發現緩存里的包丟失了,而後面的包已經到了,就會觸發上面的Dup ACK,告知我接收到的連續的數據的序號到哪裡為止,也就是DupACK包的ACK。這個請求會反覆發送,直到服務端發送缺失包(retransmit)。在收到缺失包前,後續的包即使收到也不會ack。這個是retransmit的流程。

上面的流程在dump中典型的例子用wireshark打開會是下麵的樣子:註意這裡包括【TCP Previous segment not captured】【Dup ACK】 等內容都是wireshark的分析結果。TCP包中並不包含這些標簽。

首先從端發現丟包【TCP Previous segment not captured】然後引發從端大量發送dup ack,直到主端重傳通過TCP Fast Retransmition 或Retransmition 重傳missing package,見下圖。重傳期間所有有缺失的包會暫存入buffer。

 

在wireshark中可以對重傳的包進行過濾  tcp.analysis.retransmission 

過濾結果為32條,占所抓包的0.3%,這個統計可以看做是就是丟包的統計。然而由於這樣的丟包,觸發tcp進行反覆溝通引起的混亂遠遠大於此,如果統計所有由此引起的dup Ack, Out of Order,Fast Retransmit,Transmit,window_update 等,可以看到這些處理丟包的請求占到了5.5%之多。

同時剛纔提到發送端可能發送很多包,但是只是其中一個丟了。這些沒有丟掉的包會放在一個緩衝區中,這個緩衝區叫做window,由於後續包不斷到來,而失去的包沒有補上,所以tcp不能向上層轉發,於是就會更改window的大小,這個也是非常消耗資源的行為。

總結來說:

從庫的dump中,共抓包16.81秒10176個包,錯誤重傳造成的dup ack和重傳包達到562 占 5.5%;

主庫(同步源)的dump中,共抓包12秒 3501個包,錯誤重傳以及dup ack相關的包占到325,占比9.3%;

而同機房內部節點完全未見丟包與重傳,且在跨機房節點處於無延遲正常狀態也未見丟包重傳。

重傳與流量下降間的關係

為了確保這個現象只在跨機房調用中出現,我們也抓取了同機房同步,以及跨機房無延遲時的情況,這兩種情況下均無上述問題。重傳錯誤與流量的關係可見下圖,折線為吞吐,柱形為error包數量,可見流量的重大轉折均伴隨有相關錯誤,下圖也展現了window scaling的情況,展示出由於錯誤發生,windows size 的修改情況,可見6分鐘左右發生了一次大的scaling,正對應了dump中的錯誤。

結論與解決方法

在丟包率0.3%的情況下,mongodb的replicaSet發生了比較嚴重的問題。表現為同步速率大幅下降,然後產生延遲。

客戶網路情況比較複雜,鏈路是運營商鏈路,還有許多第三方廠商的設備,難以在短時間內排查原因,所以再發生同步時,我們採用rs.syncFrom腳本切換同步源臨時解決這個問題:即當腳本監測延遲>10分鐘時,立刻切換到另外一個數據源。

此方法基於在產生延遲後,立即切換另外一個數據源可以重新打開同步鏈路快速同步,瞬間同步時速可以到達160Mb/s,延時數據能很快消失。

但是在執行過程中,出現過切換同時,mongodb由於大量寫入而影響業務的情況,所以後來改為在非高峰先講需要修改的節點改為hide節點再進行處理。

未來最終解決方案

解決網路延遲:這個是最直接的解決辦法,畢竟同機房同步未見問題。

減少replicaSet的量:檢查業務中的寫入更新刪除邏輯,減少生成量。具體分析和處理方法將另文描述。

使用mongoshake等第三方同步工具:由於尚未明晰重傳為何導致複製集處理速度下降,所以不使用複製集也可能可以解決這個問題。且複製集對源的選擇有自己的演算法,雖然可以短時間的切換,但是更多時候是根據mongodb自身的演算法進行選擇,比如在本案中,三台N節點Mongo都到S節點同步,造成帶寬乘以3倍,雖然可以手動制定其中兩台從同節點一臺複製,但mongodb還是有可能自動根據自己的演算法切換源。而使用第三方同步工具可以解決上面的兩個問題。但是要檢查第三方工具在0.3%網路丟包下的工作情況。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • public partial class ModelStatusDictionary<T> where T : new() { static readonly DynamicMethod<T> _dynamicMethod = new DynamicMethod<T>(); /// <summary ...
  • 我覺得我可以加入歷史博物館了,加入微軟歷史博物館,本文也是和大家吹歷史的博客 ...
  • 全屏應用對應的是視窗模式應用,全屏應用指的是整個屏幕都是被咱一個應用獨占了,屏幕上沒有顯示其他的應用,此時的應用就叫全屏應用。如希沃白板這個程式。本文主要告訴大家從微軟官方的文檔以及考古瞭解到的 Windows 對全屏應用的優化,以及是如何進行的優化,方便小伙伴在撕的時候可以找到根據 ...
  • "TOC" Shell學習 shell概述 shell是一個命令行解釋器,它接收應用程式/用戶命令,然後調用操作系統內核。 shell解釋器 1. Linux提供的解釋器有 2. bash和sh的關係 3. Centos預設的解析器是bash Shell腳本入門 1. 腳本格式 腳本以 !/bin/ ...
  • 進程管理類命令 信號: 在linux當中所有的進行管理都是靠信號來管理的.像我們平時要結束某個進程就是使用的15信號SIGTERM,還有想要強制殺死某個進程,就是使用的9信號SIGKILL等等. 在linux可以查看信號有哪些的指定太多了,kill -l ; trap -l; man 7 signa ...
  • liunx中各種監控工具,量大.本篇全是命令介紹,筆者把各個命令的都實驗一遍,給同學們看看. ...
  • 阻塞IO模型(Blocking I/O) 內核一開始提供了 與 阻塞式操作。 當客戶端連接時,會在對應進程的文件描述符目錄(/proc/進程號/fd)生成對應的文件描述符(0 標準輸入;1 標準輸出;2 標準錯誤輸出;),比如 fd 8 , fd 9; 應用程式需要讀取的時候,通過系統調用 讀取,如 ...
  • 自上世紀80年代末至90年代初互聯網誕生以來,Web服務可以說是在互聯網的普及過程當中起到了巨大的作用。而Web服務應該是當今世界上普通用戶訪問互聯網的最廣泛的方式了,用戶只需在瀏覽器中輸入所謂網址的方式即可瀏覽互聯網上的海量信息,而瀏覽器這種瘦客戶端的交互方式也是目前最主流的交互方式。 Web服務 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...