别人家的DBA |腾讯游戏DBA团队的发展自白

发表于2015-07-31
评论0 921浏览

想免费获取内部独家PPT资料库?观看行业大牛直播?点击加入腾讯游戏学院游戏程序行业精英群

711501594



DBA这个岗位跟仓管员很像,就是每天给别人发点货,别人在你这儿放点货,DBA工作就是把货尽快给送出去或者让人家尽快放进来。当然,还有一份重要的工作,就是让仓库里摆放的货物尽可能整齐,这也是仓管员的本职工作,你不能拿到货往仓库里一通乱扔,别人来取货,又让别人等上半个小时。


图:腾讯游戏DBA Team Leader Robin

内容提纲:

  1. 前辈的积累

  2. Game Cloud Storage架构

  3. Game Cloud Storage组成

  4. Game Cloud Storage去哪

  5. 驱动力及方向探讨

前辈的积累:三类游戏DB架构解析

图:前辈的积累


图: 腾讯互娱的三类游戏

腾讯互娱有三类PC端游戏:1. 平台休闲游戏,比如QQGame斗地主、QQ宠物;2. 高级休闲游戏,因为游戏实时性要求增高,对用户需要就近接入,这类游戏会进行分区处理;3. 大型多人在线游戏MMOG,这类游戏玩法比较复杂,可能包含上万个任务,道具信息,逻辑很复杂,实时性要求更高,对应单用户数据量也会变得更大,新的MMOG游戏或者运营时间长的MMOG单用户数据量会达到几百K。手游这几年本身游戏内容不断的丰富,演进中的游戏分类基本也可以参考原先端游。

图:PLAT/QQGame DB分布

对于平台休闲/QQ游戏的DB,数据集中一个城市存放。因为游戏玩法相对最简单,所以,玩家自身的属性较少,可能就是积分、荣誉、装扮,少量道具的变化,对应数据量也比较小,比较适合集中存放,不同地域的gamesvr到专线也不会有太大压力。

此类DB特点:

  • DB数据集中,基本分布在同城IDC;

  • 单用户数据结构简单,数据量少(<1K);

  • 用户量巨大,通常注册用户过亿,后台通过qq号hash或者uin末尾2-3位数字做分布式数据切片处理;

  • 单DBServer支持访问人数大于10万。

图:ACG/飞车 DB分布

相对MMOG,ACG/飞车的游戏内容比较简单,以玩家对局为主,但单用户的数量会比PLAT / QQGame要大一点,需要大区方式运营,产品策划对于用户聚合有更多诉求,大区增加相对少,反而单个大区承载人数的上限,会因为时间推移,逐步通过技术升级不断提升。

DB特点:

  • 介于PLAT,MMOG之间,单大区支持人数有10万。

图:MMOG/ 三国DB分布

MMOG/ 三国游戏逻辑复杂,用户属性多,玩家升级、打怪、做任务、多人组队作战PK为主。本身一个大区,因为内容过多,复杂的经济系统平衡等,同时承载人数有几万的上限,需要通过不断增加大区,扩张在线人数。实时性要求更高,适合把整个游戏的后台物理设施跟用户作就近接入,这样用户体验会更好一些。

DB特点:

  • DB数据分布广,分布在多个IDC;

  • 单用户数据结构简单,数据量少(50K-几百K);

  • DBServer物理及逻辑扩展频繁,单个区支持同时游戏人数在2-3万。

图:DB架构简化

经过总结,发现其实架构是蛮简单的,我们的MySQL就很简单,一个Master,一个Slave,一个LogDB,把三种游戏精练一下,其实就是一个很简单的架构,如上图。

我们总结了一个经验,因为单用户数据量比较小的话,DB部署的适合集中存在一个城市;如果像一个用户的玩家数据达到几百K的时候,还是适合整体单区架构包括数据库做就近接入、Set化。

图:DB架构精粹

  • 数据部署策略:集中与Set分布,数据集中适合逻辑简单,用户属性较少的游戏;IDC Set分布,适合逻辑复杂,用户属性多游戏.

  • 数据切割策略:平行(QQ号或其它用户ID)及垂直(不同模块属性数据,例如QQGame的道具与装扮信息的切分)

  • 成本与质量策略:分级投入,核心状态与日志流水硬件分离,让读写最频繁的状态类信息保持一个较小的规模,为核心状态类数据增加热备投入。流水日志现在因为近几年大数据很时髦,也有传输到hadoop做分析,也相当于有备份了。

  • 回写策略:前端cache定时合并回写,本身Mysql设置innodb_flush_log_at_trx_commit=0,提升2-3倍性能。

  • 简化策略:对于MMOG将用户属性中数据量较大的任务,道具,仓库信息以二进制方式封装到Blob中。尽可能将DB问题简化为或IO或内存或CPU资源不足的问题。

  • SNS游戏没有列出来,是因为现在所有游戏几乎都包含了SNS元素,但当社交变为游戏的重点时,因为热点不在集中,首要策略是All In Memory,比如前些年特别流行的QQ农场业务。

Game Cloud Storage 架构

图:Game Cloud Storage架构

Game Cloud Storage主要解决硬件故障处理时间长,版本停机时间长,以及空闲率高这三个问题。mysql前增加了proxy一层做高可用;推出定制的tmysql,秒级在线加字段;以及将多实例管理变得更加方便,便于缩扩容。

自动切换

图:Auto-Switch

Auto-Switch首要的考虑是避免误切换。不切换影响最多回到从前,但误切换可能导致更加复杂的问题,比如切换到一个落后了几天数据的Slave,意味着要整体停机,数据乱了,耗费N个小时来做用户数据回档工作,新的用户数据完全丢失。

MySQL Proxy定制扩展

  • refresh_backends,在proxy管理端口扩展了一个核心的指令refresh backend,通过外围控制,外围检测到master故障,一个指令将proxy指向slave,引导后续gamesvr来的正常访问,通过增加proxy整体访问切割,也避免一致性问题;

  • Refresh_user,做user@ip白名单的控制,Proxy本身当它作为MySQL代理的时候,MySQL看到的ip已经都是proxy,增强这一点来延续对于MySQL对来源IP的控制。

  • Show_processlist,查看来源连接,在MySQL里看到的都是来自于proxy的连接,这个时候也不方便去定位一些来源链接的问题,所以proxy需要看到能更直接地来自于gameserver等等前端详细信息。

  • Refresh_connlog,打开记录连接log,保证整个所有DB的请求,可以追溯来源。

监控逻辑

多点监控

高可用切换主要依赖外围的集中监控,我们分了几个大的IDC,比如成都、深圳和上海等,我们会在大的区域本地进行监控,比如成都会有本地的点去对成都所有DB定时监测,深圳也会监测,并会对比这两者,如果两者有一者存活的话,那就不做处理,如果两者都有问题的话,就会考虑开始把它进行切换,这是多点监控。

SQL探测,SSH登陆

先通过replace sql探测DB端口,成功则认为ok,否则通过ssh登陆,及touch文件探测。为什么要以SHH作为条件?因为MySQL负载高的时候,SQL探测遇到Hang住异常,希望ssh进一步去探测物理机器存活,如果ssh登陆不了或ssh后touch遇到只读,我们基本断定一台机器故障了,这个时候,会推送到下一步第二轮探测队列,以便整机切换。

DoubleCheck

前述第一轮探测,检验完成后,进行Double Check探测,确认问题后,同时检查一下Slave这些跟进的状态是不是对的,最近的数据Check Sum校验是不是一致的,是否有主备Time delay。

最后,满足切换的前置条件包括以下几方面:

  1. show slave status, 获取binlog获取及本地relay执行对比;

  2. Checksum(7天内)不一致块数量,小于5个块可进行切换;

  3. Slave落后Master时间, 小于10秒为可进行切换;

  4. Master已故障时间,小于10分钟可进行切换;

压缩

图:压缩

关于Blob我们遇到的一个问题是,当时比较火的《地下城与勇士》,上线刚半年单机数据量达到200多G。当时跑的硬件只是只有8G内存,6块SAS磁盘一台机器,一个周末因为夜间备份时间过长,到了白天还没结束,业务连续出了2个突发。后来,我们跟韩国的开发商商定了压缩这个投入最小的方案,通过一次停机,整体数据做一次压缩,整个数据库数据从200多G变成了4G。

同时,后续数据修改,从数据库拿到数据后进行gameserver进行解压,在gameserver写入数据库前就进行压缩。根据在Slave上对OSS金钱统计相关数据进行的经营统计分析,发现原来要执行400分钟的,基本上降低到5分钟。很简单的压缩还是蛮有用的,控制核心数据量,对后续这个游戏长续运营产生了极大的帮助,这个游戏早期被外界叫做掉线城与虚弱勇士,我想我们做的很简单的事情,对于帮助游戏丢掉这个恶名还是有一点帮助的。

图:压缩演进历程

压缩演进历程:

2008年,遇到一款MMOG游戏,单一用户量很大,当时想到最简单的办法就是压缩。开发方,在select时候,用mysql自身的uncompress做解压,update直接sql里边用mysql函数compress写回,用MySQL的技术就搞定了。

2011年,逐步会有一些内部的ORM DB公共组件可以做一些透明开关,通过中间件层去压缩数据。

2013年,前面几种办法都不是DBA能完全cover的,总需要开发更新中间件,或者改写sql,或者更新gameserver逻辑,我们想了一招,就是把Mysql内完全解决这个问题,完全对开发透明,只要给字段通过alter增加Compress的属性,在MySQL底层直接就把大字段压缩给做了。这个效率,我们测试中发现远好于本身innodb page压缩。

监控

  • 2007年前,监控是比较零散的。

  • 2007年刚入职,接到的第一个稍大的任务就是给DB写监控,我们都把监控放在数据库机器本地,还有一些Hang判断,ErrorLog检测,还有status我们收集了232个。

  • 2009年,因为有时候某个指标异常的时候,难以得到问题相关因素现场,所以我们针对slowquery量及io利用率超过一定阀值去做了一些现场保留工作,比如show processlist,ps aux,top等,并保存在监控日志里边。同时,也做了checksum的办法,OS层指标增加一些我们急需的但公司网管系统并未涉及的,比如每个分区的ioutil等。

  • 2012年,为了配合做GCS高可用,做一些时间同步的检测;为了能更方便地去对比一些DB的性能,聚合性能指标在一起,做了特别方便的性能对比工具。

Game Cloud Storage去哪

图:Game Cloud Storage去哪

思考GCS去哪,本身也是在想源码定制这条路该往哪里走?如果大家对开源软件比较有兴趣的话,可以参考我们走过的路,可以先尝试简单功能的优化,然后考虑扩展至性,再考虑性能,因为性能优化的挑战,涉及到mysql底层更复杂的锁调优等机制优化,我一直觉得还是蛮大的。最近一两年,在线加字段这个痛点解决折后,我们一直希望能MySQL在保持mysql协议基本不变的前提下,能像nosql类似MongoDB扩展性那么好,在这方面做了一些探索。

我们选用了Spider,一个分布式的MySQL底层存储引擎来解决这个问题,前一两年开始研究这个Spider,到现在已有超过10个业务上用了起来。Spider官方,在最近一两年也不断完善,合并到MariaDB 10的正式版本里面。大家如果对数据库分布式有需求,同时不希望开发太多修改,可以考虑MariaDB 10的版本。

图:运维的驱动力

最近业界有很多运维发展方向的讨论,我自身也在思考运维的核心驱动力到底是什么。如果我去回顾过去的一些历程,我自己考虑运维核心的驱动力还是最简单两个字——问题。可能来自业务发展的快速增大数据量,请求并发增大,或者开发使用整个存储的容易程度,或者平时运维的一些问题,我们不希望自己那么多通宵处理故障,那么多步骤那么辛苦缩扩容。不管在哪家公司,只要我还能够不断解决问题,可能这个公司我还能呆得下去;如果没有问题需要解决,或者是天天时间都花在其他地方了,可能也就没什么意思了。

图:内部平台产品方向

我们做这些内部平台,按目前的人力投入,最重要的还是聚焦支撑内部精品大业务的发展。但站在内外部技术平台竞争加剧的角度,每天都能看到各种各样渠道吹牛的信息(就像我今天这样),都说自己很厉害,很强,我们的下一步该怎么走,怎么证明自己的价值,获得应有的认可,这是个很关键的问题。

听了很多业界大拿的建议,比如叶金荣同学,平静的思考之后,我们后续计划或者是策略大概是:首要的,仍然会站在“巨人的肩膀上”,更好的使用及支持整个社区开放协议存储方案,通过更为深入研究积累,能提供基本闭环的服务支撑能力;第二步,关于怎么证明团队价值,从前几年的“定制”方向转变到“回到社区”方向,在那个更加广袤的空间去追求些许的认可。

更新这个ppt之前,翻出来多年前内部分享的一页ppt,“关于DB的美好想象”,其中第一点因为牵扯业务过于多样化逻辑数据设计,还是没做到,第二点做到一点点。

原文链接

著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

游戏学院公众号二维码
腾讯游戏学院
微信公众号

提供更专业的游戏知识学习平台