記一次隊列積壓問題的分析、解決

来源:http://www.cnblogs.com/sealake/archive/2017/04/26/6763501.html
-Advertisement-
Play Games

現象: 同事負責的項目轉到我的頭上,整理服務過程中發現了隊列的積壓問題。 為了搞清楚積壓的嚴重程度, 對隊列任務數每分鐘進行一次採樣,生成一個走勢圖, 隊列積壓情況一目瞭然,非常嚴重。 分析: 聽了同事對系統的介紹,猜測是mongo性能影響了處理效率,於是針對mongo進行分析 1. 使用mongo ...


現象:

同事負責的項目轉到我的頭上,整理服務過程中發現了隊列的積壓問題。

為了搞清楚積壓的嚴重程度, 對隊列任務數每分鐘進行一次採樣,生成一個走勢圖, 隊列積壓情況一目瞭然,非常嚴重。 

 分析:

聽了同事對系統的介紹,猜測是mongo性能影響了處理效率,於是針對mongo進行分析

1. 使用mongotop  /usr/local/mongodb/bin/mongotop --host 127.0.0.1:10000

odds_easy.basic_odds表的操作一直排第一,寫操作占大部分時間

 

2. 看mongo shard日誌

大量超過1s的操作,集中在odds_easy.basic_odds寫操作,  看日誌lock數量很多

 

查詢某一個文檔的更新,在同一秒中居然有15個更新操作,這樣的操作產生什麼樣的結果: 大量的寫鎖,並且影響讀;而且還是最影響性能的數組的$push, $set操作

 

看看文檔的結構,數組的數量之大,而且裡面還是對象嵌套; 對這樣一個文檔不停的更新, 性能可想而知

 

 看看 db.serverStats()的lock情況

 

 看看odds_easy的db.basic_odds.stats()情況,大量的更新衝突

 

3.  看看sharding情況

  使用腳本,查看sharding情況,重定向到文件中查看。
  sql='db.printShardingStatus({verbose:true})'
  echo $sql|/usr/local/mongodb/bin/mongo --host 192.168.1.48:30000 admin --shell 

   basic_odds的sharding信息:

    shard key: { "event_id" : 1, "betting_type_id" : 1 }    event_id為mysql自增欄位,betting_type_id為玩法id(意味著幾個固定的值,區別度不大)

    shard 分佈情況, 從圖裡面可以看到mongo主要根據event_id這個自增欄位的範圍進行數據拆分,  意味著相鄰比賽的數據大概率會被分配到同一個shard分區上(這就是為什麼01機器上的日誌大小遠大於其他機器的原因吧,目前的數據都集中在shard1上)    

 

 下圖為資料庫讀寫情況, 更新操作是查詢操作的4倍。 對一個寫多讀少的資料庫, 本該將寫操作分佈到不同的分區上,結果由於sharding key的錯誤選擇造成了寫熱點,將寫集中到了同一個分區,進一步加劇了寫的阻塞

 

結論

  1. 文檔結構不合理,數組過大、更新過於頻繁,特別是對同一文檔。 對數組頻繁的更新操作是mongo最不推薦的,不僅影響本機的性能,還影響oplog的數據同步
  2. sharding key不合理造成了寫熱點,  在第一點不合理的基礎上,更加劇了性能的急劇下降,  還會造成頻繁的mongo數據遷移
    (由於odds_easy.basic_odds的更新量大,目前問題在這個表上,但是其他表也有同樣的問題)

     【可以看到前期合理的架構設計是多麼的重要】

解決思路

  1. 減少同一時刻對同一文檔的更新操作,將一定時間內的多次更新改為一次更新。 
  2. 將更新最頻繁的process欄位從文檔中移出,寫到新的表中。 在新表中,同一event_id,betting_type_id, 賠率公司的變化在同一條記錄中
  3. 文檔結構中加入時間欄位,方便數據遷移,定期將歷史數據進行遷移,進行冷熱數據分離
  4. 修改sharding key為hash或者其他欄位,將寫操作分佈到不同的分區上

解決方案

分兩個階段:

第一階段 結構優化

  1.  odds_easy庫中basic_odds, main_odds不再存儲最近10條的變化,去掉process欄位。  
  2.  數據直接 mongo push到odds_change中對應的記錄rows欄位中 
  3.  單獨提供介面,數據變化從odds_change中讀取,  使用 mongo的$slice讀出最近n條信息,然後程式排序截取即可
  4. odds_easy庫和odds_change庫中的表都使用 event_id 作 hash sharding key
  5. odds_easy, odds_change, odds_bet007, odds_betbrain_bb, odds_betbrain_v5, odds_txodds這些庫中的記錄都加入match_time欄位。   新增的記錄直接加入;歷史的記錄補全

第二階段 冷熱分離

  目的

  1. 解決積壓問題
  2. 提高訪問速度
  3. 防止用戶對大量歷史的訪問從而影響熱數據的訪問。(可以在配置中加入開關, 出現問題時關閉歷史數據的訪問)

 系統中加入redis做熱數據緩存, zookeeper/etcd作為配置服務中心以及熱數據導入的流程式控制制中心


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

-Advertisement-
Play Games
更多相關文章
  • ThinkPHP框架 訪問入口文件後在application文件夾中會出現一些文件夾,其中的home文件夾是前端模塊,也可以在application文件夾中新建文件夾。home文件夾模塊中Conf文件夾的config配置文件,是對於當前模塊的:修改當前模式convention配置文件是對於全體的配置 ...
  • Kafka是分散式發佈-訂閱消息系統。它最初由LinkedIn公司開發,之後成為Apache項目的一部分。Kafka是一個分散式的,可劃分的,冗餘備份的持久性的日誌服務。它主要用於處理活躍的流式數據。 在大數據系統中,常常會碰到一個問題,整個大數據是由各個子系統組成,數據需要在各個子系統中高性能,低 ...
  • 參考:http://design-patterns.readthedocs.io/zh_CN/latest/structural_patterns/proxy.html ...
  • 1 #include 2 #include 3 4 using namespace std; 5 6 class Component 7 { 8 public: 9 virtual void operation() = 0; 10 }; 11 12 class ConcreteComponentA:... ...
  • 靜態工廠方法是一種將類的運用者和產生著隔離的設計模式,它是一種創造型模式,但是它不屬於23種基本設計模式中的一種,它是理解抽象工廠的基礎 "參考yqj2065的博客" 上課時yqj2065要求:除了JDK等框架或工具中的類,自己編寫的類不得使用new創建對象(Test除外)。 據說是因為使用new會 ...
  • 概述: GOF定義:給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。 在軟體開發特別是DSL開發中常常需要使用一些相對較複雜的業務語言,如果業務語言使用頻率足夠高,且使用普通的編程模式來實現會導致非常複雜的變化,那麼就可以考慮使用解釋器模式構建一個解釋 ...
  • 讀完了這本書,收穫很多,對程式設計有了很多新的理解。將每章模式的大概要點做了些筆記以備查閱,一些設計模式書讀完也對其瞭解得不是很透徹,需要以後在實踐中來不斷地加深理解吧。讀書過程中用Java跟著實踐了些部分模式的代碼上傳到了 "https://github.com/wanghaoxi3000/des ...
  • 1、使用Eclipse 建立Maven項目(webapp OR quickstart) 2、配置Maven,如下: 3、建立啟動Application 4、編輯Controller 5、通過application.properties對項目進行配置 項目文件佈局如下: 啟動Application程式 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...