资讯专栏INFORMATION COLUMN

从《红色警戒:复兴》论MongoDB设计模式的重要性

pf_miles / 2909人阅读

摘要:继而取名红色警戒复兴。在经过了将近一年的蛰伏后,作为红色警戒复兴的联合创始人,终于有幸在今年月份见证他的第一次公开亮相。至此,我们初步断定,症结点在深层嵌套文档导致的数据多层寻址引发的。

前言

在2016年5月份的某一天,我和菠萝同学怀着对昔日《红警95》的缅怀之情,相约脱胎于开源项目OpenRA,来自制Server、Web、个人系统等,重现《红警95》的昔日光芒。继而取名《红色警戒:复兴》。

在经过了将近一年的蛰伏后,作为《红色警戒:复兴》的联合创始人,终于有幸在今年4月份见证他的第一次公开亮相。

《红色警戒:复兴》官方网站

为何选用MongoDB

在构建项目之初,曾以为的天马行空、伟大蓝图在实际操作过程中遇到了非常多的阻碍。脱胎于开源项目,用.NET实现的游戏引擎,当我们还在为windows服务器不稳定而纠结的时候,MS发布了.NET CORE!这一振奋人心的事情立马让我们决定去大干一番!

(中间省略1万字……)

然后在实际开发过程中,遇到了一个比较棘手的问题。我们希望记录下战斗中所有的战斗数据以供后期采用统计分析方法对收集来的大量数据进行分析,提取有用信息并形成结论而对数据加以详细研究、概括总结。

我们先来看一个gif图

从该gif中,我们可以看到红色玩家单位中有大量的坦克并摧毁了绿色玩家的建筑、士兵、坦克等单位,这一场战斗的数据是会直接记录到我们的MongoDB中,最后当游戏结束时作统一处理。

这里考验数据库性能的点在于,我们需要记录这一回合中,红色玩家有多少A单位、B单位……,其中包括建筑、士兵、坦克、飞机、防御单位等。在游戏过程中的所有游戏数据我们都是存mongo的,考虑到大量的计算,MySQL无法胜任。

因此最终的DB选型就是MongoDB作为游戏中的数据计算容器,MySQL作为最终的数据落盘容器。这也是许多项目采用的一种MongoDB+MySQL的解决方案。

设计模式惹的祸

在使用MongoDB记录数据的时候,通过OPS记录,发现当游戏进度推进至20分钟后(注意这个时间点,由于游戏特性,决定了往往在激战20分钟后,会出现经济大于生产的情况),兵种数量急剧增加,MongoDB CPU负载就会骤然飙升,而这仅仅是在测试环境,若投入生产,,这种情况一般我是采取零容忍的,接下来就是一段改造的过程。

首先一起了解下起初的设计结构:

{
    "_id" : ObjectId("58ecdc0b5003d2a379b871df"),
    "profileId" : 1,
    "gameId" : 1,
    "units" : {
        "soldiers" : {
            "Rifle" : 23,
            "Grenadier" : 46
        },
        "vehicles" : {
            "V2" : 15,
            "Light" : 7
        }
    },
    "money" : {
        "earned" : 12345,
        "spent" : 54321
    }
}

以上Json是游戏中记录的部分的战斗数据结构。需求很简单,需要记录下实时的玩家数据,比如士兵中有一种兵种类型Rifle,当前数量为23个;V2远程坦克有15辆等等。

为什么会造成数据库的负载过高呢?

目前发现一个现象,当数据量不是特别大的时候(也就是之前所强调的20分钟这个零界值),服务器的cpu load并没有表现出异常,而一旦过了零界值,在经济远大于生产的情况下,玩家往往会持续输出战斗单位、防御单位、基本建筑等。这个阶段,我们的MongoDB往往是在做高频率的update操作,且是对同一条数据中的不同数值进行操作。

分析

排除NUMA启动。
由于官方有明确表示,因此我也关闭了NUMA,具体NUMA对MongoDB的影响可参照 MongoDB Manual 关于NUMA的解释

这里引用一段:

Running MongoDB on a system with Non-Uniform Access Memory (NUMA) can cause a number of operational problems, including slow performance for periods of time and high system process usage.

排除CPU分配不均。

鉴于MongoDB Manual中有提到对于云服务或者虚机的使用注意事项,因为我们也像服务商确认过了,不存在如下引用 MongoDB on Virtual Environments

When using MongoDB with KVM, ensure that the CPU reservation does not exceed more than 2 virtual CPUs per physical core.

排查slow log

无论计算机发展的如何遵循摩尔定律,冯诺依曼体系结构是不会变的。也就是说我们的cpu是顺序执行的。

因此在排除了前面2种情况后,我们需要确认的是是否存在慢查询了。

也就是在slow log中,我们发现大量的10s以上的update操作。这无疑使我们更接近了真相。因为真相只有一个。

为什么在零界值前cpu load并没有表现出过载的情况?

对于update涉及到的查询条件都已经加上了索引,但并未有明显改善。

但是慢查询是摆在那里的,不离不弃。我们尝试着对profileId进行频繁update,但CPU显然没有任何波动。

至此,我们初步断定,症结点在深层嵌套文档导致的数据多层寻址引发的。

Embedded data models allow applications to store related pieces of information in the same database record. As a result, applications may need to issue fewer queries and updates to complete common operations.

显然我们错误的理解了MANUAL中对于embedded doc 的用法。

通过抓取currentOp,进一步确认,问题就在update的内嵌文档上。

纵观这条战斗数据,细心的你一定发现了,我们的数据嵌套非常深,而对于这条数据中最需要计算的部分是藏在最里面的,3层嵌套的计算对于mongodb来说是非常吃力的,需要耗费巨大的cpu去做这件事情。

经过对业务需求的再整理,达成一个共识,可以暂时抛弃对于兵种的分类,只记录实际存在的数据。

基于以上思路,我们得出了如下的model:

{
    "_id" : ObjectId("58ecdeed5003d2a379b871e0"),
    "profileId" : 1,
    "gameId" : 1,
    "Rifle" : 23,
    "Grenadier" : 46,
    "V2" : 15,
    "Light" : 7,
    "earned" : 12345,
    "spent" : 54321
}

通过改造data model,除去兵种的分类,只对已有的单位进行update、新增的兵种进行初始化即可。

从3层嵌套中解放出来,放在一级目录下,再次测试,cpu毫无压力。

至此,一次关于MongoDB的Schema Design/Data Model改造到此告一段落。

最后附上原子弹的gif,这个动图其实也是对我们mongodb的一次考验,需要瞬时减去相对应数量的单位。

最后欢迎大家来一起体验我们的《红色警戒:复兴》!

也欢迎志同道合的小伙伴通过 官方网站-加入我们 来加入我们的团队,为复兴红警努力!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19073.html

相关文章

  • 一位90后自述:如何年薪3w到30w

    摘要:红色警戒复兴的联合创始人,中国第位获得者,大中华区核心成员。给我吹了一通后,我感觉被洗脑了,当年还是很吃香的啊,传闻年月入。不要满足于现状,要勇于走出舒适区,尝试不同的东西。 showImg(https://img-blog.csdnimg.cn/20190304200609292.jpeg#pic_center); 作者介绍:90后生人/男/二本本科/世界500强技术主管 1.引言 ...

    Eidesen 评论0 收藏0
  • 程序猿:学习方式要性

    摘要:大家都知道,做我们开发这行的,最核心的竞争力就是学习能力。学习只要找对了方法,也没那么累。核心就是一起学习,讨论后端技术。这种方式会一直继续下去。目前已经有课程了,后续还会更新下去。 大家都知道,做我们开发这行的,最核心的竞争力就是学习能力。技术一直在变化,框架一直在更新,学还是不学。 不学,你会落伍,学,太累了,根本学不过来。学习只要找对了方法,也没那么累。 最好的学习方式那就是兴趣...

    OnlyMyRailgun 评论0 收藏0
  • 各类BI工具“大数据”特性

    摘要:的大数据策略目前,适用的大数据生态系统连接包括和支持和的多维分析数据库可实时连接到数据源,或将其调入内存。面向业务用户的大数据自助式可视化。应对的是一些需要实施展现结果,比如银行交易风险的流水分析,直接对接,,等大数据平台。 市面上的BI工具形形色色,功能性能包装得十分亮丽,但实际应用中我们往往更关注的是朴实的技术特性和解决方案。对于大数据,未来的应用趋势不可抵挡,很多企业也正存在大数...

    AaronYuan 评论0 收藏0
  • 助推现代IDC液体冷却技术复兴,AI至关重要

    摘要:液体冷却技术的优势在于能够以更高的密度进行部署,通过提高效率来降低总成本,并显著减少占地面积。虽然液体冷却的好处令人印象深刻,但其应用障碍却令人望而生畏。工智能的技术进步,如今已经从实验室的研究转向真正的商业和消费者应用。由于人工智能应用程序的计算量很大,因此许多IT硬件架构师使用GPU作为核心处理器或辅助处理器。许多基于GPU的服务器,其散热量是传统服务器的两倍,热设计功率(TDP)达到了...

    EsgynChina 评论0 收藏0
  • MongoDB 上模拟事务操作来实现支付

    摘要:因为在支付过程中不能保证每一次操作都成功,所以还要引入一个日志表来做数据的一致性,保证用户资金变动与实际相符。虽然在数据设计中遇到一些复杂结构的问题,比如和的问题。 [ 玩转 LeanCloud ] 开发者经验分享: 作者:Davy 我们的产品叫「学海密探」,属于在线教育行业,产品需要有支付功能,然而支付最蛋疼是什么?有人会说是支付宝和微信等支付接口的接入开发!没错,但支付接口的开发算...

    crossoverJie 评论0 收藏0

发表评论

0条评论

pf_miles

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<