亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

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

vibiu / 3502人閱讀

摘要:年月日本文是關(guān)于記錄某次游戲服務(wù)端的性能優(yōu)化此處涉及的技術(shù)包括引擎隨著游戲?qū)肴藬?shù)逐漸增加單個集合的文檔數(shù)已經(jīng)超過經(jīng)常有玩家反饋說卡特別是在服務(wù)器遷移后從核降到核卡頓更嚴(yán)重了遂開始排查問題確認(rèn)服務(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), 卡頓更嚴(yán)重了, 遂開始排查問題.

確認(rèn)服務(wù)器壓力

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

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

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

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

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

到了此時基本確定問題所在了: 大量的查詢(先不管是否合理)導(dǎo)致MongoDB不斷進(jìn)行磁盤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

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

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

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

增加/修改索引

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

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

游戲邏輯需要對某些集合中符合條件的所有文檔 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});

之所以使用稀疏索引, 是因?yàn)榇蟛糠滞婕沂遣痪哂蟹Q號(TitleData字段), 使用稀疏索引時只會索引存在該字段的文檔, 通過對比, User集合中, 默認(rèn)的 _id_ 索引大小138MB, 剛建立的稀疏索引TitleData_1大小僅為8KB(最小大小).

修改查詢語句

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

因此需要改造部分服務(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的一些操作, 默認(rèn)是30秒, 比如 find() 操作一旦超過30秒會拋出 "超時異常", 然而此時該語句還在MongoDB實(shí)例中執(zhí)行.

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

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

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

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

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

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

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

相關(guān)文章

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

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

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

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

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

    摘要:這是多處理器系統(tǒng)中,調(diào)度器用來分散任務(wù)到不同的機(jī)制,通常也被稱為處理器間中斷,。文章編寫計(jì)劃 待完成: 詳細(xì)介紹用到的各個工具 作者: 萬千鈞(祝星) 適合閱讀人群 文中的調(diào)優(yōu)思路無論是php, java, 還是其他任何語言都是用. 如果你有php使用經(jīng)驗(yàn), 那肯定就更好了 業(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(二)——進(jìn)擊的 Promise Effective JavaScript leeheys blog -...

    kamushin233 評論0 收藏0

發(fā)表評論

0條評論

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