成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

記一次MongoDB高負載的性能優(yōu)化

huhud / 2602人閱讀

摘要:年月日本文是關(guān)于記錄某次游戲服務(wù)端的性能優(yōu)化此處涉及的技術(shù)包括引擎隨著游戲?qū)肴藬?shù)逐漸增加單個集合的文檔數(shù)已經(jīng)超過經(jīng)常有玩家反饋說卡特別是在服務(wù)器遷移后從核降到核卡頓更嚴重了遂開始排查問題確認服務(wù)器壓力首先使用命令查看總體情況此時占用不高

Last-Modified: 2019年6月13日11:08:19

本文是關(guān)于記錄某次游戲服務(wù)端的性能優(yōu)化, 此處涉及的技術(shù)包括: MongoDB(MMAPv1引擎), PHP

隨著游戲?qū)肴藬?shù)逐漸增加, 單個集合的文檔數(shù)已經(jīng)超過400W, 經(jīng)常有玩家反饋說卡, 特別是在服務(wù)器遷移后(從8核16G降到4核8G), 卡頓更嚴重了, 遂開始排查問題.

確認服務(wù)器壓力

首先使用top 命令查看總體情況, 此時cpu占用不高, %wa比例維持在40%左右, 初步判斷是磁盤IO過高

使用iotop命令以進程粒度來查看io統(tǒng)計, 發(fā)現(xiàn)MongoDB進程全速在讀操作.

使用MongoDB自帶的mongostat 命令, 發(fā)現(xiàn) faults字段持續(xù)高達200以上, 這意味著每秒訪問失敗數(shù)高達200, 即數(shù)據(jù)被交換出物理內(nèi)存, 放到SWAP

由于未設(shè)置交換空間, 因此無法通過 vmstat 命令查看是否正在操作SWAP

在mongo shell中執(zhí)行 db.currentOp() 確認當前存在大量執(zhí)行超久的操作

到了此時基本確定問題所在了: 大量的查詢(先不管是否合理)導(dǎo)致MongoDB不斷進行磁盤IO操作, 由于內(nèi)存較小(相較之前的16G)導(dǎo)致查詢過的緩存數(shù)據(jù)不斷被移出內(nèi)存.

開始處理 減小單個集合大小

這一步驟主要是針對庫中幾個特別大的集合, 且這些集合中的數(shù)據(jù)不重要且易移除.

此處以Shop表為例(保存每個玩家各種商店的數(shù)據(jù)), 在移除超過N天未登錄玩家數(shù)據(jù)后, 集合大小從24G降為3G

通過減小集合大小, 不僅可以提高查詢效率, 同時可以加快每天的數(shù)據(jù)庫備份速度.

慢日志分析

需要打開慢日志

profile=1
slowms=300

逐條確認所有慢日志, 分析執(zhí)行語句問題

use xxx;
db.system.profile.find({}, {}, 20).sort({millis:-1});

此時的重點在于確認執(zhí)行統(tǒng)計字段(execStats)中 階段(stage)是全表掃描(COLLSCAN)的, 這是最大的性能殺手.

增加/修改索引

通過慢日志分析, 發(fā)現(xiàn)大部分全表掃描的原因在于:

排行榜定期統(tǒng)計

游戲邏輯需要對某些集合中符合條件的所有文檔 update

針對這幾種情況, 可以通過增加索引來解決.

舉例1: 玩家等級排行榜

// 查詢語句
db.User.find({gm:0}, {}, 100).sort({Lv:-1, Exp:-1});

// 移除舊索引, 增加復(fù)合索引
db.User.createIndex({Lv:-1, Exp:-1}, {background:true});
db.User.dropIndex({Lv:-1})

生產(chǎn)環(huán)境建索引一定要加 {background: true}, 否則建索引期間會引起大量阻塞.

還有刪除舊索引前, 記得先建立好新的索引, 避免期間出現(xiàn)大量慢查詢.

通過 explain("allPlansExecution")查詢分析器可以看出, 此時最初階段是 IXSCAN, 即掃描索引.

舉例2: 玩家稱號處理

// 查詢語句
db.User.find({TitleData:{$exists:true}});

// 增加稀疏索引
db.createIndex({TitleData:1}, {sparse:true, background:true});

之所以使用稀疏索引, 是因為大部分玩家是不具有稱號(TitleData字段), 使用稀疏索引時只會索引存在該字段的文檔, 通過對比, User集合中, 默認的 _id_ 索引大小138MB, 剛建立的稀疏索引TitleData_1大小僅為8KB(最小大小).

修改查詢語句

由于項目代碼經(jīng)過多手, 部分人員經(jīng)驗不足, 代碼編寫時未考慮到性能問題.

因此需要改造部分服務(wù)端代碼, 這部分就是苦力活了, 逐個去修改, 屬于業(yè)務(wù)代碼優(yōu)化.

舉例1: 篩選玩家

// 原查詢語句: 發(fā)放全服獎勵
db.User.find({});

// 修改后: 篩選僅最近30天登陸, 利用現(xiàn)有索引 {LastVisit:-1}
db.User.find({LastVisit:{$gt: 30天前的時間戳}})

舉例2: 公會成員信息

// 原查詢語句: 在User集合中搜索指定公會成員
db.User.find({GuildId:xx});

// 修改后: 利用Guild集合中已有的GuildMembers成員列表, 逐個獲取公會成員數(shù)據(jù)
db.Guild.find({Id:xx}, {Id:1, GuildMembers:1}, 1);
db.User.find({Id:{$in: [xx, xx, xx]}})
定時器增加鎖

早期服務(wù)器數(shù)據(jù)量較小時, 每個分鐘級定時器都能順利在1分鐘內(nèi)跑完, 但一旦出現(xiàn)慢查詢(未優(yōu)化之前出現(xiàn)過十幾分鐘的), 上一個定時器未跑完, 下一個定時器又來了, 大量的慢查詢語句堆在MongoDB中導(dǎo)致整個數(shù)據(jù)庫被拖垮, 直接雪崩. 這是玩家反饋卡頓的最直接原因.

盡管經(jīng)過上面優(yōu)化后不會出現(xiàn)一個查詢1分鐘以上這種情況, 但是多個查詢累加起來, 也有可能超過1分鐘.

為了避免定時器腳本堆疊, 因此需要加個鎖, 避免出現(xiàn)問題.

具體的加鎖方案有:

memcached

redis

很簡單.

避免客戶端超時

定時器通常是用于執(zhí)行一些耗時操作, 除了上面的鎖問題外, 還有一個不可忽視的: 客戶端超時.

PHP中對MongoDB的一些操作, 默認是30秒, 比如 find() 操作一旦超過30秒會拋出 "超時異常", 然而此時該語句還在MongoDB實例中執(zhí)行.

由于定時任務(wù)未完成, 下一個定時器來的時候還是會繼續(xù)嘗試進行同樣的操作..

解決方案很簡單, 以php代碼為例

$mongo->selectCollection("xx")->find([...])->timeout(-1);
更多的優(yōu)化考慮

更換存儲引擎: 將 MMAPv1 替換為 WiredTrigger

使用集群(或簡單的主從), 將數(shù)據(jù)導(dǎo)出及數(shù)據(jù)備份等直接從庫上操作, 更進一步是改造服務(wù)端邏輯代碼, 將部分慢查詢應(yīng)用到從庫中(主要不要)

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/31697.html

相關(guān)文章

  • 一次MongoDB負載性能優(yōu)化

    摘要:年月日本文是關(guān)于記錄某次游戲服務(wù)端的性能優(yōu)化此處涉及的技術(shù)包括引擎隨著游戲?qū)肴藬?shù)逐漸增加單個集合的文檔數(shù)已經(jīng)超過經(jīng)常有玩家反饋說卡特別是在服務(wù)器遷移后從核降到核卡頓更嚴重了遂開始排查問題確認服務(wù)器壓力首先使用命令查看總體情況此時占用不高 Last-Modified: 2019年6月13日11:08:19 本文是關(guān)于記錄某次游戲服務(wù)端的性能優(yōu)化, 此處涉及的技術(shù)包括: MongoDB...

    vibiu 評論0 收藏0
  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    番茄西紅柿 評論0 收藏0
  • 一次PHP并發(fā)性能調(diào)優(yōu)實戰(zhàn) -- 性能提升104%

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機制,通常也被稱為處理器間中斷,。文章編寫計劃 待完成: 詳細介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗, 那肯定就更好了 業(yè)務(wù)背景 框架及相應(yīng)環(huán)境 laravel5.7, mysql5.7, redis5, nginx1.15 cento...

    xeblog 評論0 收藏0
  • 2017年3月份前端資源分享

    平日學(xué)習(xí)接觸過的網(wǎng)站積累,以每月的形式發(fā)布。2017年以前看這個網(wǎng)址:http://www.kancloud.cn/jsfron... 03月份前端資源分享 1. Javascript 175453545 Redux compose and middleware 源碼分析 深入 Promise(二)——進擊的 Promise Effective JavaScript leeheys blog -...

    kamushin233 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<