一、优化目标&架构
如背景所述,并与客户技术交流沟通后确认从架构层面进行优化,确认采用MongoDB分片集群来代替原有MongoDB副本集架构实现相关优化特性,简化如图:
简单来说:
兜底:由于MonogoDB分片集采用On ECS架构,同时具备ESSD云盘能力,所以在客户的游戏业余场景上,可以实现更高频的备份(小时级,目前需要手动定时点击,预计7月份上线功能,具体见后面的一些案例解释)以及基于云盘的快照特性可以实现备份快速回滚,也就对应着游戏业务的秒级回档(在特定故障停服场景有重大功效)。
高可用:MongoDB分片在游戏场景上相比副本集的架构“横截面”更宽,使得故障几率进一步被打散,一分片三副本多分片即实现N * 三副本的功效,在抵御AZ级的极端故障场景相比副本集更具优势,使得客户游戏业务的可用性更高。
扩展性:经过NoSQL优化专项转化成分片集架构后,其多分片的架构以及协助客户一起做的压测场景,能够测算出QPS/每分片 的数据,这样子使得游戏业务在进行运营扩展时DAU上涨带来的稳定性风险得以解除,同时对于每分片所能承载的QPS,特别是有了更清晰的性能SLA数据,分片的动态增删使得客户可以横向扩展,不再需要靠堆叠实例级别来增加扩展性,侧面减少成本,也给客户提供更多的爆款可能。
二、阶段概述
从人员配置上,技术服务侧需要参考是否有现成的技术服务方案,如果没有则需要快速WBS确认核心阶段,在本次专项中拆分阶段后为:
2.1、阶段介绍
选型阶段:针对客户业务逻辑进行拆分,这里客户是游戏业务,更多是利用NoSQL的特性提升在线游戏的读取效率,所以选型建议原产品形态进行优化,MongoDB是符合这个业务特性的产品,其次针对客户现有的产品架构进行分析,如背景所属最终从副本集切换为分片集更合适,更细化的在技术服务NoSQL优化机制中体现。
压测阶段:在这个阶段,本次专项中客户采用自研的压测模型与工具进行,压测阶段与选型阶段定义的相关QPS强耦合,压测过程主要是为了暴露未知的问题以及综合业务场景下真实的QPS压力,在本次专项中压测阶段的输出提到了关键作用。
迁移阶段:压测阶段后收集相关压测数据集中解决,按预期会进入迁移阶段,该阶段主要利用DTS产品对现有的数据库数据进行预创建任务并执行数据迁移(此过程为同步/复制),并保持增量同步,确保最终切换阶段可以在预期时长里完成切换,该阶段越早进行暴露出迁移问题的几率越高,切换阶段的风险就越低。
切换阶段:迁移阶段的相关卡点解决后(具体在后续的典型问题来讲述)切换就显得相当轻松,不过依旧需要基于项目维度设计相关的切换时间点,好在前面三个阶段准备够充分,切换基本比较顺利。
2.2、阶段里程碑
为方便读者理解,这里通过一张图来展示,具体细节将在“专项“坑”点“一章中来阐述:
三、专项“坑”点
为方便读者理解,这里结合专项阶段情况针对此次专项中遇到的一些重点(特别是卡住项目进度的问题)问题进行逐一分解与解法建议:
3.1、选型阶段“坑”点
在讲坑点之前,我们所设想的是“先选架构—— 再选规格 —— 客户确认 —— 开始迁移”,而实际上,我们所经历的是“先选架构”这个阶段很顺利,因为要满足客户的需求如背景所属,必然是副本集往分片集进行切换,但是到了具体的“再选规格”阶段就开始出现一些点:
3.1.1、“真假QPS”
这个坑点特别“隐蔽”也是在我们做完整个专项后复盘才发现,我们(特指技术服务TAM+架构师SA)视角与客户视角一开始其实并未对齐,直到提供了选型书后在压测阶段才出现了非预期情况,在游戏场景下,客户反馈的QPS诉求是单次业务交互的,比如:
- 玩家做一次背包展开
- 玩家增加技能属性点
- 玩家进出副本场景
- ……
所以在选型阶段,客户提供了国服“3000QPS”,海外服“1200QPS”(区服概念主要就是涉及到国内还是海外的资源部署,另外一个“坑”点),指的是一次玩家交互下的QPS,但是实际上这个“QPS”带来的MongoDB(或叫NoSQL QPS)其实不一定是一个QPS,从这次专项的情况看,一次业务 QPS有可能是来自于Update+Del+Command等(这里的概念参考NoSQL相关的概念)组合QPS,要解决这个问题,核心是找到 业务QPS:技术QPS 的比例,在本次专项经过压测阶段(这也是为什么压测阶段需要review选型并重新定型的原因)数据约300+次业务交互分析(从MongoDB云监控或高级监测可以获取)看出来比例为1:3(其中读占2/3、写1/3),所以在识别“真假QPS”上肯定选型,特别是阿里云MongoDB的选型需要依照技术QPS来进行选型,评估公式如下:
技术 QPS = ( 业务QPS * Avg(读比例) + 业务QPS * Avg(写比例) ) * Buff
所以最终这次专项的技术QPS总体其实是6000QPS(比原来翻了倍),很多在压测期间出现的问题也就符合预期了(比如频繁HA、客户认为QPS异常等)。
3.1.2、“真假规格”
很庆幸这个“坑”更多是来自于我们提前发现了,同时也引发了客户对于我们产品本身的挑战。
在选型阶段,确认了相关QPS再去换算需要的节点数量,MongoDB的组成核心需要关注的是Monogd节点、Shard节点、CS节点,其中在本专项中因为频繁交互以及游戏场景下,首先需要确认的重点是Shard节点,这也是每个节点性能上限的支撑角色,讲到这里还没聊到“真假规格”到底是什么意思,要了解这个背景其实要先知道MongoDB分片集群的架构:
看到这里或许体感还不明显,那么看下面这个图:
从这里就能看出来,其实MongoDb分片集用的是On ECS架构,底层是ECS(复用ECS架构) + MongoDB集群架构(这一点也在后期与产研团队讨论时出现了争议,后续总结说),所以基本Shard节点的规格基本等同于 ECS规格+Sharing消耗 ,这里的规格选择第一版公式为:
Shard节点规格 = (计算资源(CPU/RAM)+ 存储资源(云盘))* Buff
然而,在MongoDB领域还需要考虑上存储资源与ECS本身的BPS限制,所以请参考以下公式进行评估:
Shard节点规格 =(计算资源(CPU/RAM/BPS[需匹配云盘BPS])+ 存储资源(云盘))* Buff
3.2、压测阶段“坑”点
终于熬过选型阶段,如3.1所述,其实压测阶段与选型阶段是相得益彰的,在压测的前期其实会反复横跳与两个阶段之间,而在后半段则横跳在压测与迁移两个阶段之间,客户在游戏领域的专业程度也使得他们愿意付出这个成本来进行压测,没错,每一个MongoDB,或者说NoSQL得切换都最好有压测的阶段,因为无论是白皮书也好,还是经验丰富的架构师,始终会有一些评估死角,而压测就是暴露这些死角的最佳阶段,客户压测的场景采用的是游戏业务场景,转化成MonogDB技术场景就是基于“表数据量”、“平均文档大小”、“读QPS”、“写QPS”来进行。
3.2.1、“Oplog调优”
进入压测阶段,由于客户压测场景是模拟客户业务高并发的场景,换句话说就是oplog会有频繁的读写日志,导致Oplog的增量速率大于Oplog本身的容量时会触发节点状态异常进而使得节点HA等异常,关于Oplog在压测阶段有哪些需要考虑的点呢?
速率:速率的估算可以根据当下Oplog的容量设置得到的容量实际使用情况,以及其保留的时间进行粗估算,公式为:Oplog生产速率 = OplogSizeMb / 保留时间,这一点速率的获取的目标其实就是为了合理的设置OplogSizeMb与保留时间,而这两个数值最好就是根据压测期间的真实业务场景动态调整。
容量与保留时间:需要注意的是在分片式集群控制台设置的OplogSizeMB是单个分片的值,如果说设置的是50G,则一个集群实例下每个分片的Oplog大小都是50G了,在分片集群的oplogsize值计算和建议是oplogsize值配置为磁盘容量的50%,oplog保存窗口时间在1h以上(但由于客户MongoDB版本为4.2,该参数得4.4及以上版本才支持),对dts的同步、dbs的增量备份、以及节点的主从同步都更为友好。 后续可根据压测时和业务的实际oplog保存窗口和大小进行调整,另外oplog保留时长参数是MongoDB 4.4版本才支持修改的,4.2不支持此参数调整(需要产研后端配置),同时暂时Oplog容量暂时是不支持按分片百分比来调整的,也就说这个容量的绝对值要估算得相对准确,所以,压测阶段的必要性就再次显性了。
容量与保留时间的评估公式为:
Oplog初始值 = ((磁盘容量 * 50%) + Buff) < 磁盘容量– Buff
Oplog生产值 = (X̄[((磁盘容量 * 50%) + Buff)] ) <磁盘容量 – Buff
这两个核心因素是在切换分片式集群时的关键指标。
3.2.2、“Oplog放大”
Oplog放大问题是我们在专项前期遭遇到一个特别头疼的问题,核心原因是4.2内核情况下MongoDb hidden节点在压测场景(频繁读写Oplog)下会有Oplog放大问题,采用了引导客户4.4内核进行压测的方式即可。
3.3、迁移阶段“坑”点
3.3.1、迁移选型
根据互联网技术服务团队方案库中对于MonogDB迁移方案的一些经验,这次我们迁移上还是建议客户采用了DTS(本来是考虑到客户业务复杂度以及相关库表结构兼容问题不建议用DTS的),不过在DTS选型上还是吃了亏,主要原因还是在于仅评估了方案选型,却忽略了规格选型,分开来讲,方案选型是指要满足客户边做同步边做灾备的需求,所以最终设计的迁移方案架构如下:
在讨论架构选型上,我们也与客户讨论到了灾备的场景,对于灾备,切换成新分片集群后,从副本集单集群的可用性其实已经提升到了多分片集群的模式,加上原本就有的多可用区部署,也就是说可用性已经提升了两个档位,经过成本与方案的评估,对于跨Region的灾备在DB层面上的投入会过大,所以最终确认,保持可用区级别的容灾比较符合该客户现有的可用性要求,待业务整体的MAU达到客户超过预期的程度时再部署跨Region灾备(由于切换了集群架构,使得这里的灾备方案也更容易落地)。
在规格选型上,也是本次专项迁移出现评估失误的地方,对于RPS(就是迁移数据行数)评估存在问题,核心原因就是RPS 不等于 QPS,按3000QPS(也因3.1.1的误解)客户直接选择了medium规格DTS进行迁移,最终造成DTS迁移任务直接失败,所以这里有了3.1.1“坑”点打底,我们发现,实际上按Oplog速率、QPS情况看,需要讨论另外一个核心解决方案是:
- 建立DTS监控(主要监控延迟、数据不一致)
- 与客户一同盯盘检查是否延迟超过
- DTS监控阈值公式 = (DTS Dealy >= 3600s) >= DTS Time(3600s)
- (即一个小时内延迟超过了一个小时即报警,同时沉默周期为 3小时为佳 )
- 发现告警联动产研进行调整配置并收集现场数据(Oplog、内存、QPS等)
- 直到告警收敛完成并DTS Dealy < 10s
- 记录完成的数据以便其他区服迁移参考
这么一套下来基本能解决到初始选型错误造成的性能问题,也避免了因为规格导致的性能问题并进而导致数据不一致(这一点会导致切换失败,可以在3.3.2详细了解),当然缺点就是会比较依赖于产研的效率(这一点可以在重点里程碑通过一些报备机制进行规避,后面单独一章报备机制会讲到),所以笔者希望在这个场景下能够产品化,减少客户使用产品的非战时成本。
3.3.2、数据纠正
在本次专项的迁移阶段遭遇最多的除了性能不足导致各种DTS任务失败(包含超大字节异常、OOM、中断等),其次就是数据不一致问题了。
由于MongoDB是快速且活跃的NoSQL结构,QPS数极高加上超额的DTS规格时,在没有3.3.1中“动态调整规格”的机制情况下,出现数据不一致(无论是全量还是增量)几乎是必然的,只是如果不及时调整性能以及定制不一致数据,那么最终数据不一致的数量会随着DTS任务的运行越积累越多,所以DTS在这类场景下是一款高度需要盯盘、性能评估、源目数据结构需要高度一致的产品。
所以数据不一致如何解决呢?常规的做法是DTS任务全量迁移跑完后先对全量数据进行校验,请注意这里的性能是分两部分(也会影响数据纠正的效率):
在本项目中,A阶段的校验出现不一致以及B阶段的增量阶段的校验不一致前半段是需要通过实时的数据不一致监控来确保得到及时的校验任务性能调整与数据修正(这里的监控机制来自于DTS本身的数据校验监控,阈值为>10即告警),监控需要尽可能保持高敏,避免切换阶段出现异常。说回数据纠正,由于专项本身客户有严格的项目化管理,所以对于工期是非常严格的,在约定工期之前若等跑完全量、增量校验再进行数据订正很可能时间上来不及做应急预案,所以在本专项里有两个点可供参考:
- 在进行校验任务时出现的数据不一致一旦超过阈值可以进行数据订正
- 迁移/同步任务尽可能提前做
3.4、切换阶段无坑点
雨过则天晴,前面三个阶段都是不同的“坑”的情况下,到了切换阶段,就到了技术服务的主场了,在重保阶段,特别是DTS方面(因为涉及到最后一刻的点位)需要保证一定的保障阵营,现场技术服务团队则盯盘、播报持续,确保最终切换顺利与观察业务开服后的情况:
3.5、机制建设与同步
在本次专项中其实建立了N多机制,笔者挑了其中5个关键的机制给于读者在相同场景时可以参考:
机制名 |
描述 |
动作 |
压测应急机制 |
提升压测时效性,将非预期情况转化为预期内预案进行处理 |
建立Q-List,压测阶段非预期问题较多,通过技术服务问题收集统一收口,对于需要常期落地的问题记录临时规避方案并确保实时监控&修复 |
NoSQL预检查机制 |
基于实例维度的Checklist,在交付前进行二次检查,确保上线稳定 |
1、Checklist
|
运维共建机制 |
基于MonogoDB优化专项,共建监控运维的机制可有效规避人工监控不及时与实时观察现网业务指标进行引导调整等动作 |
完成对重要实例/资源组的自动监控预警,同时运行1v1反馈机制,具体建立的监控策略见附录。(需要针对核心业务进行监控,对于非核心业务进行排除,同时确保一周更新一次实时性,最大程度减少监控噪音) |
迁移应急机制 |
DTS包括迁移和数据同步任务,建立保障机制来确保迁移阶段顺利 |
核心是观察每次压测、模拟迁移的数据不一致进行设计阈值监控,对于超过阈值的部分进行告警(通过DTS任务本身的告警订阅相关短信、电话通知) |
四、总结
我们在整个专项遭遇到的问题一共100+个,还有很多细枝末节的问题,因为篇幅有限,这里就在每个阶段中都精选了几个比较重点的因素进行展开阐述,力求诸位读者在遇到类似NoSQL优化专项时能够有所参考并提前躲过一些已知的“坑”点,为方便读者对此类项目有更立体的工期判断依据,以下为本次项目真实的时间轴情况:
完成后为客户带来的收益情况:
以上的技术细节、里程碑情况仅限特定场景下交流使用。
注:本文未经许可禁止转载或摘要