前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >关于《秦时明月世界》运维的那些事儿—自研上云与core优化

关于《秦时明月世界》运维的那些事儿—自研上云与core优化

作者头像
腾讯大讲堂
发布2021-06-15 11:10:14
7840
发布2021-06-15 11:10:14
举报
文章被收录于专栏:腾讯大讲堂的专栏

作者:reneeyang(杨韧)  腾讯光子技术服务工程师

导语|秦时明月世界手游已经上线一段时间了,运营稳定,整个上线过程达到了预期的效果。现复盘整理如下,如果能通过些许经验,让其他业务躺平且少走弯路,就是我本文的初衷。

为什么普遍现网环境限制coredump?

Coredump也叫核心转储,是应用程序在运行过程中由于各种异常或者bug导致退出,在满足一定条件下产生了一个core文件,这个core文件包含了程序运行时内存、寄存器状态、堆栈指针等信息。Core文件就像一个案发现场,提供了第一手的现场信息供开发调试和定位。

程序异常崩溃时候,coredump是定位BUG的利器,有诸多好处,但是有一种场景让业务不得不放弃它:如果程序运行时占用大量内存,异常崩溃时生成的coredump文件可能会非常非常大。而生成文件的写盘过程非常缓慢,这会严重影响系统的整体运行情况。可以假想,这个程序如果异常崩溃后其实也没什么太大影响,因为(tcm/监控脚本/管控系统)的自动拉起机制会自动检测并运行新的进程实例来恢复业务。但是,30GB大小的core文件写盘需要数分钟,在这期间该进程就完全瘫痪了,这肯定不是业务希望看到的情况。其次即便core掉的进程不是核心体验影响进程,但是写coredump文件期间,占用了大量的IO,也会影响同服务器上其它的进程给用户提供服务。

业务普遍使用限制core的方案有哪些?

一般情况下,限制coredump常常使用下面几板斧:

1.修改系统配置 ulimit -c,限制core文件的大小 一般不建议这种方式,我们要获取的信息中最重要的,通常是异常发生时函数调用栈,而如果裁剪core文件的大小,则再用gdb bt可能无法获得函数调用栈。

2.只在部分机器打开core其余关闭,限制写core的机器范围 这种方案比较适用于无状态的模块,可以减少和控制影响范围,也避免雪崩效应,但对于有状态模块该方案不大适用。

3.产生首个core后半小时内关闭core的打印 可以通过直接限制core目录的写入权限来实现,短时间内重复触发的core有极大概率是同样的原因,此方法可以减少不必要的影响。

4.不实际产生core文件,只捕捉core信号 不实际产生core文件,只捕捉程序core时发出的信号,一旦截获到信号后,把堆栈信息单独打印到一个文件中。这个文件很小,好处是程序可以快速启动,但同时由于缺少其它现场信息,提高了定位的难度。这种方案适用于对服务可用性要求非常高,同时定位难度较低的程序。这个方案需要开发在程序层面上来实现。

5.修改启动进程脚本 /proc/$进程ID/coredump_filter ,使用内核转储掩码来排除要转储的内存块

PS:默认值为0x33

秦时明月世界是否能限制coredump?

秦时明月世界手游是一款MMORPG游戏业务,玩家面对的是一个复杂的虚拟世界,对游戏的品质有要求。因此对于开发版本质量的要求也非常高,复杂而庞大的系统,众多的玩法模块,上线前要充分的考虑和测试,上线后万一发现问题能快速的定位和应对处理。因此core文件对于秦时明月手游在发现和定位问题上起着不可或缺的作用。

就要不要对core做限制这个问题,在上线前与后台大佬多次发起讨论,纠结了许久。并在上线前对外测试中实际验证过上面通过coredump_filter限制core输出内容方案,虽然core文件大小能得到30%左右的减少,但是也存在这样的风险:在某模块的A机器上发生了coredump之后,A机器提供服务受损了,而由于MMO类型业务的复杂性,以及导致coredump的原因可能具有偶然性,会比较难定位和复现。coredump文件的内容不完整会进一步降低了定位问题的效率,隐患问题没能得到快速的修复解决,后续可能爆发大面积coredump。这既白费了A机器coredump付出的代价,又增加了全网服务异常的风险。因此秦时业务希望,既要写完整的coredump,又要控制住coredump对服务受损时长的影响。

秦时明月发生coredump影响多久时长?

发生coredump到恢复服务是需要这么一个过程:内核检测到进程的一些异常行为时,会给进程发送相应信号。进程收到信号后,内核会帮进程写个coredump,coredump写完后内核再把进程干掉,释放其占用的资源。而进程在退出后被系统/脚本进行重新拉起,拉起后还有初始化、加载数据等步骤。而这整段过程中间的时间里,进程是无法对用户提供服务的。

由于秦时明月为分区分服业务,大区模块 gamesvr的物理部署方式是一个区一台服务器,这个核心模块是个单点模块,在gamesvr模块发生coredump是直接影响玩家可用性的。而这个gamesvr模块(一个core文件大小在30G左右)对应上面这个coredump流程的实测数据:写core耗时约210s + 自动拉起秒级 + 进程初始化约3~5s,总影响时间长达3-4分钟,这个对用户和业务都是不可接受的。

用户体验里有个指标是,用户极限等待时长约10s。秦时明月这边也有实际的运营观察数据:我们发现20s以内恢复服务,在线呈V曲线,虽出现缺口但能快速恢复;超过20s后,玩家离开游戏概率增加,在线回升缓慢,在线曲线较难在短时间内恢复到core发生之前水平。

自研上云与CBS云盘

公司930变革后,开始全面推进 “开源协同,自研上云”,秦时明月作为一款新业务,也必然响应公司战略。经过与业务协商,运维将现网环境全量部署在自研云上,硬盘这块最开始是使用的高性能CBS云盘。

为什么使用CBS云盘,有2个原因。 第一个原因是:这是当下仅有的选择。Gamesvr模块出于业务性能上的需求,秦时是使用的是C3高主频机型,到目前为止还没有同时支持高主频和本地盘的自研云机型。推动新机型的支持可能会涉及需求评估,硬件供应商选型,新机型测试验收,以及后续资源的轮转和成本问题,不仅时间上存在巨大风险,从公司及业务成本考量也不划算。 第二个原因是希望体验CBS云盘带来的好处。CBS云盘提供的是一种抽象的分布式存储资源,采用三副本的分布式机制,系统确认数据在三个副本中都完成写入后才会返回写入成功的响应。后台数据复制机制能在任何一个副本出现故障时迅速通过数据迁移等方式复制一个新副本,时刻确保有三个副本可用,避免单点故障引起的数据丢失等问题,提供高达 99.9999999% 的数据可靠性。在云上服务器发生宕机的情况下,使用云盘的机器可以秒级迁移并恢复服务。

CBS云盘架构图

由架构图中可以看出,CBS云盘是把本地IO转换成了网络IO,它的性能相对于本地盘是有差距的。秦时最开始使用的高性能云硬盘300G,按官网显示规格吞吐性能在145MB/s,写完30G的core理论耗时数据3.5分钟,这跟秦时业务的实测数据确实也匹配,但是却符合不了业务的性能需求。

PS:如果对IO性能有较高需求,同时又没有像秦时明月业务一般使用了高主频等特殊机型,可以选择IT5机型,这种机型为本地SSD硬盘,和云盘对比还是有着数量级上的差距的。 IT5机型腾讯云官网IO性能数据:单盘随机读性能高达65万 IOPS(4KB块大小),顺序读吞吐能力高达2.8GB/s(128KB块大小)。整机随机读性能高达205万 IOPS(4KB块大小),顺序读吞吐能力均高达11GB/s(128KB块大小)。

如何实现目标

那么问题来了,如何在自研上云的大背景下,既要打印完整的30G大小core文件,又要将core的影响时长控制在20s内

升级磁盘

最开始秦时使用的是CBS云盘中性能最低的高性能云盘,到发文时自研云已经支持增强型SSD云硬盘,但在秦时业务上线前2020年底那会儿纠结实现方案的时候,该类硬盘还在测试阶段,没有正式开放申领。只能选择当时最高可以申请到的性能配置:SSD云硬盘,通过硬盘类型调整+扩磁盘容量(CBS上限跟磁盘大小也有关系),将磁盘IO吞吐性能从145MB/s提到了260MB/s。至此,在当时CBS云硬盘性能已经提升到极限了。

【运行效果】升级磁盘后,写core的时间已经从3~4min降低到2min了,离目标还是有很大一段差距。

通过管道将core作为标准输入传给脚本

那还能有什么办法呢,从core的man pages中,发现了内核2.6.19版本之后支持通过管道将core作为标准输入传给一个用户态的程序或脚本,这个脚本里就可以定制个性化的处理。

优化方案1:

把core_pattern配置为通过管道传给脚本:

脚本里边压缩边写磁盘:

引入多线程压缩pigz

再考虑到我们的CPU资源较为充足,还可以用上多线程压缩提速,引入了pigz。

优化方案2:

gzip替换成pigz -p指定8线程压缩(这里为什么不能压缩成tar包,留个伏笔)

【运行效果】30G的core文件压缩后约2G大小,耗时进一步降到40s左右,而且这个耗时并不是由于磁盘IO限制导致的(假设IO满写 2G / 速率260MB/s应为7.8s,说明瓶颈已经不在IO上了),瓶颈从磁盘IO转换到压缩计算上,而此时CPU也用到极限了。 进了一大步,但是离20s的目标还有差距。IO极限了,CPU极限了,内存有没有可能?

同步改异步,先写内存再压缩落磁盘

优化方案3:

先将core直接写到内存里:

再启个守护进程,每秒钟探测/dev/shm下是否有core文件,若有则用多线程压缩后再落地磁盘并清理内存中的core文件。出于压缩比和使用习惯原因,压缩落地磁盘的是tar包。

【运行效果】经实际验证,30G的core直接写内存耗时只要12s,再加上进程拉起后初始化的3~5s耗时,刚好控制在20s内,目标达成。但优化方案3也引入了一个新问题:这么大的core直接写内存,会不会存在反复coredump,压缩转存脚本处理不过来,导致内存耗尽,从而影响整台服务器运行的可能。与秦时后台兄弟们一起讨论评估后,通过2点措施来保障: 1.对核心模块gamesvr内存扩容26G,约等于gamesvr上1个core的大小; 2.脚本中对于半小时内反复出现的core,仅压缩转存第一个,其余的直接删除丢弃。

又遇到core压缩包解压问题

上线前我们就先写内存的方案做了全网的部署和调整后, 在某次删档对外测试期间又发现了一个问题:开发在解压core压缩包想定位问题的时候,解压core压缩包过程中IO性能急剧下降,直接影响到了在运行的进程,导致业务进程对外服务受损。

参考CODM和天刀手游业务的解决方案,我们在解压这步引入了xtar,同时对全网CBS云盘做了部署上的打散。

引入xtar

Xtar是由腾讯云侧开发的,对linux上tar可执行文件源码上做了修改,使其可以基于流量控制进行解压,减缓解压操作来带的IO压力的可执行程序,在多款头部业务的发布等场景中均有应用。 xtar特别适合与CBS盘配套使用,例如发布场景:可能几千上W台机器同时解压发布包,对CBS会有非常大的瞬间集中压力,引入了xtar对业务自身、对腾讯云侧都增加一层保护。

xtar的使用方法:

xtar的部署: 秦时业务是在业务初始化步骤中,就把xtar可执行文件直接放在/usr/local/bin下。需要的同学可以在文末自行下载取用。

Flow-control值的评估:50MB是结合了CODM和天刀业务的使用经验,并经过实践验证,确定秦时配置值在50MB能较好平衡时间和性能需求。

cbs打散

1.为什么需要打散? 因CBS单集群能力固定,所以需通过按业务分类后尽可能的均衡打散到所有集群中来抗突发写流量,通常用于解决游戏发版、同类业务批量IO操作。 缩小故障域,降低单集群故障对对客户相同业务的影响。 2.如何保障做到均衡打散? 各区会保障所有集群都处于可售状态,用户同一批次申领的CBS在装箱时会尽量分散到所有可售集群中。 后端服务定期分析扫描用户下相同业务类型CBS在集群中的分布,进行打散。 3.如何打散? 一般默认装箱时会打散,但同时也跟云盘标签会有关系,不放心的可以先联系腾讯云侧,提供业务机器列表,请腾讯云侧帮查询是否有打散。 而打散操作,首先要业务侧配置子机别名或云盘别名或者云盘标签,保证前缀一致,然后联系腾讯云侧处理即可。 4.在打散期间可正常使用吗? 可以,CBS迁移打散属于常规动作不影响正常使用,但在打散前应避免批量操作导致被qos影响业务。

最终方案抉择

上线后导量关键期使用先写内存异步压缩落地磁盘方案

秦时明月项目确定了在导量关键期上线后的关键导量期采用优化方案3,以保障关键时期的用户体验为第一要务。

上线后平稳期用管道传输脚本直接压缩写磁盘方案

出于成本收益比的考量,上线平稳后再逐步切换回优化方案2,将升配的26G内存再降配回去,以节省资源。

平稳期调整core部署方案再次遇到问题

秦时明月业务顺利上线并进入平稳期后,准备按计划切换回直接通过管道传脚本压缩写磁盘方案,遇到了新问题,在前面优化方案2留下了个伏笔,core作为标准输入通过管道传给脚本进行压缩,这里只能生成zip包,无法生成tar包,这样一来解压时就没法用xtar了,解压时就存在瞬间IO过高的风险。

为什么只能生成zip包,很简单,因为tar不支持这种使用方法。如下图简化场景的示例,跟pigz或者gzip不一样,tar是必须要接文件名的,不支持将core文件作为标准输入,通过管道传给tar命令的。 tar vs pigz用法区别:

这里也希望腾讯云再增加个限流解压zip包的官方程序。而在有官方解决方案之前,有没临时方案能解决?这时我想起曾在上线前一次与腾讯云的护航交流中听到过:xtar的实现其实是在tar里面加了些sleep的逻辑。那我能不能用脚本来模拟这种实现,于是得到了以下思路:

通过信号,进程的处理是可以跟磁带机播放一样播放暂停的

具体方法:把解压进程放后台运行,然后向解压进程发送一个SIGSTOP信号,类似于磁带机按下暂停键,它就会因响应该信号而进入TASK_STOPPED状态,sleep一段时间后,再向进程发送一个SIGCONT信号,像磁带机按下播放键一样,又可以让解压进程从TASK_STOPPED状态恢复到TASK_RUNNING状态,如此反复,是不是就有点类似于xtar加sleep的实现? 经过多次的调整测试测试,最后敲定执行1秒,sleep 10秒这个较为保守的比例。观察磁盘IO能约等于xtar 的flow-control=20MB的效果。

实现脚本:

效果

机器磁盘IO表现:

至此问题已经得到了解决,但是观察xtar和信号控制脚本的表现还是有些区别的,xtar的流控会更为均匀些,对于xtar的具体实现原理,后续计划再跟腾讯云侧深入了解学习下。

进一步的思考

还有没其它思路

对于通过管道将core作为标准输入传给脚本,脚本处理落地的方案,之前还有个思路是试试脚本处理不直接落本地,而是pipe免密传输到集中一台机器,由于可以预见这个耗时肯定不符合秦时的需求,我就没有尝试了。但好处是方便开发集中分析,有兴趣的同学还可以去做进一步的探索。

万物皆可盘

秦时之前我也负责过几个新业务上线,以往面对core的风险问题,都是给业务建议和推广已广泛应用的限制core打印方案。在core这一个点上,能挖出萝卜带出泥牵出这么一顺溜的问题和解法,是我自己完全没有预料到的。所以也多亏了秦时项目组的坚持,只要思想不滑坡,办法总比困难多。

近期热文推荐

腾讯低代码OTeam建设概述

企业微信万亿级日志检索系统

     你“在看”我吗?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯大讲堂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 腾讯低代码OTeam建设概述
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档