国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

huhud / 2582人閱讀

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

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

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

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

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

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

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

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

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

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

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

開(kāi)始處理 減小單個(gè)集合大小

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

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

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

慢日志分析

需要打開(kāi)慢日志

profile=1
slowms=300

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

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

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

增加/修改索引

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

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

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

針對(duì)這幾種情況, 可以通過(guò)增加索引來(lái)解決.

舉例1: 玩家等級(jí)排行榜

// 查詢語(yǔ)句
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}, 否則建索引期間會(huì)引起大量阻塞.

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

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

舉例2: 玩家稱號(hào)處理

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

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

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

修改查詢語(yǔ)句

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

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

舉例1: 篩選玩家

// 原查詢語(yǔ)句: 發(fā)放全服獎(jiǎng)勵(lì)
db.User.find({});

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

舉例2: 公會(huì)成員信息

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

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

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

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

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

具體的加鎖方案有:

memcached

redis

很簡(jiǎn)單.

避免客戶端超時(shí)

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

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

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

解決方案很簡(jiǎn)單, 以php代碼為例

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

更換存儲(chǔ)引擎: 將 MMAPv1 替換為 WiredTrigger

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

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/31697.html

相關(guān)文章

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

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

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

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

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

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

    xeblog 評(píng)論0 收藏0
  • 2017年3月份前端資源分享

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

    ermaoL 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<